19
votes

I have a telerik asp.net mvc grid which needs to be populated based on the search criteria the user enters in separate text boxes. The grid is using ajax method to load itself initially as well as do paging.

How can one pass the search parameters to the grid so that it sends those parameters "every time" it calls the ajax method in response to the user clicking on another page to go to the data on that page?

I read the telerik's user guide but it does not mention this scenario. The only way I have been able to do above is by passing the parameters to the rebind() method on client side using jquery. The issue is that I am not sure if it is the "official" way of passing parameters which will always work even after updates. I found this method on this post on telerik's site: link text

I have to pass in multiple parameters. The action method in the controller when called by the telerik grid runs the query again based on the search parameters.

Here is a snippet of my code:

$("#searchButton").click(function() {
    var grid = $("#Invoices").data('tGrid');

    var startSearchDate = $("#StartDatePicker-input").val();
    var endSearchDate = $("#EndDatePicker-input").val();

    grid.rebind({ startSearchDate: startSearchDate ,
                    endSearchDate: endSearchDate
                });
});
6

6 Answers

10
votes

So according to Telerik "recommended approach is to set the arguments in the onDataBinding event".

function onGridBinding(e) {
if (cancelGridBinding) {  
    // ...
}
else {
    var searchValue = 'something';
    e.data = { search: searchValue };
}

}

7
votes

For myself I use ViewModel object that I pass using jQuery and javascript object, my View is stongly typed SearchMemberModel, witch contains my search fields and I have a Textbox for every fields in my view. My databinding is on passing the Model to the controller. Then I build my object in javascript and pass it to my controller in the rebind call.

Here's my code :

View and javascrip

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Admin.Master" Inherits="System.Web.Mvc.ViewPage<Enquete.Models.SearchMemberModel>" %>

<% using (Html.BeginForm()) {%>
    <%: Html.ValidationSummary(true) %>

    <fieldset>
        <legend><%: Resources.Search %></legend>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.MemberNumber) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.MemberNumber) %>
            <%: Html.ValidationMessageFor(model => model.MemberNumber) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Email) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Email) %>
            <%: Html.ValidationMessageFor(model => model.Email) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.FirstName) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.FirstName) %>
            <%: Html.ValidationMessageFor(model => model.FirstName) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.LastName) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.LastName) %>
            <%: Html.ValidationMessageFor(model => model.LastName) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Phone) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Phone) %>
            <%: Html.ValidationMessageFor(model => model.Phone) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Active) %>
        </div>
        <div class="editor-field">
            <%: Html.CheckBoxFor(model => model.Active) %>
            <%: Html.ValidationMessageFor(model => model.Active) %>
        </div>

        <p>
            <input type="submit" value="<%: Resources.ToSearch %>" id="btnSearch" />
        </p>
    </fieldset>

<% } %>

 <%= Html.Telerik().Grid<SerializableMember>()
                .Name("Grid")
                .Columns(colums =>
                 {
                     colums.Bound(c => c.Email).Title(Resources.Email);//.ClientTemplate("<a href=\"" + Url.Action(MVC.Admin.Edit()) + "/<#=Id#>\" ><#=Email#></a>");
                     colums.Bound(c => c.FirstName).Title(Resources.FirstName);
                     colums.Bound(c => c.LastName).Title(Resources.LastName);
                     colums.Bound(c => c.MemberNumber).Title(Resources.MemberNumber);
                     colums.Bound(c => c.Active).Title(Resources.Active).HeaderHtmlAttributes(new { @class = "center-text" }).HtmlAttributes(new { @class = "center-text" }).ClientTemplate("<img src=\"Content/images/icons/<#=Active#>.png\" alt=\"<#=Active#>\" />");
                     colums.Bound(c => c.Id).Title(" ").HtmlAttributes(new { @class = "center-text" }).ClientTemplate("<a href=\"" + Url.Action(MVC.Member.ResetPassword()) + "/<#=Id#>\" title=\"" + Resources.ResetPassword + "\" >" + Resources.ResetPassword + "</a>");
                     colums.Bound(c => c.Id).Title(" ").HtmlAttributes(new { @class = "center-text" }).ClientTemplate("<a href=\"" + Url.Action(MVC.Member.Activate()) + "/<#=Id#>\" title=\"" + Resources.Activate + "\" >" + Resources.Activate + "</a>");
                     colums.Bound(c => c.Id).Title(" ").HtmlAttributes(new { @class = "center-text" }).ClientTemplate("<a href=\"" + Url.Action(MVC.Member.Deactivate()) + "/<#=Id#>\" title=\"" + Resources.Deactivate + "\" >" + Resources.Deactivate + "</a>");
                 })
                //.DataBinding(d => d.Ajax().Select("ListAjax", "Member", Model))
                .DataBinding(d => d.Ajax().Select(MVC.Member.ListAjax(Model).GetRouteValueDictionary()))
                .Sortable()
                .NoRecordsTemplate(Resources.NoData)
        %>
        <%= Html.AntiForgeryToken() %>

        <script type="text/javascript">
            $(document).ready(function () {
                $('#btnSearch').click(function () {
                    var grid = $('#Grid').data('tGrid');
                    var searchModel = {
                        MemberNumber: $('#MemberNumber').val(),
                        Email: $('#Email').val(),
                        FirstName: $('#FirstName').val(),
                        LastName: $('#LastName').val(),
                        Phone: $('#Phone').val(),
                        Active: $('#Active').is(':checked')
                    };
                    grid.rebind(searchModel);
                    return false;
                });
            });
        </script>

        <%= Html.Telerik().ScriptRegistrar().jQuery(false).DefaultGroup(g => g.DefaultPath("~/Content/Javascript/2010.3.1110"))%>

