My html and json with jquery is below. please someone help me to do this in javascript function.
Is there any other way without using clone function?
with pure javascript can we do this any other way to display json content in HTML id's
$(function () {
// Fake JSON result - array of values
json = [{
fields: {
imagem: "Image 1",
nome_produto: "Name 1",
descricao: "Description 1",
preco_produto: "product 1"
}
}, {
fields: {
imagem: "Image 2",
nome_produto: "Name 2",
descricao: "Description 2",
preco_produto: "product 2"
}
}, {
fields: {
imagem: "Image 3",
nome_produto: "Name 3",
descricao: "Description 3",
preco_produto: "product 3"
}
}];
// take a copy of an existing one as a template
$.each(json, function (i, items) {
var clone = $('.conteudo:first').clone();
clone.find('.foto').text(items.fields['imagem']);
clone.find('.inf:eq(0)').text(items.fields['nome_produto']);
clone.find('.inf:eq(1)').text(items.fields['descricao']);
clone.find('.inf:eq(2)').text(items.fields['preco_produto']);
$('section').append(clone);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<div class="conteudo">
<div class="foto">FOTO</div>
<div class="inf">TITULO</div>
<div class="inf">DESCRICAO</div>
<div class="inf">PRECO</div>
</div>
</section>
My html and json with jquery is below. please someone help me to do this in javascript function.
Is there any other way without using clone function?
with pure javascript can we do this any other way to display json content in HTML id's
result should be json data like below
Image 1
Name 1
Description 1
product 1
Image 2
Name 2
Description 2
product 2
Image 3
Name 3
Description 3
product
You can build the html as a string using concatenation:
To add a unique id to each row use the index i variable provided by the foreach loop
$(function () {
// Fake JSON result - array of values
json = [{
fields: {
imagem: "Image 1",
nome_produto: "Name 1",
descricao: "Description 1",
preco_produto: "product 1"
}
}, {
fields: {
imagem: "Image 2",
nome_produto: "Name 2",
descricao: "Description 2",
preco_produto: "product 2"
}
}, {
fields: {
imagem: "Image 3",
nome_produto: "Name 3",
descricao: "Description 3",
preco_produto: "product 3"
}
}];
// take a copy of an existing one as a template
$.each(json, function (i, items) {
var clone = '<div class="conteudo" id="conteudo'+i+'"><div class="foto">'+items.fields['imagem']+'</div><div class="inf">'+items.fields['nome_produto']+'</div><div class="inf">'+items.fields['descricao']+'</div><div class="inf">'+items.fields['preco_produto']+'</div></div>'
$('section').append(clone);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
</section>
Related
var codeContent = {
"content": "This is sample content",
"Fields" : [{
"Field name": "Value 1",
"Field Value": "Red color"
}, {
"Field name": "Value 2",
"Field Value": "Orange color"
}]
}
var qr_png = qr.image(codeContent, {
type: 'png',
size: 3, //4 comment
ec_level: 'L',
margin: 0
});
Excepted Output when scanned
I have the following JSON data but would like to implement the HTML page such that it shows the parent as the header and all the children under the same parent under the content and then follow by the second parent as the header and all the children under the second parent under the content. How would I be able to do so? An example would be the following:
Sample 1
Product 1 - Test Product 1
Product 2 - Test Product 2
Sample 2
Product 1 - Test Product 1
"sampleList": [
{
"parent": "Sample 1",
"children": [
{
"product": "Product 1",
"name": "Test Product 1"
}
]
},
{
"parent": "Sample 1",
"children": [
{
"product": "Product 2",
"name": "Test Product 2"
}
]
},
{
"parent": "Sample 2",
"children": [
{
"product": "Product 1",
"name": "Test Product 1"
}
]
}
]
With Array.reduce() to perform group by parent and concatenate array.
Create a new array from result 1 with each object element has parent and children property.
let grouped = this.sampleList.reduce((groups, current) => {
groups[current.parent] = groups[current.parent] || [];
groups[current.parent].push(...current.children);
return groups;
}, Object.create(null));
this.groupedSampleList = Object.keys(grouped).map((key) => ({
parent: key,
children: grouped[key],
}));
If you use es2017, you can work with Object.entries() as:
this.groupedSampleList = Object.entries(grouped).map((value) => ({
parent: value[0],
children: value[1],
}));
<div *ngFor="let parent of groupedSampleList">
<strong>{{ parent.parent }}</strong>
<div *ngFor="let child of parent.children">
{{ child.product }} - {{ child.name }}
</div>
</div>
Demo on StackBlitz
The JSON data structure provided contains duplicate keys which is not ideal. Also, parents with the same value have children stored in separate locations. If the format could be improved such that each parent and child are separate items in the list, it can be easily performed iteratively using a ngFor, which allows you to iterate through data. Providing the JSON key will display the needed child elements. I have included an example below. https://angular.io/api/common/NgForOf
Reformatted Data:
sampleList":
[
{
"parent": "Sample 1",
"children": [
{
"product": "Product 1",
"name": "Test Product 1",
},
{
"product": "Product 1",
"name": "Test Product 1",
}],
},
{
"parent": "Sample 2",
"children": [
{
"product": "Product 1",
"name": "Test Product 1",
}]
}
]
<li *ngFor="let item of sampleList; index as I;">
<h3> {{item.parent}} </h3>
<li *ngFor="let item2 of sampleList[I].children;">
<div> {{item2.product}} - {{item2.name}}</div>
</li>
</li>
I have the following array of objects; however this could be any unknown key/value and be infinitely nested, for now this is a testing sample:
[
{
"reference_id": "R123",
"customer": "Person 1",
"customer_email": "person1#email.com",
"location": "UK",
"bookings": [
{
"product": "Product 1",
"provider": "Company 1",
"cancellable": true
},
{
"product": "Product 2",
"provider": "Company 2",
"cancellable": true
},
{
"product": "Product 3",
"provider": "Company 1",
"cancellable": true
}
]
},
{
"reference_id": "R1234",
"customer": "Person 2",
"customer_email": "person2#email.com",
"location": "USA",
"bookings": [
{
"product": "Product 1",
"provider": "Company 1",
"cancellable": true
},
{
"product": "Product 3",
"provider": "Company 1",
"cancellable": true
}
]
},
{
"reference_id": "R12345",
"customer": "Person 3",
"customer_email": "person3#email.com",
"location": "UK",
"bookings": [
{
"product": "Product 2",
"provider": "Company 2",
"cancellable": true
},
{
"product": "Product 3",
"provider": "Company 1",
"cancellable": true
}
]
}
]
My current implementation is as follows:
const selected = [
{
term: 'Company 1',
column: 'provider',
},
{
term: 'Person 1',
column: 'customer',
},
];
const recursivelyFilterByValue = () => (value) => selected.every((item) => {
if (!value) return false;
if (typeof value === 'string') {
// console.log('value', value === item.term);
return value === item.term;
}
if (Array.isArray(value)) {
return value.some(this.recursivelyFilterByValue());
}
if (typeof value === 'object') {
return Object.values(value).some(this.recursivelyFilterByValue());
}
return false;
});
const results = data.filter(recursivelyFilterByValue());
Basically I am adding to the "selected" array then using that to filter the data array by. I do want to ensure the key matches the "column" also however I haven't added that yet.
For the input above I would expect to output the below:
[
{
"reference_id": "R123",
"customer": "Person 1",
"customer_email": "person1#email.com",
"location": "UK",
"bookings": [
{
"product": "Product 1",
"provider": "Company 1",
"cancellable": true
},
{
"product": "Product 2",
"provider": "Company 2",
"cancellable": true
},
{
"product": "Product 3",
"provider": "Company 1",
"cancellable": true
}
]
},
]
However the output array is empty. If I only search for one term (remove all but one term from selected array) the output is correct for that term however any subsequent terms bring back a blank array.
I'm wondering if my use of .some() is the problem however changing this causes too much recursion errors.
Essentially, I want to return the original parent object so long as there is a key:value match for all my conditions in the selected array, at any level of its children.
Any guidance would be much appreciated, thank you.
I'm not quite sure if this is what you're looking for. It makes the assumption that my guess in the comments was correct:
Do I have this right? You have one (presumably dynamic) condition that says that an object either has a provider property with value "Customer 1" or has a (recursively) descendant object that does. And you have a second condition regarding customer and "Person 1", and you're looking for objects that meet both (or all) such conditions. Does that describe what you're trying to do?
Here we have two fairly simple helper functions, testRecursive and makePredicates as well as the main function, recursivelyFilterByValue:
const testRecursive = (pred) => (obj) =>
pred (obj) || Object (obj) === obj && Object .values (obj) .some (testRecursive (pred))
const makePredicates = (criteria) =>
criteria .map (({term, column}) => (v) => v [column] == term)
const recursivelyFilterByValue = (criteria, preds = makePredicates (criteria)) => (xs) =>
xs .filter (obj => preds .every (pred => testRecursive (pred) (obj)))
const selected = [{term: 'Company 1', column: 'provider'}, {term: 'Person 1', column: 'customer'}]
const input = [{reference_id: "R123", customer: "Person 1", customer_email: "person1#email.com", location: "UK", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R1234", customer: "Person 2", customer_email: "person2#email.com", location: "USA", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R12345", customer: "Person 3", customer_email: "person3#email.com", location: "UK", bookings: [{product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}]
console .log (recursivelyFilterByValue (selected) (input))
.as-console-wrapper {max-height: 100% !important; top: 0}
testRecursive checks whether a predicate is true for an object or for any objects nested inside it.
makePredicates turns an array of {term, column}-objects into predicate functions that test if an object has the proper term in the property named by the column.
recursivelyFilterByValue combines these, calling makePredicates to turn the selected items into predicate functions, then filtering the input by testing if each of the predicates is true.
This is not the most efficient code imaginable. It rescans the hierarchy for each predicate. I'm sure we could figure out a version to do the scan only once, but I think it would make for much more complex code. So you might want to test in your production-sized data whether it's fast enough for your needs.
This solution is not as beautifully elegant as an accepted answer, but why not show my efforts. Perhaps someone will find this way more understandable.
const selected = [{term: 'Company 1', column: 'provider'}, {term: 'Person 1', column: 'customer'}]
const input = [{reference_id: "R123", customer: "Person 1", customer_email: "person1#email.com", location: "UK", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R1234", customer: "Person 2", customer_email: "person2#email.com", location: "USA", bookings: [{product: "Product 1", provider: "Company 1", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}, {reference_id: "R12345", customer: "Person 3", customer_email: "person3#email.com", location: "UK", bookings: [{product: "Product 2", provider: "Company 2", cancellable: true}, {product: "Product 3", provider: "Company 1", cancellable: true}]}]
const iter = (obj, sel) =>
Object.entries(obj).some(([key, value]) => {
if (Array.isArray(value))
return value.some((obj) => iter(obj, sel));
if (typeof value === 'object' && value !== null)
return iter(value, sel);
return (key === sel.column) && (value === sel.term);
});
const deepFilter = (arr, sels) =>
arr.filter((obj) =>
sels.every((sel) => iter(obj, sel)));
console.dir(deepFilter(input, selected), {depth: null});
.as-console-wrapper {max-height: 100% !important; top: 0}
I have a nested array of objects and want to get only the child property elements of an array. This is just an example and the actual data will include a unique children property in separate indices in the array. I am only able to traverse the first array in the list.
Here is my implementation:
const headers = [{
id: "name1",
title: "Name 1",
children: [{
title: "Children 1",
child: [{
title: "Child 1",
onClick: "child1Click"
},
{
title: "Child 2",
onClick: "child2Click"
}
]
},
{
title: "CHildren 2",
child: [{
title: "Child 3",
id: "child3Click"
},
{
title: "Child 4",
id: "child4Click"
}
]
}
]
},
{
id: "name2",
title: "Name 2",
children: [{
title: "Children 3",
child: [{
title: "Child 5",
onClick: "child5Click"
},
{
title: "Child 6",
onClick: "child6Click"
}
]
},
{
title: "CHildren 4",
child: [{
title: "Child 7",
id: "child7Click"
},
{
title: "Child 8",
id: "child8Click"
}
]
}
]
},
{
id: "name3",
title: "Name 3"
},
{
id: "name4",
title: "Name 4"
}
]
console.log(_.flattenDeep(_.map(_.compact(_.map(headers, item => item.children))[0], item1 => item1.child)))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Expected Output:
[
{
"title": "Child 1",
"onClick": "child1Click"
},
{
"title": "Child 2",
"onClick": "child2Click"
},
{
"title": "Child 3",
"id": "child3Click"
},
{
"title": "Child 4",
"id": "child4Click"
},
{
"title": "Child 5",
"onClick": "child5Click"
},
{
"title": "Child 6",
"onClick": "child6Click"
},
{
"title": "Child 7",
"id": "child7Click"
},
{
"title": "Child 8",
"id": "child8Click"
}
]
Please advice.
Edit: I was able to get the required result using console.log(.flattenDeep(.map(.flattenDeep(.compact(_.map(headers, 'children'))), 'child')))
But is there an optimized version for doing the same? Thanks
Get the children with _.flatMap(), filter out the undefined values, and then use _.flatMap() again to get the values of the child property:
const headers = [{"id":"name1","title":"Name 1","children":[{"title":"Children 1","child":[{"title":"Child 1","onClick":"child1Click"},{"title":"Child 2","onClick":"child2Click"}]},{"title":"CHildren 2","child":[{"title":"Child 3","id":"child3Click"},{"title":"Child 4","id":"child4Click"}]}]},{"id":"name2","title":"Name 2","children":[{"title":"Children 3","child":[{"title":"Child 5","onClick":"child5Click"},{"title":"Child 6","onClick":"child6Click"}]},{"title":"CHildren 4","child":[{"title":"Child 7","id":"child7Click"},{"title":"Child 8","id":"child8Click"}]}]},{"id":"name3","title":"Name 3"},{"id":"name4","title":"Name 4"}]
const result = _.flatMap(_.compact(_.flatMap(headers, 'children')), 'child')
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
If you're using lodash/fp, you can generate a more readable function with _.flow():
const fn = _.flow(
_.flatMap('children'),
_.compact,
_.flatMap('child')
)
const headers = [{"id":"name1","title":"Name 1","children":[{"title":"Children 1","child":[{"title":"Child 1","onClick":"child1Click"},{"title":"Child 2","onClick":"child2Click"}]},{"title":"CHildren 2","child":[{"title":"Child 3","id":"child3Click"},{"title":"Child 4","id":"child4Click"}]}]},{"id":"name2","title":"Name 2","children":[{"title":"Children 3","child":[{"title":"Child 5","onClick":"child5Click"},{"title":"Child 6","onClick":"child6Click"}]},{"title":"CHildren 4","child":[{"title":"Child 7","id":"child7Click"},{"title":"Child 8","id":"child8Click"}]}]},{"id":"name3","title":"Name 3"},{"id":"name4","title":"Name 4"}]
const result = fn(headers)
console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash#4(lodash.min.js+lodash.fp.min.js)'></script>
Using lodash with _.flow() and _.partialRight():
const pr = _.partialRight;
const fn = _.flow(
pr(_.flatMap, 'children'),
_.compact,
pr(_.flatMap, 'child')
)
const headers = [{"id":"name1","title":"Name 1","children":[{"title":"Children 1","child":[{"title":"Child 1","onClick":"child1Click"},{"title":"Child 2","onClick":"child2Click"}]},{"title":"CHildren 2","child":[{"title":"Child 3","id":"child3Click"},{"title":"Child 4","id":"child4Click"}]}]},{"id":"name2","title":"Name 2","children":[{"title":"Children 3","child":[{"title":"Child 5","onClick":"child5Click"},{"title":"Child 6","onClick":"child6Click"}]},{"title":"CHildren 4","child":[{"title":"Child 7","id":"child7Click"},{"title":"Child 8","id":"child8Click"}]}]},{"id":"name3","title":"Name 3"},{"id":"name4","title":"Name 4"}]
const result = fn(headers)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Here is my data:
{
"bracketName": "Set Bracket Name",
"bracketId": "tTzbUZ",
"modID": "B11PTVjERm",
"creationDate": 1503352813796,
"teams": [{
"name": "team 1",
},
{
"name": "team 2",
},
{
"name": "team 2",
}
]
}
I am trying to get the position of the team. Here is my code:
var content = fs.readFileSync('brackets/' + data.bracket + '.json');
content = JSON.parse(content);
content.teams.indexOf({"name": "team 2"});
But it doesn't work. I'm not sure how to do this. Could somebody help me?
content.teams.findIndex(team => team.name == 'team 2')
You can use findIndex. For example:
content.teams.findIndex(x => x.name=="team 2")