In this case I have a grid with a few locked/fixed columns, followed by a couple of groups of columns under one header. Something like this:
01.@(Html.Kendo().Grid<GradeBusinessLayer.ViewModels.Assets.ElectricalCableDetailViewModel>()02. .Name("grid")03. .Columns(columns =>04. {05. columns.Bound(d => d.Object).Width(200).Locked(true).Lockable(false);06. columns.Bound(d => d.Revision).Width(200).Locked(true).Lockable(false);07. 08.@* ==== BLOCK: Info ====*@09. columns.Group(grp4376 => grp437610. .Title("Info")11. .HeaderTemplate("<div style='display:flex'><span class='k-link' style='text-overflow: ellipsis;white-space: nowrap;overflow: hidden;''>Info</span><span> <i class='fa fa-eye' onclick='hideGroup(this)' aria-hidden='true'></i></span></div>")12. .Columns(col4376 => {13. col4376.Bound(d => d.Alias).Width(200);14. col4376.Bound(d => d.SubClass1Name).Width(200);15. col4376.Bound(d => d.CheckedBy).Width(200);16. col4376.Bound(d => d.CheckedDate).Width(200);17. .18. .19. .The column group should be collapsible. This is intended to be different from hiding the group, because the user should be able to uncollapse it again. I could not find a standard way to do this, so I devised my own, with which I'm partially satisfied.
How I did it: The group now has a caption, followed by an eye (from font-awesome, but this could of course by any glyph). When the eye is clicked, a javascript function replaces the eye with a slashed eye and hides all the columns, except for the first. This is that function:
01.function hideGroup(vis)02.{03. vis = $(vis);04. var grd = $("#grid").data("kendoGrid");05. 06. var cell = vis.closest("th");07. var row = cell.closest("tr");08. var grpIdx = $("th", row).index(cell);09. 10. var grpCol = undefined;11. for (i=0; i<grd.columns.length; i++)12. {13. if (typeof grd.columns[i].columns !== "undefined")14. {15. if (grpIdx-- === 0)16. {17. grpCol = grd.columns[i];18. break;19. }20. }21. }22. 23. if (typeof grpCol === "undefined")24. return;25. 26. if (vis.hasClass("fa-eye"))27. {28. vis.removeClass("fa-eye");29. vis.addClass("fa-eye-slash");30. for (i=grpCol.columns.length-1; i>0; i--)31. grd.hideColumn(grpCol.columns[i]);32. }33. else34. {35. vis.removeClass("fa-eye-slash");36. vis.addClass("fa-eye");37. for (i=grpCol.columns.length-1; i>0; i--)38. grd.showColumn(grpCol.columns[i]);39. }40.}
So first the header cell is discovered. Then the index of that header cell in the row. Then the columns are enumerated until the column with that index is found, not counting the columns that don't have subcolumns (those are the fixed columns and they are in a different <tr>, it turns out, so I cannot use the grpIdx straight away). When the column object has been identified, it can be used to iterate its columns to show/hide them as intended.
My questions:
- Is there a standard or more proper way to do this? (If so I guess I want to use that instead, and the next questions are rendered irrelevant.)
- Is there a better way to locate the group column? The way I do it now is very cumbersome, indirect and depending on the way the grid is rendered now.
- When the eye is clicked, the header cell is first selected, before the onclick is fired. However, when the header is wide and partiallly invisable, it is scrolled into view. This moves the eye and apparently the onclick event is not fired. Is it possible to make the click happen before the select? Or instead make the group header not selectable, while maintaining the "eye functionality"?