And that's my controller

[GridAction]
    public virtual ActionResult ListAjax(SearchMemberModel search)
    {
        var gridModel = new GridModel<SerializableMember>();
        var data = _session.All<Member>();
        if (search != null)
        {
            if (search.Active) data = data.Where(x => x.Active);
            if (!string.IsNullOrEmpty(search.Email)) data = data.Where(x => x.Email.Contains(search.Email));
            if (!string.IsNullOrEmpty(search.FirstName)) data = data.Where(x => x.FirstName.Contains(search.FirstName));
            if (!string.IsNullOrEmpty(search.LastName)) data = data.Where(x => x.LastName.Contains(search.LastName));
            if (!string.IsNullOrEmpty(search.MemberNumber)) data = data.Where(x => x.MemberNumber.Contains(search.MemberNumber));
            if (!string.IsNullOrEmpty(search.Phone)) data = data.Where(x => x.Phone.Contains(search.Phone));
        }

        var list = new List<SerializableMember>(data.Count());
        list.AddRange(data.ToList().Select(obj => new SerializableMember(obj)));
        gridModel.Data = list;
        return View(gridModel);
    }

I can give you my search model class too :

public class SearchMemberModel
{
    [LocalizedDisplayName("MemberNumber")]
    public string MemberNumber { get; set; }

    [LocalizedDisplayName("Email")]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [LocalizedDisplayName("FirstName")]
    public string FirstName { get; set; }

    [LocalizedDisplayName("LastName")]
    public string LastName { get; set; }

    [LocalizedDisplayName("Phone")]
    public string Phone { get; set; }

    [LocalizedDisplayName("ActiveOnly")]
    public bool Active { get; set; }
}

Hope it can helps anyone out there!

2
votes

This is actually documented here.

2
votes
<script type="text/javascript">
    $(document).ready(function () {
        $('#apply').click(function () {
            var params = { 
                showDisabled : $('input[name=ShowDisabled]').attr('checked'), 
                showExpired : $('input[name=ShowDisabled]').attr('checked')
            };

            var grid = $('#Grid').data('tGrid');
            grid.rebind(params);
        });
    });
</script>

Here's the controller action bound to your select command:

[GridAction(EnableCustomBinding=true)]
public ActionResult _BindGrid(GridCommand command, string mode, int? id, bool showExpired, bool showDisabled)
{
    return View(new GridModel(GetMessageGridItems(command, mode, id,  showExpired, showDisabled)));
}

The param 'command' has the sorting and paging information. Note: this solution is for an ajax-ified grid. If you are doing straight-up posts, you can still use the GridCommand command parameter to maintain the state of paging/filtering/sorting.

0
votes

Give this one a try: Telerik MVC Grid External Filter

It's a jquery plugin which enables you to set the filter by custom input controls.

0
votes

Here is a much easier way to pass parameters back from your form during the telerix ajax post back.

Simply hook into the global $.ajaxPrefilter event and use jquery to serialize the contents of your from to the URL that is being submitted. This will work with ASP.MVC model binding

<script type="text/javascript">

$.ajaxPrefilter(function (options) {
    options.url = options.url + "&" + $("form").serialize();
});

</script>