kendo ui Listbox remove item

1.3k Views Asked by At

Hey all I need some help with getting a selected item and removing it from the kendoListBox.

I currently have successfully been able to add the checked item(s) into the kendoListBox when checking an item in the kendoTreeView but I am unable to find how to go about removing an item when I uncheck it from the kendoTreeView.

let apiData = {
  "object_list": [{
    "Name": "facebook",
    "Description": null,
    "Id": "eb8cb0c8c32d1201bff30cf54S4f30889abb23f92b1f7",
    "DocumentType": null,
    "ProviderId": 2,
    "Cat": "Social Networks"
  }, {
    "Name": "twitter",
    "Description": null,
    "Id": "732fe66cce4365bc5074384f09b34e787f3f3efe8b55",
    "DocumentType": null,
    "ProviderId": 2,
    "Cat": "Social Networks"
  }, {
    "Name": "Google",
    "Description": null,
    "Id": "8b11d6f7b74bf71a7ddbc62dcfead27087e0f3e047e",
    "DocumentType": null,
    "ProviderId": 2,
    "Cat": "Search Engines"
  }]
};

$("#treeview").kendoTreeView({
  checkboxes: {
    checkChildren: true
  },
  check: onCheck,
  dataSource: {
    data: apiData,
    schema: {
      model: {
        children: 'items'
      },
      parse: (data) => {
        let newData = [];

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

          if (!parent) {
            parent = {
              id: 2,
              text: item.Cat,
              expanded: true,
              items: [],
              spriteCssClass: "folder"
            };

            newData.push(parent);
          }

          parent.items.push({
            id: 3,
            text: item.Name,
            spriteCssClass: "image"
          });
        });

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

$("#Sources").kendoListBox();

function onCheck(e) {
  var checkedNodes = [];
  var checkedNode = e.node.innerText;
  
  console.log(e.node.innerText);
  
  if (e.node.ariaChecked == "false") {
    console.log("Its already selected *REMOVE*");
    var listBox = $("#Sources").data("kendoListBox");
    
    console.log(listBox);
    
  } else {
    console.log("Its just now been selected *ADD*");
    var listBox = $("#Sources").data("kendoListBox");

    listBox.add({
      text: checkedNode,
      value: checkedNode
    });
  }
}

function onExpand(e) {
  if ($("#tbSourcesFilter").val() == "") {
    $(e.node).find("li").show();
  }
}

$("#tbSourcesFilter").keyup(function(e) {
  var filterText = $(this).val().toLowerCase();

  //console.log("filterText: ", filterText);

  if (filterText !== "") {
    $("#treeview .k-group .k-group .k-in").closest("li").hide();
    $("#treeview .k-group").closest("li").hide();

    $("#treeview .k-in:contains(" + filterText + ")").each(function() {
      $(this).parents("ul, li").each(function() {
        var treeView = $("#treeview").data("kendoTreeView");
        treeView.expand($(this).parents("li"));
        $(this).show();
      });
    });

    $("#treeview .k-group .k-in:contains(" + filterText + ")").each(function() {
      $(this).parents("ul, li").each(function() {
        $(this).show();
      });
    });
  } else {
    //console.log("k-group: ", $("#treeview .k-group").find("li").show());
    $("#treeview .k-group").find("li").show();
    var nodes = $("#treeview > .k-group > li");
    //console.log("nodes: ", nodes);

    $.each(nodes, function(i, val) {
      //console.log(nodes[i].getAttribute("data-expanded"));
      if (nodes[i].getAttribute("data-expanded") == null) {
        $(nodes[i]).find("li").hide();
      }
    });
  }
});
        #treeview .k-sprite {
          background-image: url("../content/web/treeview/coloricons-sprite.png");
        }

        .rootfolder {
          background-position: 0 0;
        }

        .folder {
          background-position: 0 -16px;
        }

        .pdf {
          background-position: 0 -32px;
        }

        .html {
          background-position: 0 -48px;
        }

        .image {
          background-position: 0 -64px;
        }

        #filterText {
          width: 100%;
          box-sizing: border-box;
          padding: 6px;
          border-radius: 3px;
          border: 1px solid #d9d9d9;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.common.min.css">
      <link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.rtl.min.css">
      <link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.default.min.css">
      <link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.mobile.all.min.css">
      <script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/angular.min.js"></script>
      <script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/jszip.min.js"></script>
      <script type="text/javascript" src="http://cdn.kendostatic.com/2021.1.330/js/kendo.all.min.js"></script>
<input id="filterText" type="text" placeholder="Search categories" />
<div id="treeview"></div>
<select id="Sources"></select>

I have seen a few examples but they all seem to do nothing.

This code below does remove the selected item in the (hidden) select box but not from the kendoListBox.

$("select option[value='" + checkedNode + "']").remove();

It seems that the Kendo UI places this into the kendoListBox when adding an item.

<li class="k-item" role="option" aria-selected="false">facebook</li>

And the code here only shows how to remove the first item in the kendoListBox and not a selected one.

var listBox = $("#listBox").data("kendoListBox");
listBox.remove(listBox.items().first());

I'm sure it will be something easy I am overlooking but it would be great for someone to help me out in finding a way to remove it via the kendoUI api/commands.

2

There are 2 best solutions below

2
DontVoteMeDown On BEST ANSWER

You can do it in two ways:

  1. Using ListBox's remove() method with the target node selected by jQuery:

let apiData = {
  "object_list": [{
    "Name": "facebook",
    "Description": null,
    "Id": "eb8cb0c8c32d1201bff30cf54S4f30889abb23f92b1f7",
    "DocumentType": null,
    "ProviderId": 2,
    "Cat": "Social Networks"
  }, {
    "Name": "twitter",
    "Description": null,
    "Id": "732fe66cce4365bc5074384f09b34e787f3f3efe8b55",
    "DocumentType": null,
    "ProviderId": 2,
    "Cat": "Social Networks"
  }, {
    "Name": "Google",
    "Description": null,
    "Id": "8b11d6f7b74bf71a7ddbc62dcfead27087e0f3e047e",
    "DocumentType": null,
    "ProviderId": 2,
    "Cat": "Search Engines"
  }]
};

$("#treeview").kendoTreeView({
  checkboxes: {
    checkChildren: true
  },
  check: onCheck,
  dataSource: {
    data: apiData,
    schema: {
      model: {
        children: 'items'
      },
      parse: (data) => {
        let newData = [];

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

          if (!parent) {
            parent = {
              id: 2,
              text: item.Cat,
              expanded: true,
              items: [],
              spriteCssClass: "folder"
            };

            newData.push(parent);
          }

          parent.items.push({
            id: 3,
            text: item.Name,
            spriteCssClass: "image"
          });
        });

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

$("#Sources").kendoListBox();

function onCheck(e) {
  let checkedNodes = [],
      checkedNode = e.node.innerText,
      listBox = $("#Sources").data("kendoListBox");
  
  console.log(e.node.innerText);
  
  if (e.node.ariaChecked == "false") {
    let $listBoxItem = listBox.wrapper.find(`li:contains("${e.node.innerText}")`);
    listBox.remove($listBoxItem);
  } else {
    listBox.add({
      text: checkedNode,
      value: checkedNode
    });
  }
}

function onExpand(e) {
  if ($("#tbSourcesFilter").val() == "") {
    $(e.node).find("li").show();
  }
}

$("#tbSourcesFilter").keyup(function(e) {
  var filterText = $(this).val().toLowerCase();

  //console.log("filterText: ", filterText);

  if (filterText !== "") {
    $("#treeview .k-group .k-group .k-in").closest("li").hide();
    $("#treeview .k-group").closest("li").hide();

    $("#treeview .k-in:contains(" + filterText + ")").each(function() {
      $(this).parents("ul, li").each(function() {
        var treeView = $("#treeview").data("kendoTreeView");
        treeView.expand($(this).parents("li"));
        $(this).show();
      });
    });

    $("#treeview .k-group .k-in:contains(" + filterText + ")").each(function() {
      $(this).parents("ul, li").each(function() {
        $(this).show();
      });
    });
  } else {
    //console.log("k-group: ", $("#treeview .k-group").find("li").show());
    $("#treeview .k-group").find("li").show();
    var nodes = $("#treeview > .k-group > li");
    //console.log("nodes: ", nodes);

    $.each(nodes, function(i, val) {
      //console.log(nodes[i].getAttribute("data-expanded"));
      if (nodes[i].getAttribute("data-expanded") == null) {
        $(nodes[i]).find("li").hide();
      }
    });
  }
});
#treeview .k-sprite {
          background-image: url("../content/web/treeview/coloricons-sprite.png");
        }

        .rootfolder {
          background-position: 0 0;
        }

        .folder {
          background-position: 0 -16px;
        }

        .pdf {
          background-position: 0 -32px;
        }

        .html {
          background-position: 0 -48px;
        }

        .image {
          background-position: 0 -64px;
        }

        #filterText {
          width: 100%;
          box-sizing: border-box;
          padding: 6px;
          border-radius: 3px;
          border: 1px solid #d9d9d9;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.common.min.css">
      <link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.rtl.min.css">
      <link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.default.min.css">
      <link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.mobile.all.min.css">
      <script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/angular.min.js"></script>
      <script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/jszip.min.js"></script>
      <script type="text/javascript" src="http://cdn.kendostatic.com/2021.1.330/js/kendo.all.min.js"></script>
<input id="filterText" type="text" placeholder="Search categories" />
<div id="treeview"></div>
<select id="Sources"></select>

  1. Using DataSource's remove() method with the target Model selected from dataItems():

let apiData = {
  "object_list": [{
    "Name": "facebook",
    "Description": null,
    "Id": "eb8cb0c8c32d1201bff30cf54S4f30889abb23f92b1f7",
    "DocumentType": null,
    "ProviderId": 2,
    "Cat": "Social Networks"
  }, {
    "Name": "twitter",
    "Description": null,
    "Id": "732fe66cce4365bc5074384f09b34e787f3f3efe8b55",
    "DocumentType": null,
    "ProviderId": 2,
    "Cat": "Social Networks"
  }, {
    "Name": "Google",
    "Description": null,
    "Id": "8b11d6f7b74bf71a7ddbc62dcfead27087e0f3e047e",
    "DocumentType": null,
    "ProviderId": 2,
    "Cat": "Search Engines"
  }]
};

$("#treeview").kendoTreeView({
  checkboxes: {
    checkChildren: true
  },
  check: onCheck,
  dataSource: {
    data: apiData,
    schema: {
      model: {
        children: 'items'
      },
      parse: (data) => {
        let newData = [];

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

          if (!parent) {
            parent = {
              id: 2,
              text: item.Cat,
              expanded: true,
              items: [],
              spriteCssClass: "folder"
            };

            newData.push(parent);
          }

          parent.items.push({
            id: 3,
            text: item.Name,
            spriteCssClass: "image"
          });
        });

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

$("#Sources").kendoListBox();

function onCheck(e) {
  let checkedNodes = [],
      checkedNode = e.node.innerText,
      listBox = $("#Sources").data("kendoListBox");
  
  console.log(e.node.innerText);
  
  if (e.node.ariaChecked == "false") {
    let listBoxItem = listBox.dataItems().find(item => item.text === e.node.innerText);
    
    if (listBoxItem) {
      listBox.dataSource.remove(listBoxItem);
    }
    
  } else {
    listBox.add({
      text: checkedNode,
      value: checkedNode
    });
  }
}

function onExpand(e) {
  if ($("#tbSourcesFilter").val() == "") {
    $(e.node).find("li").show();
  }
}

$("#tbSourcesFilter").keyup(function(e) {
  var filterText = $(this).val().toLowerCase();

  //console.log("filterText: ", filterText);

  if (filterText !== "") {
    $("#treeview .k-group .k-group .k-in").closest("li").hide();
    $("#treeview .k-group").closest("li").hide();

    $("#treeview .k-in:contains(" + filterText + ")").each(function() {
      $(this).parents("ul, li").each(function() {
        var treeView = $("#treeview").data("kendoTreeView");
        treeView.expand($(this).parents("li"));
        $(this).show();
      });
    });

    $("#treeview .k-group .k-in:contains(" + filterText + ")").each(function() {
      $(this).parents("ul, li").each(function() {
        $(this).show();
      });
    });
  } else {
    //console.log("k-group: ", $("#treeview .k-group").find("li").show());
    $("#treeview .k-group").find("li").show();
    var nodes = $("#treeview > .k-group > li");
    //console.log("nodes: ", nodes);

    $.each(nodes, function(i, val) {
      //console.log(nodes[i].getAttribute("data-expanded"));
      if (nodes[i].getAttribute("data-expanded") == null) {
        $(nodes[i]).find("li").hide();
      }
    });
  }
});
#treeview .k-sprite {
          background-image: url("../content/web/treeview/coloricons-sprite.png");
        }

        .rootfolder {
          background-position: 0 0;
        }

        .folder {
          background-position: 0 -16px;
        }

        .pdf {
          background-position: 0 -32px;
        }

        .html {
          background-position: 0 -48px;
        }

        .image {
          background-position: 0 -64px;
        }

        #filterText {
          width: 100%;
          box-sizing: border-box;
          padding: 6px;
          border-radius: 3px;
          border: 1px solid #d9d9d9;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.common.min.css">
      <link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.rtl.min.css">
      <link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.default.min.css">
      <link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.mobile.all.min.css">
      <script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/angular.min.js"></script>
      <script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/jszip.min.js"></script>
      <script type="text/javascript" src="http://cdn.kendostatic.com/2021.1.330/js/kendo.all.min.js"></script>
<input id="filterText" type="text" placeholder="Search categories" />
<div id="treeview"></div>
<select id="Sources"></select>

2
G_P On

If the text of your entries is unique, you could follow the code from here which shows how to remove an entry in the listbox by text (it actually does a contains search, so may need to alter it): https://demos.telerik.com/kendo-ui/listbox/api

Here it is added to your onCheck method

function onCheck(e) {
  var checkedNodes = [];
  var checkedNode = e.node.innerText;
  
  console.log(e.node.innerText);
  
  if (e.node.ariaChecked == "false") {
    console.log("Its already selected *REMOVE*");
    var listBox = $("#Sources").data("kendoListBox");
    
    var text = e.node.innerText;
    var items = listBox.items();
    for (var i = 0; i < items.length; i++) {
        var dataItem = listBox.dataItem(items[i]);
        if (dataItem.Name.toLowerCase().indexOf(text) >= 0) { //WARNING - Contains Search here- may need to change depending on your requirements
            listBox.remove(items[i]);
        }
    }

    console.log(listBox);
    
  } else {
    console.log("Its just now been selected *ADD*");
    var listBox = $("#Sources").data("kendoListBox");

    listBox.add({
      text: checkedNode,
      value: checkedNode
    });
  }
}

If the text is not unique you would have to look at going based on the id's of the underlying dataitem I guess.

Reference links: For ListView - but should work with ListBox https://docs.telerik.com/kendo-ui/knowledge-base/check-listview-item-selected

https://docs.telerik.com/kendo-ui/api/javascript/ui/listbox/methods/select