I have an array of objects. I have to somehow process this data and create an HTML document. I have no problems with HTML and CSS, but don't know where to start with JS and how to process the data. I don't even understand how to describe my problem correctly in order to Google some similar solutions. Can anyone help me to make a plan what exactly I should do?
I've made a picture describing the logic. When users click the button, they'll see a menu (in a block looks like a dropdown menu), then they can go through category and select the item they want to choose. Please note that there's only one block, in the pic I'm just showing the logic. After that, below the user can see the list of items they selected
const menu = [{
categories: [{
id: 1,
name: 'Desserts',
categories: [{
id: 2,
name: 'Ice cream',
categories: [{
id: 3,
name: 'Vanilla',
categories: []
}, {
id: 4,
name: 'Strawberry',
categories: []
}]
}, {
id: 5,
name: 'Baked apples',
categories: []
}]
}, {
id: 6,
name: 'Coffee',
categories: []
}, {
id: 7,
name: 'Tea',
categories: [{
id: 8,
name: 'Green tea',
categories: [{
id: 9,
name: 'With Jasmine',
categories: []
}, {
id: 10,
name: 'Simple',
categories: []
}]
}, {
id: 11,
name: 'Black Tea',
categories: []
}]
}]
}]
CodePudding user response:
Below I show you the one of sample logic. You can add more looping and styles as per the level of categories and requirements you have;
var objData= JSON.parse(aResultData);
var sHtml = '<ul>';
for(var i=0; i<objData.length; i ) {
sHtml = sHtml '<li>' objFundSourceData[i].name '</li>';
if (objFundSourceData[i].categories.length>0) {
for(var j=0; j<objData.length; j ) {
if (j==0) {
sHtml = sHtml '<ul>' objFundSourceData[j].name '</ul>';
} else {
sHtml = sHtml '<li>' objFundSourceData[j].name '</li>';
}
if (objFundSourceData[j].categories.length>0) {
for(var k=0; k<objData.length; k ) {
if (k==0) {
sHtml = sHtml '<ul>' objFundSourceData[k].name '</ul>';
} else {
sHtml = sHtml '<li>' objFundSourceData[k].name '</li>';
}
}
}
}
}
}
sHtml = sHtml '</ul>'
CodePudding user response:
In this approach, I first flatten your object structure assigning each item a reference to its parent's ID.
The array structured this way easily allows you to filter
"subitems".
const menu = [{
categories: [{
id: 1,
name: 'Desserts',
categories: [{
id: 2,
name: 'Ice cream',
categories: [{
id: 3,
name: 'Vanilla',
categories: []
}, {
id: 4,
name: 'Strawberry',
categories: []
}]
}, {
id: 5,
name: 'Baked apples',
categories: []
}]
}, {
id: 6,
name: 'Coffee',
categories: []
}, {
id: 7,
name: 'Tea',
categories: [{
id: 8,
name: 'Green tea',
categories: [{
id: 9,
name: 'With Jasmine',
categories: []
}, {
id: 10,
name: 'Simple',
categories: []
}]
}, {
id: 11,
name: 'Black Tea',
categories: []
}]
}]
}]
const m = menu[0].categories
// THIS WILL BE THE FLAT ARRAY OF ITEMS IN MENU
let arr = []
// ITERATE ROOT CATEGORIES
for (let cat of m) {
// FOR EACH CATEGORY, CALL THE RECURSIVE FUNCTION
recurCats(cat, 0)
}
// HERE IS THE FLAT ARRAY
console.log(arr)
const level0 = arr.filter(item => item.parentID == 0).map(item => '<option data-id="' item.id '" value="' item.name '">' item.name '</option>')
document.getElementById('s1').innerHTML = '<option value="0">Select an item</option>' level0.join('')
document.getElementById('s1').addEventListener('change', function() {
let thisID = this.options[this.selectedIndex].getAttribute('data-id')
const level1 = arr.filter(item => item.parentID == thisID).map(item => '<option data-id="' item.id '" value="' item.name '">' item.name '</option>')
document.getElementById('s2').innerHTML = '<option value="0">Select an item</option>' level1.join('')
})
document.getElementById('s2').addEventListener('change', function() {
let thisID = this.options[this.selectedIndex].getAttribute('data-id')
const level2 = arr.filter(item => item.parentID == thisID).map(item => '<option data-id="' item.id '" value="' item.name '">' item.name '</option>')
document.getElementById('s3').innerHTML = '<option value="0">Select an item</option>' level2.join('')
})
// RECURSIVE FUNCTION
function recurCats(cat, parentID) {
arr.push({
name: cat.name,
id: cat.id,
parentID: parentID
})
if (cat.hasOwnProperty('categories') && cat.categories.length > 0) {
for (let subcat of cat.categories) {
recurCats(subcat, cat.id)
}
}
}
<select id="s1"></select>
<select id="s2"></select>
<select id="s3"></select>