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

Use a detail template (child grid) conditionally

4 Answers 2451 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Jesse
Top achievements
Rank 1
Veteran
Jesse asked on 13 Apr 2018, 08:16 PM

I'm implementing a hierarchical grid. it's all working well except if the parent row's ViewModel doesn't have any child items, it still renders a grid with no rows for the detail template. This is the behavior I would expect, but not the behavior I want. If there are no child items, I want to not render a detail template and also not display the expand icon for that row. Here is a case where the same thing was requested for Kendo for Angular.  And below is an excerpt of my view:

01.@(Html.Kendo().Grid<PmtHistAccountPaymentVM>(Model.PaymentHistory)
02.        .Name(gridName)
03.        .Columns(columns =>
04.        {
05.            columns.Bound(c => c.PaymentDate).Title("Date").Format("{0:d}");
06.            columns.Bound(c => c.PaymentAmount).Format("{0:C}").Title("Amount");
07.        })
08.        .ClientDetailTemplateId(gridID + "-accountTransGridTemplate")
09.        .NoRecords("No Payments")
10.        .DataSource(dataSource => dataSource
11.            .Ajax()
12.            .Model(model => { model.Id(p => p.ID); })
13.            .PageSize(15)
14.            .ServerOperation(true)
15.            .Read(read => read.Action("PaymentHistory_Read", "CustomerAccounts").Data("function(){ ... }"))
16.        )
17.        .Events(e => e.DetailInit("crm.accounts_pmthist.grid_initDetailGrid"))
18.        .Deferred()
19.)
20.<script type="text/x-kendo-temp" id="@gridID-accountTransGridTemplate">
21.    #if(TransactionPayments && TransactionPayments.length > 0){#
22.    @(Html.Kendo().Grid<PmtHistTransactionPaymentVM>()
23.        .Name(gridName+"#=ID#")
24.        .Columns(cols =>
25.        {
26.            cols.Bound(p => p.AccountTransactionProductName).Title("Description");
27.            cols.Bound(p => p.CostPaid).Format("{0:c}");
28.            cols.Bound(p => p.TaxPaid).Format("{0:c}");
29.            cols.Bound(p => p.PaymentAmount).Format("{0:c}");
30.        })
31.        //.Sortable()
32.        //.Filterable()
33.        .AutoBind(false)
34.        .DataSource(ds => ds.Ajax().ServerOperation(false))
35.        .ToClientTemplate()
36.    )
37.    #}#
38.</script>

 

As you can see, on line 21, I attempted to add a conditional statement. This seems to have eliminated the detail template successfully but the expand icon still shows on the parent row and creates an error in the DetailInit event handler. I decided I'd better ask if I'm on the right track or if something better is available to accomplish this?

4 Answers, 1 is accepted

Sort by
0
Stefan
Telerik team
answered on 17 Apr 2018, 07:08 AM
Hello, Jesse,

Thank you for the details.

This indeed the correct way to conditionally render a detail template.

As for the arrow, please check the following forum post and the suggestion from Marcin Butlak:

https://www.telerik.com/forums/hide-detail-indicator-detail-grid

And as for the error, please advise the error message as this will help us determine what may be causing it, as I tried the same approach on my end and it was working as expected.

I can only assume that if "TransactionPayments" is null or undefined, trying to get its length will cause an error.

Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Jesse
Top achievements
Rank 1
Veteran
answered on 17 Apr 2018, 11:20 PM

Thank you, Stefan. I understand that solution is saying to remove the class(es) that displays the expand icon, but arriving at that point isn't exactly working for me. The error was from the first line below  "Cannot read property 'kendoGrid' of undefined" so I just need to make sure that the detailCell actually contains a .k-grid before trying to get the kendoGrid. When I do that, I get rid of the error but the detail grid's dataBound event never fires, because there's no data for it to bind to. So the linked solution doesn't work. I was able to hide the expander icon in grid_initDetailGrid, but that only hides it once it's clicked. I'd rather it just never exist in the first place.

this.grid_initDetailGrid = function (e) {
            var detailGrid = e.detailCell.find('>.k-grid').data().kendoGrid;
            var dataItem = e.data;
                detailGrid.dataSource.data(dataItem.TransactionPayments);
0
Stefan
Telerik team
answered on 18 Apr 2018, 07:48 AM
Hello, Jesse,

I applied the solution provided by Marcin Butlak and it is working as expected on my end.

The main point is to have a field inside the master row that indicates if the row has child records or no in order to determine if the arrow will be hidden or not:

<script>
    function dataBound() {
            var dataSource = this.dataSource;
            this.element.find('tr.k-master-row').each(function () {
                var row = $(this);
                var data = dataSource.getByUid(row.data('uid'));
                // this example will work if ReportId is null or 0 (if the row has no details)
                if (data.hasChildItems=== false) {
                    row.find('.k-hierarchy-cell a').css({ opacity: 0.0, cursor: 'default' }).click(function (e) { e.stopImmediatePropagation(); return false; });
                }
            });
    }
</script>

This is required as otherwise there is no option to hide the arrow initially before actually making the request and checking that it is empty.

Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Jesse
Top achievements
Rank 1
Veteran
answered on 18 Apr 2018, 05:17 PM
I'm sorry, I originally read the wrong reply in that thread. Thanks for pointing it out again. I was hoping not to have to iterate over the rows again after they were created, but it doesn't look like there's anything like a rowBound event to do that. Handling it in the DataBound event as you showed does appear to work for my immediate purpose. Thanks for your help!
Tags
Grid
Asked by
Jesse
Top achievements
Rank 1
Veteran
Answers by
Stefan
Telerik team
Jesse
Top achievements
Rank 1
Veteran
Share this question
or