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 => grp4376
10.
.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.
else
34.
{
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"?