Can't get grid.dataSource.filter to work

3 posts, 0 answers
  1. Chad
    Chad avatar
    29 posts
    Member since:
    Nov 2012

    Posted 07 Dec 2012 Link to this post

    Hello,

    I am trying to get ajax filtering to work without luck. However, there may be an overriding issue as I see in the script debugger that I am getting an error in kendo.web.min.js just upon loading my page.
    Uncaught TypeError: Cannot call method replace of undefined
    This is being displayed directly below line 9 in this .js file.

    My Controller:
    //Kendow MVC Server binding test
            public ActionResult KendoGrid([DataSourceRequest] DataSourceRequest request, string areaFilter = null)
            {
                ListLocationsViewModel viewModel = _manageLocationsAppServ.CreateListLocationsViewModel(0, areaFilter);
                return Json(viewModel.Locations.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
            }


    Here is my .cshtml
    @using Kendo.Mvc.UI
    @using OTIS.domain.CompanyMgmt
    @model OTIS.AppServ.CompanyMgmt.ViewModels.ListLocationsViewModel
     
    @{
        ViewBag.Title = "Locations | OTIS";
    }
     
    <h2>Locations</h2>
    @Html.Raw(TempData["message"])
    <p>
        @using (Html.BeginForm())
        {   
            <p>
                Area: @Html.DropDownList("areaFilter", new SelectList(Model.AreaOptions), "")
                <input type="submit" value="Search"/>
                <button onclick="filter()">Filter</button>
            </p>
        }
    </p>
    <hr />
    <p>
        @Html.ActionLink("Create New", "Edit", "ManageLocations", null, new { @class="button" })
    </p>
    @(Html.Kendo().Grid<OTIS.AppServ.CompanyMgmt.ViewModels.ListLocationsViewModel.LocationsGrid>()
        .Name("MVCClientBindGrid")
        .Columns(columns =>
        {
            columns.Bound(l => l.DisplayLocation);
            columns.Bound(l => l.Area);
            columns.Bound(l => l.Zone);
            columns.Bound(l => l.Aisle);
            columns.Bound(l => l.Bay);
            columns.Bound(l => l.Level);
            columns.Bound(l => l.Position);
            columns.Bound(l => l.Barcode);
            columns.Command(command => command.Custom("Details").Click("showDetails")).Width(100);
        })
        // Add "Create" command
        .ToolBar(toolbar =>
            {
                //Want to place this at the bottom
                toolbar.Custom().Text("Add").Url("#_").HtmlAttributes(new { onclick = "addNew()", @class = "k-grid-add" });
            })
        .DataSource(dataSource => dataSource
            .Ajax() // Specify that the data source is of ajax type
            .ServerOperation(false) // paging, sorting, filtering and grouping will be applied client-side
            .PageSize(10)
            .Model(model => model.Id(c => c.Id))
            .Read(read => read.Action("KendoGrid", "ManageLocations",  new { area = "CompanyMgmt" })// Specify the action method and controller name
                    //.Data("getFilters") // the name of the JavaScript function which will return the additional data
             
            )
        )
        .Pageable()
        .Sortable()
        .Scrollable()
        .Filterable()
        .Groupable()
    )
     
    <script type="text/javascript">
        var detailsTemplate = kendo.template($("#template").html());
     
        function showDetails(e) {
            e.preventDefault();
            var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
            window.location.href = "@Url.Action( "Edit", "ManageLocations")" + "/" + dataItem.id;
        }
     
        function addNew() {
            window.location.href = "@Url.Action( "Edit", "ManageLocations")";
        }
     
        function filter() {
            var grid = $("#MVCClientBindGrid").data("kendoGrid");
     
            var area = $('#areaFilter').val()
            grid.dataSource.filter({
                logic: "and",
                filters: [
                    { field: 'Area', operator: 'eq', value: 'SHIP' },
                    { field: 'Area', operator: 'eq', value: 'SHIP' }
                ]
            });
             
        }
        
     
    </script>
    Here is the full HTML as rendered...so you can see what .js files are included and in what order
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8" />
            <title>Locations | OTIS - My ASP.NET MVC Application</title>
            <link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
            <meta name="viewport" content="width=device-width" />
             
            <link href="/Content/site.css" rel="stylesheet"/>
    <link href="/Content/superfish.css" rel="stylesheet"/>
     
            <link href="/Content/kendo/kendo.common.min.css" rel="stylesheet"/>
      
            <link href="/Content/themes/green_machine/jquery-ui-1.9.2.custom.css" rel="stylesheet"/>
    <link href="/Content/themes/green_machine/green_machine.css" rel="stylesheet"/>
     
              
            <script src="/Scripts/modernizr-2.5.3.js"></script>
              
            <script src="/Scripts/jquery-1.8.3.js"></script>
     
            <script src="/Scripts/jquery-ui-1.8.20.js"></script>
     
            <script src="/Scripts/kendo/kendo.web.min.js"></script>
    <script src="/Scripts/kendo/kendo.aspnetmvc.min.js"></script>
      
            <script>
                //JQuery custom theme application
                $(function () {
                    $("input[type=submit], a.button, button").button()
     
                    $('ul.sf-menu').superfish({
                        animation: { opacity: 'show', height: 'show' },  // fade-in and slide-down animation
                        speed: 'fast',                          // faster animation speed
                        autoArrows: true,                           // disable generation of arrow mark-up
                        dropShadows: true                            // disable drop shadows
                    });
                });
            </script>
               
        </head>
        <body>
             
            <header>
                <div class="content-wrapper">
                    <div class="float-left">
                        <p class="site-title"><a href="/CompanyMgmt/Home">OTIS</a></p>
                    </div>
                    <div class="float-right">
                        <section id="login">
                                 
            Hello, <a class="username" href="/Account/UserProfile" title="Manage">chadr</a>!
    <form action="/Account/LogOff" id="logoutForm" method="post"><input name="__RequestVerificationToken" type="hidden" value="EHsDe8SgQElcRgrIcNq4uuC_Y8XexV-LUKiigBQGqQpjTHVVDvapFTB0W6sylMdJUAelKHrka6apyRxGy39CDJ4JUf_ae4rwGNxFR3aaXp81" />            <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a>
    </form>   
     
                        </section>
                    </div>
                    <div class="float-right">
                        <nav>
                            <ul class="sf-menu sf-hover" id="menu">
                                <li><a href="/">Home</a></li>
                                <li><a href="#">Admin</a>
                                    <ul>
                                        <li><a href="/CompanyMgmt/ManageCompanies">Companies</a></li>
                                        <li><a href="/CompanyMgmt/ManageLocations">Locations</a></li>
                                        <li><a href="/CompanyMgmt/ManageCompanies/Kendo">Kendo Test</a></li>
                                    </ul>
                                </li>
                                <li><a href="/Home/About">About</a></li>
                                <li><a href="/Home/Contact">Contact</a></li>
                            </ul>
                        </nav>
                    </div>
                </div>
                <div class="clear-fix"></div>
            </header>
            <div id="body">
                 
                <section class="content-wrapper main-content clear-fix">
                     
     
    <h2>Locations</h2>
     
    <p>
    <form action="/CompanyMgmt/ManageLocations" method="post">        <p>
                Area: <select id="areaFilter" name="areaFilter"><option value=""></option>
    <option>RECV</option>
    <option>SHIP</option>
    </select>
                <input type="submit" value="Search"/>
                <button onclick="filter()">Filter</button>
            </p>
    </form></p>
    <hr />
    <p>
        <a class="button" href="/CompanyMgmt/ManageLocations/Edit">Create New</a>
    </p>
    <div class="k-widget k-grid" id="MVCClientBindGrid"><div class="k-toolbar k-grid-toolbar k-grid-top"><a class="k-grid-add k-button k-button-icontext " href="#_" onclick="addNew()"><span></span>Add</a></div><div class="k-grouping-header">Drag a column header and drop it here to group by that column</div><div class="k-grid-header"><div class="k-grid-header-wrap"><table cellspacing="0"><colgroup><col /><col /><col /><col /><col /><col /><col /><col /><col style="width:100px" /></colgroup><tr><th class="k-header k-filterable" data-field="DisplayLocation" data-title="Display Location" scope="col"><a class="k-grid-filter"><span class="k-icon k-filter"></span></a><a class="k-link" href="/CompanyMgmt/ManageLocations/KendoGrid?MVCClientBindGrid-sort=DisplayLocation-asc">Display Location</a></th><th class="k-header k-filterable" data-field="Area" data-title="Area" scope="col"><a class="k-grid-filter"><span class="k-icon k-filter"></span></a><a class="k-link" href="/CompanyMgmt/ManageLocations/KendoGrid?MVCClientBindGrid-sort=Area-asc">Area</a></th><th class="k-header k-filterable" data-field="Zone" data-title="Zone" scope="col"><a class="k-grid-filter"><span class="k-icon k-filter"></span></a><a class="k-link" href="/CompanyMgmt/ManageLocations/KendoGrid?MVCClientBindGrid-sort=Zone-asc">Zone</a></th><th class="k-header k-filterable" data-field="Aisle" data-title="Aisle" scope="col"><a class="k-grid-filter"><span class="k-icon k-filter"></span></a><a class="k-link" href="/CompanyMgmt/ManageLocations/KendoGrid?MVCClientBindGrid-sort=Aisle-asc">Aisle</a></th><th class="k-header k-filterable" data-field="Bay" data-title="Bay" scope="col"><a class="k-grid-filter"><span class="k-icon k-filter"></span></a><a class="k-link" href="/CompanyMgmt/ManageLocations/KendoGrid?MVCClientBindGrid-sort=Bay-asc">Bay</a></th><th class="k-header k-filterable" data-field="Level" data-title="Level" scope="col"><a class="k-grid-filter"><span class="k-icon k-filter"></span></a><a class="k-link" href="/CompanyMgmt/ManageLocations/KendoGrid?MVCClientBindGrid-sort=Level-asc">Level</a></th><th class="k-header k-filterable" data-field="Position" data-title="Position" scope="col"><a class="k-grid-filter"><span class="k-icon k-filter"></span></a><a class="k-link" href="/CompanyMgmt/ManageLocations/KendoGrid?MVCClientBindGrid-sort=Position-asc">Position</a></th><th class="k-header k-filterable" data-field="Barcode" data-title="Barcode" scope="col"><a class="k-grid-filter"><span class="k-icon k-filter"></span></a><a class="k-link" href="/CompanyMgmt/ManageLocations/KendoGrid?MVCClientBindGrid-sort=Barcode-asc">Barcode</a></th><th class="k-header" scope="col"><span class="k-link"> </span></th></tr></table></div></div><div class="k-grid-content" style="height:200px"><table cellspacing="0"><colgroup><col /><col /><col /><col /><col /><col /><col /><col /><col style="width:100px" /></colgroup><tbody><tr class="t-no-data"><td colspan="9"></td></tr></tbody></table></div><div class="k-pager-wrap k-grid-pager"><a class="k-link k-state-disabled" data-page="1" href="#" title="Go to the first page"><span class="k-icon k-i-seek-w">seek-w</span></a><a class="k-link k-state-disabled" data-page="0" href="#" title="Go to the previous page"><span class="k-icon k-i-arrow-w">arrow-w</span></a><ul class="k-pager-numbers k-reset"><li><span class="k-state-selected" data-page="1">1</span></li></ul><a class="k-link k-state-disabled" data-page="2" href="#" title="Go to the next page"><span class="k-icon k-i-arrow-e">arrow-e</span></a><a class="k-link k-state-disabled" data-page="1" href="#" title="Go to the last page"><span class="k-icon k-i-seek-e">seek-e</span></a><span class="k-pager-info k-label">0 - 0 of 0 items</span></div></div><script>
        jQuery(function(){jQuery("#MVCClientBindGrid").kendoGrid({"columns":[{"title":"Display Location","field":"DisplayLocation","encoded":true},{"title":"Area","field":"Area","encoded":true},{"title":"Zone","field":"Zone","encoded":true},{"title":"Aisle","field":"Aisle","encoded":true},{"title":"Bay","field":"Bay","encoded":true},{"title":"Level","field":"Level","encoded":true},{"title":"Position","field":"Position","encoded":true},{"title":"Barcode","field":"Barcode","encoded":true},{"width":"100px","command":[{"name":"Details","buttonType":"ImageAndText","text":"Details","click":showDetails}]}],"groupable":{},"pageable":{"buttonCount":10},"sortable":true,"filterable":true,"toolbar":{"command":[{"name":null,"attr":" onclick=\"addNew()\" class=\"k-grid-add\"","buttonType":"ImageAndText","text":"Add"}]},"dataSource":{"transport":{"read":{"url":"/CompanyMgmt/ManageLocations/KendoGrid"}},"pageSize":10,"page":1,"total":0,"type":"aspnetmvc-ajax","schema":{"data":"Data","total":"Total","errors":"Errors","model":{"id":"Id","fields":{"Id":{"type":"number"},"DisplayLocation":{"type":"string"},"Area":{"type":"string"},"Zone":{"type":"string"},"Aisle":{"type":"string"},"Bay":{"type":"string"},"Level":{"type":"string"},"Position":{"type":"string"},"Barcode":{"type":"string"}}}}}});});
    </script>
     
    <script type="text/javascript">
        var detailsTemplate = kendo.template($("#template").html());
     
        function showDetails(e) {
            e.preventDefault();
            var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
            window.location.href = "/CompanyMgmt/ManageLocations/Edit" + "/" + dataItem.id;
        }
     
        function addNew() {
            window.location.href = "/CompanyMgmt/ManageLocations/Edit";
        }
     
        function filter() {
            var grid = $("#MVCClientBindGrid").data("kendoGrid");
     
            //grid.dataSource.filter({
            //    logic: "and",
            //    filters: [
            //        { field: 'ID', operator: 'gte', value: 10 },
            //        { field: 'ID', operator: 'lte', value: 20 }
            //    ]
            //});
            var area = $('#areaFilter').val()
            grid.dataSource.filter({
                logic: "and",
                filters: [
                    { field: 'Area', operator: 'eq', value: 'SHIP' },
                    { field: 'Area', operator: 'eq', value: 'SHIP' }
                ]
            });
             
        }
        function getFilters() {
     
            var filters = []; // create an empty array
     
            filters.push({
                key: "areaFilter",
                value: $('#areaFilter').val()
            });
            return filters;
     
            //return {
            //    areaFilter: "SHIP"
            //};
        }
     
    </script>
     
                </section>
            </div>
            <footer>
                <div class="content-wrapper">
                    <div class="float-left">
                        <p>© 2012 - OTIS - Order Tracking and Inventory System</p>
                    </div>
                </div>
            </footer>
             
             
            <script src="/Scripts/superfish.js"></script>
    <script src="/Scripts/supersubs.js"></script>
     
             
            <script>
                $(document).ready(function () {
                     
     
                    //to utilize jquery theme in superfish menu
                    //$("ul.sf-menu li").addClass("ui-state-default");
     
                    //$("ul.sf-menu li").hover(function () { $(this).addClass('ui-state-hover'); },
                    //                         function () { $(this).removeClass('ui-state-hover'); });
     
                });
            </script>
             
        </body>
    </html>
    Any insight is much appreciated!
    Thanks,
    Chad
  2. Chad
    Chad avatar
    29 posts
    Member since:
    Nov 2012

    Posted 07 Dec 2012 Link to this post

    Ok, I'm an idiot. My goals was to implement server side filtering using an MVC controller and ajax binding.
    the grid.dataSource.filter is for filtering on the CLIENT Side only.

    To do a Server Side filter by taking inputs on your page and use them to refresh your grid, via an ajax post to your controller you need to do the following:

    1. Set the .Data parameter in the grid setup to call a js function that gets your form fields to filter by.
    .Read(read => read.Action("KendoGrid", "ManageLocations",  new { area = "CompanyMgmt" })// Specify the action method and controller name
                    .Data("GetCriteria") // the name of the JavaScript function which will return the additional data
    2. Create your filter criteria fields on the page so that your users can select their criteria. Then include a Filter button to initiate the server side filtering.
    Area: @Html.DropDownList("areaFilter", new SelectList(Model.AreaOptions), "")
    <button onclick="filter()">Filter</button>
    3. create your GetCriteria() js functin to go collect the user input on the form
    function GetCriteria() {
            var obj = {
                areaFilter: $("#areaFilter").val()
            };
            return obj;
        };
    4. create a filter() js function that is called from the "Filter" button in order to connect all the dots
    function filter() {
            var grid = $("#MVCClientBindGrid").data("kendoGrid");
            grid.dataSource.read();
        }
    This call to grid.dataSource.read() will invoke the grid to read using the .read method as you defined it in step 1, which just prior to the read, executes the function specified in .Data, i.e. GetFilters(), to pass those filters to your controller as parameters.

    5. Here is the controller
    //Kendow MVC Server binding test
            public ActionResult KendoGrid([DataSourceRequest] DataSourceRequest request, string areaFilter = null)
            {
                ListLocationsViewModel viewModel = _manageLocationsAppServ.CreateListLocationsViewModel(0, areaFilter);
                return Json(viewModel.Locations.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
            }
    Hope this helps someone else.

    I think one of the most confusing aspects of Kendo is that you can implement it using multiple means (MVC Server, MVC ajax, straight ajax) and so when you are searching for answers, it is not very apparent as to which solution works in which type of implementation. Hopefully this will be easier to grasp as time continues, but it would be great if all the documentation clearly stated the scope under which it applied.

    Chad
  3. Aaron
    Aaron avatar
    10 posts
    Member since:
    Mar 2013

    Posted 03 May 2013 Link to this post

    Hey man, your solution was really useful and really easy to understand it saved me from days of looking over the interweb so thank you!

    just thought of sharing my scenario:

    Scenario: Multiple filters applied to Kendo grid both done on client & server side grid filters.

    a. Client side filters - using html textbox and kendo dropdownlist

    javascript
    $('#btnSearch').on("click", function (e) {
           refreshGrid();
           return false;
       });
     
       function refreshGrid() {
           $filter = new Array();
     
           $filter.push({ field: "StudentID", operator: "contains", value: $('#txtStudentID').val() });
           
           $filter.push({ field: "YearSubmitted", operator: "eq", value: $('#AcademicYear').val() });
            
           var grid = $("#Grid").data("kendoGrid");
           grid.dataSource.filter($filter);
           grid.dataSource.read();
       }

    b. Server side - used for complex search involving multiple db query while using kendo dropdownlists

    javascript 
    function GetFilter() {
     
            var awardVal;
            var awardTypeVal;
            var donorVal;
     
            //award type
            if ($('#AwardType').val() == "All") {
                awardTypeVal = 0;
            } else {
                awardTypeVal = parseInt($('#AwardType').val())
            }
     
            //award
            if ($('#Award').val() == "All") {
                awardVal = 0;
            } else {
                awardVal =parseInt($('#Award').val())
            }
             
            //donor
            if ($('#Donors').val() == "All") {
                donorVal = 0;
            }else {
                donorVal =parseInt($('#Donors').val())
            }
     
            var obj = {
                awardTypeFilter: awardTypeVal,
                awardFilter: awardVal,
                donorFilter: donorVal
            };
     
     
            return obj;
        };
    Grid datasource setup (same as Chad')
    .DataSource(dataSource => dataSource
                .Ajax()
                 .Model(model => model.Id(p => p.ApplicationID))
                .ServerOperation(false) // paging, sorting, filtering and grouping will be applied client-side
                .Read(read => read.Action("ApplicationSearch_Read", "Admin")
                    .Data("GetFilter"))
            )
    Controller - Note* use nullable parameters or it won't go here unless all fields are entered.
    public ActionResult ApplicationSearch_Read([DataSourceRequest]DataSourceRequest request, int? awardFilter, int? awardTypeFilter, int? donorFilter)
            {         
               List<Application> applicationList = new List<Application>();
                var applications = context.Applications.Include("ApplicationDetails").OrderByDescending(p => p.SubmittedDate).ToList();
     
                applicationList = applications;
     
                //  Apply filters
                if ((awardTypeFilter > 0 && awardTypeFilter != null) || (awardFilter > 0 && awardFilter != null) || (donorFilter > 0 && donorFilter != null))
                {
                    applicationList = new List<Application>();
                    var applicationDetails = from a in context.ApplicationDetails
                                             select a;
                    if ((awardTypeFilter > 0 && awardTypeFilter != null))
                    {
                        applicationDetails = applicationDetails.Where(p => p.AwardDetail.Award.AwardTypeID == awardTypeFilter);
                    }
                    if (awardFilter > 0 && awardFilter != null)
                    {
                        applicationDetails = applicationDetails.Where(p => p.AwardDetail.AwardID == awardFilter);
                    }
     
                    if (donorFilter > 0 && donorFilter != null)
                    {
                        applicationDetails = applicationDetails.Where(p => p.AwardDetail.Award.DonorID == donorFilter);
                    }
     
                    var appDets = applicationDetails.ToList();
                    foreach (ApplicationDetail appDet in appDets)
                    {
                        var app = context.Applications.Include("ApplicationDetails").Where(p => p.ApplicationID == appDet.ApplicationID ).First();
                        applicationList.Add(app);
                    }
                }
     
                
     
                var data = applicationList.Select(x => new _VMApplication
                {
                    ApplicationID = x.ApplicationID,
                    SubmittedDate = x.SubmittedDate,
                    FirstName = x.FirstName,
                    LastName = x.LastName,
                    StudentID = x.StudentID,
                    IsApplicationSubmitted = x.IsApplicationSubmitted,
                    YearSubmitted = x.SubmittedDate.Year.ToString(),
                    appDetails = x.ApplicationDetails.Select(y => new _VMApplicationDetail
                    {
                        AwardID = y.AwardDetail.AwardID,
                        AwardName = y.AwardDetail.Award.AwardName,
                        AwardTypeID = y.AwardDetail.Award.AwardTypeID
                        
                    })
                });
                return Json(data.ToDataSourceResult(request));
            
            }

    Hope this helps.

    Cheers,
    Aaron
Back to Top