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

Can't get grid.dataSource.filter to work

2 Answers 987 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Chad
Top achievements
Rank 1
Chad asked on 07 Dec 2012, 07:29 PM
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 Answers, 1 is accepted

Sort by
0
Chad
Top achievements
Rank 1
answered on 07 Dec 2012, 11:29 PM
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
0
Aaron
Top achievements
Rank 1
answered on 03 May 2013, 09:06 PM
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
Tags
Grid
Asked by
Chad
Top achievements
Rank 1
Answers by
Chad
Top achievements
Rank 1
Aaron
Top achievements
Rank 1
Share this question
or