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:
-
Reference the Grid Columns.
//reference grid var grid = $("#grid").data("kendoGrid"); //reference columns var columnValues = grid.columns;
-
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"); } });
-
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);
-
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); });
-
When a user selects a column from the menu, the Kendo UI Menu's select event is fired.
- Make a reference to the Grid.
- Determine how many hidden columns are in the Grid to always keep one.
- Based on the column's field, use the showColumn or hideColumn method.
- 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); } } } }
-
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>