JSFiddle - React, Tailwind, and code Playground
by Francesco Frustaci
HTML
<script id="nodeTempl" type="text/html">
<li>
<a data-bind="text: Text"></a>
<ul data-bind="template: {name: nodeTemplate, foreach: children }"></ul>
</li>
</script>
<script id="nodeLeafTempl" type="text/html">
<li>
<a data-bind="text: Text"></a>
</li>
</script>
<ul data-bind="template: {name: nodeTemplate, foreach: children }"></ul>
JavaScript
var serverData = [
{
Id: "menuColorSearch",
Text: "Color search"
},
{
Id: "menuAncillaryProductMix",
ParentId: 'menuColorSearch',
Text: "Ancillary product mix"
},
{
Id: "menuDocuments",
Text: "Documents"
},
{
Id: "menuColorInfo",
ParentId: "menuReports",
Text: "Color info"
},
{
Id: "menuReports",
ParentId: "menuDocuments",
Text: "Reports"
},
{
Id: "menuMaintenance",
ParentId: 'menuReports',
Text: "Maintenance"
},
{
Id: "menuPriceManagement",
ParentId: "menuMaintenance",
Text: "Price management"
}
];
function getNestedMenu(index, all) {
var root = all[index];
if(!root){
return all;
}
if(!all[index].children){
all[index].children = [];
}
for(var i = 0; i < all.length; i++){
//<infinity nesting?>
//put children inside it's parent
if(all[index].Id == all[i].ParentId){
all[index].children.push(all[i]);
all[i].used = true;
}
//this is needed for each item, to determine which template to use
all[index].nodeTemplate = function(node) {
return node.children.length > 0 ? 'nodeTempl' : 'nodeLeafTempl';
}
//</infinity nesting?>
}
return getNestedMenu(++index, all);
};
function getModel(data) {
var items = getNestedMenu(0, data);
//<remove duplicates, for infinity nesting only>
for(var i = 0; i < items.length; i++){
if(items[i].used){
items.splice(i, 1);
i--;
}
}
//</remove duplicates, for infinity nesting only>
//<build root item>
var model = {};
model.children = ko.observableArray(items);
model.nodeTemplate = function(node) {
return...