New to Kendo UI for jQuery? Download free 30-day trial

Create an External Columns Menu

Environment

Product Version 2020.1.114
Product Progress® Kendo UI® Grid for jQuery

Description

Is there a way to add an external columns menu with checkbox functionality outside to the Kendo UI Grid?

Solution

Using the Kendo UI Grid's API, you can take advantage of the hideColumn and showColumn methods. These can be used in an external component, such as a Kendo UI Menu, outside of the Grid.

Here's one approach you can take to add an external Kendo UI Menu with checkbox functionality based on the Kendo UI Grid column's hidden field:

  1. Reference the Grid Columns.

            //reference grid
            var grid = $("#grid").data("kendoGrid");
    
            //reference columns
            var columnValues = grid.columns;
    
  2. Create an array and loop through the grid columns hidden field. If it's not hidden, push the "checked" string.

            //Create array
            var checkedValues = [];
    
            //for each column, add checked if hidden is undefined
            $(columnValues).each(function(index){
    
              if (this.hidden == true) {
                checkedValues.push(" ");
              } else {
                checkedValues.push("checked");
              }
            });    
    
  3. Get the Kendo UI Menu, append the first item, and reference it.

            //reference the Kendo UI Menu
            var menu = $("#columnMenu").data("kendoMenu");
    
            //create initial first item
            menu.append({text: "Columns"});
    
            //reference it through jQuery
            var firstItem = $("#columnMenu").children("li").eq(0);
    
  4. For each of the Grid columns, append a new Kendo UI Menu Item with a checkbox element. Include the array which will hold if the column will be checked initially or not.

            //for each column, append checkboxes with checked values based on hidden field
            $(columnValues).each(function(index){
              menu.append({ text: "<input type='checkbox' " + checkedValues[index] + " />"+ grid.columns[index].field, encoded: false }, firstItem);         
            });
    
  5. When a user selects a column from the menu, the Kendo UI Menu's select event is fired.

    1. Make a reference to the Grid.
    2. Determine how many hidden columns are in the Grid to always keep one.
    3. Based on the column's field, use the showColumn or hideColumn method.
    4. If the item is shown, check the box. Otherwise, uncheck it. If it's the last item, keep the box checked.
            function onSelect(e){
    
              //reference checkbox
              var checkbox = $(e.item).find("input");
    
              //reference the Grid
              var grid = $("#grid").data("kendoGrid");  
    
              //hold the number of columns
              var numOfColumns = grid.columns.length;  
    
              //loop through to find how many columns are hidden
              for (var i = 0; i < grid.columns.length; i++) {  
                if (grid.columns[i].hidden == true){
                  numOfColumns--;
                }
              }
    
              //if the field matches the selected item, check if it is hidden or not.
              for (var i = 0; i < grid.columns.length; i++) {
                if(grid.columns[i].field == e.item.innerText){
    
                  //Show the hidden column
                  if (grid.columns[i].hidden == true){
                    grid.showColumn(grid.columns[i].field);
    
                    //check box
                    $(checkbox).prop("checked", true);
    
                    //it will hide as long as there is more than one column in the Grid
                  } else if(numOfColumns != 1){
                    grid.hideColumn(grid.columns[i].field);
    
                    //uncheck box
                    $(checkbox).prop("checked", false);
                  } else {
    
                    //check box if it's the last item
                    $(checkbox).prop("checked", true);
                  }
                }
              }
            }
    
    
  6. Finally, you may want to remove the columns section from the Grid's columnMenu. One way to do that is using the Kendo UI Grid's columnMenuInit event, and removing it using jQuery.

            function onColumnMenuInit(e){
              var item = e.container.find(".k-columns-item");
              item.prev(".k-separator").remove();
              item.remove();
            }
    

Example

    <ul id="columnMenu" style="width: 100px; margin-bottom: 5px"></ul>

    <div id="grid"></div>

    <script>
      $(document).ready(function() {

        $("#columnMenu").kendoMenu({
          closeOnClick: false,
          orientation: "vertical",
          select: onSelect
        });


        $("#grid").kendoGrid({
          dataSource: {
            type: "odata",
            transport: {
              read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
            },
            schema: {
              model: {
                fields: {
                  OrderID: { type: "number" },
                  ShipCountry: { type: "string" },
                  ShipName: { type: "string" },
                  ShipAddress: { type: "string" }                                        
                }
              }
            },
            pageSize: 30,
            serverPaging: true,
            serverFiltering: true,
            serverSorting: true
          },
          columnMenuInit: onColumnMenuInit,
          height: 550,
          sortable: true,
          filterable: true,
          columnMenu: true,
          pageable: true,
          columns: [ {
            field: "OrderID",
            title: "Order ID",
            width: 120
          }, {
            field: "ShipCountry",
            hidden: true,
            title: "Ship Country"
          }, {
            field: "ShipName",
            hidden: true,
            title: "Ship Name"
          },  {
            field: "ShipAddress",
            filterable: false
          }]
        });

        //reference grid
        var grid = $("#grid").data("kendoGrid");

        //reference columns
        var columnValues = grid.columns;

        //Create array
        var checkedValues = [];

        //for each column, add checked if hidden is undefined
        $(columnValues).each(function(index){

          if (this.hidden == true) {
            checkedValues.push(" ");
          } else {
            checkedValues.push("checked");
          }
        });    

        //reference the Kendo UI Menu
        var menu = $("#columnMenu").data("kendoMenu");

        //create initial first item
        menu.append({text: "Columns"});

        //reference it through jQuery
        var firstItem = $("#columnMenu").children("li").eq(0);

        //for each column, append checkboxes with checked values based on hidden field
        $(columnValues).each(function(index){
          menu.append({ text: "<input type='checkbox' " + checkedValues[index] + " />"+ grid.columns[index].field, encoded: false }, firstItem);         
        });

        function onColumnMenuInit(e){
          var item = e.container.find(".k-columns-item");
          item.prev(".k-separator").remove();
          item.remove();
        }

        function onSelect(e){

          //reference checkbox
          var checkbox = $(e.item).find("input");

          //reference the Grid
          var grid = $("#grid").data("kendoGrid");  

          //hold the number of columns
          var numOfColumns = grid.columns.length;  

          //loop through to find how many columns are hidden
          for (var i = 0; i < grid.columns.length; i++) {  
            if (grid.columns[i].hidden == true){
              numOfColumns--;
            }
          }

          //if the field matches the selected item, check if it is hidden or not.
          for (var i = 0; i < grid.columns.length; i++) {
            if(grid.columns[i].field == e.item.innerText){

              //Show the hidden column
              if (grid.columns[i].hidden == true){
                grid.showColumn(grid.columns[i].field);

                //check box
                $(checkbox).prop("checked", true);

                //it will hide as long as there is more than one column in the Grid
              } else if(numOfColumns != 1){
                grid.hideColumn(grid.columns[i].field);

                //uncheck box
                $(checkbox).prop("checked", false);
              } else {

                //check box if it's the last item
                $(checkbox).prop("checked", true);
              }
            }
          }
        }
      });
    </script>

See Also

In this article