javascriptjquerysortingkendo-uikendo-treeview

Sorting Kendo UI Jquery treeview child items in each parent item A-Z


Hey all I am trying to find the correct way to order/sort my child names in order from A-Z.

Currently my treeview looks like this:

enter image description here

And this is how I would like to sort it:

enter image description here

The data is coming in via JSON like so (using the above example):

[{
        "Name": "AU",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Academic",
        "Icon": null,
        "ProviderId": 2
    }, {
        "Name": "Gitlab",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Code Repos",
        "Icon": null,
        "ProviderId": 2
    }, {
        "Name": "B",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Dating",
        "Icon": null,
        "ProviderId": 2
    }, {
        "Name": "GitHubCommits",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Code Repos",
        "Icon": null,
        "ProviderId": 2
    }, {
        "Name": "GitHub",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Code Repos",
        "Icon": null,
        "ProviderId": 2
    }, {
        "Name": "Re",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Academic",
        "Icon": null,
        "ProviderId": 2
    }, {
        "Name": "Ir",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Dating",
        "Icon": null,
        "ProviderId": 2
    }, {
        "Name": "Ru",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Academic",
        "Icon": null,
        "ProviderId": 2
    }, {
        "Name": "LoveA",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Dating",
        "Icon": null,
        "ProviderId": 2
    }, {
        "Name": "LoveH",
        "Description": null,
        "Id": "xxx",
        "DocumentType": null,
        "Category": "Dating",
        "Icon": null,
        "ProviderId": 2
    },.........
]

Note that the JSON above does not come in any type of order and there are also other category's but I left those out for simplicity sake. The Category names themselves are in order by me doing this:

dataSource: {
   data: resultData,
   schema: {
       model: {
          children: 'items'
       },
       parse: (data) => {
          let newData = [];

           //Re-order catagory names A-Z
           data.sort((a, b) => (a.Category > b.Category) ? 1 : -1);

....

The rest of the above code looks like this::

           data.forEach(item => {
              let parent = newData.find(parentItem => parentItem.text === item.Category);

              if (!parent) {
                 //The beginning of the tree category
                 parent = {
                     id: 2,
                     text: item.Category,
                     expanded: true,
                     items: [],
                     imageUrl: "" + item.Icon + ""
                 };

                 newData.push(parent);
              }

              parent.items.push({
                 //Each "child" under the above category
                 id: 3,
                 text: item.Name,
                 imageUrl: "" + item.Icon + ""
              });
           });

           return [{
              id: 1,
              text: 'Categories',
              expanded: true,
              items: newData
           }];
       }
   }
 }
});

How would I, using the code above, sort also the child items under each category name?

I've tried already adding this to the code:

sort: {
   field: "Name", 
   dir: "asc"
}

But that does not seem to do anything?


Solution

  • Add this:

    newData.forEach(item => {
        if (item.items || item.items.length) {
            item.items.sort((a, b) => (a.text > b.text) ? 1 : -1);
        }
    });
    

    ... before the return in parse event.

    Demo:

    <!DOCTYPE html>
    <html>
    <head>
        <base href="https://demos.telerik.com/kendo-ui/treeview/local-data-binding">
        <style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
        <title></title>
        <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2021.2.511/styles/kendo.default-v2.min.css" />
    
        <script src="https://kendo.cdn.telerik.com/2021.2.511/js/jquery.min.js"></script>
        
        
        <script src="https://kendo.cdn.telerik.com/2021.2.511/js/kendo.all.min.js"></script>
        
        
    
    </head>
    <body>
        <div id="example">
    
        <div class="demo-section k-content">
            <div>
                <div id="treeview-left"></div>
            </div>
        </div>
    
        <script>
            var inlineDefault = new kendo.data.HierarchicalDataSource({
                data: [{
                    "Name": "AU",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Academic",
                    "Icon": null,
                    "ProviderId": 2
                }, {
                    "Name": "Gitlab",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Code Repos",
                    "Icon": null,
                    "ProviderId": 2
                }, {
                    "Name": "B",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Dating",
                    "Icon": null,
                    "ProviderId": 2
                }, {
                    "Name": "GitHubCommits",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Code Repos",
                    "Icon": null,
                    "ProviderId": 2
                }, {
                    "Name": "GitHub",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Code Repos",
                    "Icon": null,
                    "ProviderId": 2
                }, {
                    "Name": "Re",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Academic",
                    "Icon": null,
                    "ProviderId": 2
                }, {
                    "Name": "Ir",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Dating",
                    "Icon": null,
                    "ProviderId": 2
                }, {
                    "Name": "Ru",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Academic",
                    "Icon": null,
                    "ProviderId": 2
                }, {
                    "Name": "LoveA",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Dating",
                    "Icon": null,
                    "ProviderId": 2
                }, {
                    "Name": "LoveH",
                    "Description": null,
                    "Id": "xxx",
                    "DocumentType": null,
                    "Category": "Dating",
                    "Icon": null,
                    "ProviderId": 2
                }],
              schema: {
               model: {
                  children: 'items'
               },
               parse: (data) => {
                  let newData = [];
    
                   //Re-order catagory names A-Z
                   data.sort((a, b) => (a.Category > b.Category) ? 1 : -1);
                 
                   data.forEach(item => {
                    let parent = newData.find(parentItem => parentItem.text === item.Category);
    
                    if (!parent) {
                       //The beginning of the tree category
                       parent = {
                           id: 2,
                           text: item.Category,
                           expanded: true,
                           items: [],
                           imageUrl: "" + item.Icon + ""
                       };
    
                       newData.push(parent);
                    }
    
                    parent.items.push({
                       //Each "child" under the above category
                       id: 3,
                       text: item.Name,
                       imageUrl: "" + item.Icon + ""
                    });
                 });
                 
                 newData.forEach(item => {
                   if (item.items || item.items.length) {
                    item.items.sort((a, b) => (a.text > b.text) ? 1 : -1);
                   }
                 });
    
                 return [{
                    id: 1,
                    text: 'Categories',
                    expanded: true,
                    items: newData
                 }];
               }
             }
            });
    
            $("#treeview-left").kendoTreeView({
                dataSource: inlineDefault
            });
        </script>
    
        <style>
            .demo-section{
                display:flex;
                justify-content:space-evenly;
            }
        </style>
    </div>
    
    
        
    
    </body>
    </html>

    Dojo

    Note that GitHubCommits will never come on top of GitHub in a common text sorting. Also note that the code i suggested only works for one level of items, for more levels it will need to be recursive.