Search code examples
ajaxasp.net-mvckendo-gridkendo-dropdown

What's missing in this Kendo Grid / DropDownList combination?


Seems to be the usual problem with Kendo grids, but a dropdown being rendered into the toolbar needs to fire an Ajax request to the server and refresh the grid from the returned data. I can see in Fiddler that the Ajax call is successfully being actioned and data is definitely being returned but we're not getting anything refreshed on the grid.

Here's the View code:

<div class="grid-validation-error" id="unitgrid-validation-error">
</div>

  @(Html.Kendo()
  .Grid(Model)
  .Name("WheelchairAlertsGrid")
  .Sortable()
  .Scrollable(scr => scr.Height("100%"))
  .Filterable()
  .ToolBar(t => t.Template(
      @<text>
        <div class="toolbar">
            <label class="category-label" for="category">Show alerts for:</label>
            @(Html.Kendo().DropDownList()
                        .Name("filter-periods")
                        .DataTextField("Text")
                        .DataValueField("Value")
                        .OptionLabel("Month")
                        .Events(e => e.Change("filterPeriodChange"))
                        .BindTo(new List<SelectListItem>(){ 
                            new SelectListItem{ Text = "Day", Value = "Day" }, 
                            new SelectListItem{ Text = "Week", Value = "Week" },
                            new SelectListItem{ Text = "Month", Value = "Month" } })
            )

        </div>
      </text>
      ))
  .Pageable(paging => paging.Messages(msg => msg.Display(ResourceManager.RetrieveResource("PagingFormat"))))
  .Columns(
      col =>
      {
          col.Bound(um => um.SerialNumber).Width(150).Title("Wheelchair").ClientTemplate
             (
                 "<a href='" +
                 Url.DealerGroupAction("Index", "Wheelchair") +
                 "/#= WheelchairDataAssignmentId #'>#= SerialNumber #" + "</a>"
             );
          col.Bound(um => um.Name).Width(150);
          col.Bound(um => um.ChargeAlert).Width(60);
          col.Bound(um => um.BatteryAbuse).Width(60);
          col.Bound(um => um.Flash).Width(60);
          col.Bound(um => um.Transmission).Width(60);
          col.Bound(um => um.DealerGroup).Width(100);
      })
)

And here's the JS code to refresh the data (with assorted variations commented out that have also been tried but failed to yield results):

function filterPeriodChange(e) {

  var ddl = $('#filter-periods').data('kendoDropDownList');
    var grid = $('#WheelchairAlertsGrid').data("kendoGrid");
    $.getJSON('@Url.DealerGroupWheelChairAlertsApiUrl("WheelchairAlerts")', { filterPeriod: ddl.value() }, function (data) {
        grid.dataSource = data;
    });
}

There's always something really simple causing these sorts of problems but I can't see the forest for the trees. Any assistance appreciated.


Solution

  • Cracked it.

    The Kendo Grid data source needs to be told to expect Ajax content. So the code should look like the following:

    ... other stuff as above
    .DataSource(ds => ds
        .Ajax()
        .PageSize(20)
    )
    

    The next piece of the puzzle is to ensure the data source is being set correctly after picking up the data:

    function filterPeriodChange(e) {
    
        var ddl = $('#filter-periods').data('kendoDropDownList');
        var grid = $('#WheelchairAlertsGrid').data("kendoGrid");
    
        $.getJSON('@Url.DealerGroupWheelChairAlertsApiUrl("WheelchairAlerts")', { filterPeriod: ddl.value() }, function (data) {
            var dataSource = new kendo.data.DataSource({
                data: data.Data,
                pageSize: 20
            });
    
            grid.setDataSource(dataSource);
        });
    
    }
    

    That seems to have sorted the issue. Now, changing my dropdown list at the top level calls my filterPeriodChange method, fires off an Ajax request and re-binds the data.