This is a migrated thread and some comments may be shown as answers.

Collapsing grouped columns

7 Answers 185 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Boardy
Top achievements
Rank 1
Veteran
Boardy asked on 26 Jan 2021, 10:13 AM

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"?

7 Answers, 1 is accepted

Sort by
0
Anton Mironov
Telerik team
answered on 28 Jan 2021, 08:42 AM

Hi Boardy,

Thank you for the code snippet, details, and the working approach provided.

After diving deeply into your implementation, I could say that this is a totally correct and recommended way to achieve the desired behavior.

The standard way to implement the needed behavior is shown in the following knowledge base article:

I fully understand your concern that if all columns from the group are hidden, the header template will be not available. In order to fix this, I would recommend adding a custom empty column in the group with the help of a Column Template. Here is an example of the Template:

columns.Template(@<text> </text>).Title("Column Title");
The approach above will give the opportunity to hide and show the needed columns and leave only the empty template one.

Your way to resolve this case is really good, but if you decide to give the approach above a try, let me know if the behavior is the expected one.

Kind Regards,
Anton Mironov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Boardy
Top achievements
Rank 1
Veteran
answered on 15 Feb 2021, 09:05 AM

Thank you for your answer. When I read your kind words, I didn't realise however my third question was left unanswered.

To elaborate: In my example there is only one column group, but there are in fact a number of column groups. It is a degraded user experience when they click on the eye and instead of collapsing, the group is selected, causing it to scroll into view (so to the left), then having to search for the eye again and click on it again in order to hide it.

I attached a screen recording that demonstrates what happens.

So... Is it possible to make the eye click event fire before the header is selected? Or instead make it impossible for the header to be selected?

 

0
Anton Mironov
Telerik team
answered on 16 Feb 2021, 01:03 PM

Hi Boardy,

Thank you for the details.

Apologize if I misunderstood something. Feel free to correct me - your application needs to hide and show grouped columns with a symbol that represents the current condition. In the following link the expected behavior is working out of the box:

I hope the implementation above is the expected one. If I could assist with further implementation, feel free to use the dojo example below:


Best Regards,
Anton Mironov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Boardy
Top achievements
Rank 1
Veteran
answered on 16 Feb 2021, 02:05 PM

The article also indeed uses the same mechanism I implemented and you suggest in the dojo. I can see that it works.

But as you can see in the screenrecording, when I click on the button, the header cell gets selected, causing it to change position and in turn not firing the event that would cause it to collapse. That is the behavior I want to prevent.

In the dojo, the header cell does not get selected. The only difference, as far as I can see, is that tje dojo uses the js version and I'm using the MVC version of the components.

0
Anton Mironov
Telerik team
answered on 18 Feb 2021, 09:20 AM

Hi Boardy,

The fastest route to getting you up and running is if you could provide a runnable, isolated, sample project. Examining this project will let us replicate the issue locally and further troubleshoot it.

In order to help you create the reproducible, I have gone ahead and created a starter project for you. It already has all the dependencies and a view/controller with a Grid.

Please take the following steps:

1. Download, unblock and extract the attached solution
2. Open it in  VS2019 and update the following files with your problematic code
2.1 Controllers/GridController.cs
2.2 Views/Home/Index.cshtml
3. Run the project and confirm that it reproduces the problem at runtime
4. Close VS2019, then open the project in File Explorer and delete the bin and obj folders
5. Zip up the solution and attach it to your next reply.

Looking forward to hearing back from you..

Greetings,
Anton Mironov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Boardy
Top achievements
Rank 1
Veteran
answered on 22 Feb 2021, 08:00 AM
I cannot reproduce the behavior with this bare project. So I guess somebody (here) put something in some stylesheet to make that happen and it is interfering with what I want to achieve here. Thank you for your patience.
0
Anton Mironov
Telerik team
answered on 23 Feb 2021, 03:01 PM

Hi Boardy,

Take the needed time to find changes in the Layout and CSS files and let me know if I could assist with anything else.

Feel free to contact me and the team if you find the problem and I will try my best to assist with resolving it.

Looking forward to hearing back from you.

Kind Regards,
Anton Mironov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
Grid
Asked by
Boardy
Top achievements
Rank 1
Veteran
Answers by
Anton Mironov
Telerik team
Boardy
Top achievements
Rank 1
Veteran
Share this question
or