Use a detail template (child grid) conditionally

5 posts, 0 answers
  1. Jesse
    Jesse avatar
    54 posts
    Member since:
    Aug 2013

    Posted 13 Apr 2018 Link to this post

    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?

  2. Stefan
    Admin
    Stefan avatar
    2913 posts

    Posted 17 Apr 2018 Link to this post

    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.
  3. Jesse
    Jesse avatar
    54 posts
    Member since:
    Aug 2013

    Posted 17 Apr 2018 in reply to Stefan Link to this post

    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);
  4. Stefan
    Admin
    Stefan avatar
    2913 posts

    Posted 18 Apr 2018 Link to this post

    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.
  5. Jesse
    Jesse avatar
    54 posts
    Member since:
    Aug 2013

    Posted 18 Apr 2018 in reply to Stefan Link to this post

    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!
Back to Top