19

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
                });
});
jww
  • 97,681
  • 90
  • 411
  • 885
GlobalCompe
  • 448
  • 1
  • 4
  • 13

6 Answers6

10

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 };
}

}

Brian
  • 1,845
  • 1
  • 22
  • 37
Craig Fisher
  • 1,681
  • 2
  • 19
  • 26
7

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!

VinnyG
  • 6,883
  • 7
  • 58
  • 76
  • 1
    Your approach is basically the same as GlobalCompe's - passing the Javascript parameters to the rebind call. The problem I am seeing with this approach is that on paging the parameters are lost. Are you seeing this also? – Craig Fisher Mar 07 '11 at 19:52
  • Solved, kind of. This (paging) is broken in the latest (Q1-2011) beta of the MVC extensions. – Craig Fisher Mar 07 '11 at 22:21
  • 1
    This answer is more helpful than the majority of client api examples on telerik web site. Thank hou so much! – Samuel Dec 15 '11 at 23:11
2

This is actually documented here.

Atanas Korchev
  • 30,562
  • 8
  • 59
  • 93
  • so if I understand correctly, all I have to do is to set the databinding as follows Html.Telerik().Grid(Model) .DataBinding(databinding => databinding.Ajax().Select("GetInvoicesInPages", "Invoices", new { startSearchDate = (string)ViewData["StartDatePicker-input"] })) .EnableCustomBinding(true) and on client side do $("#searchButton").click(function() { var grid = $("#Invoices").data('tGrid'); grid.ajaxRequest();} ); – GlobalCompe Apr 07 '10 at 18:36
2
<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.

Merritt
  • 2,333
  • 21
  • 23
0

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.

Dänu
  • 5,791
  • 9
  • 43
  • 56
  • This solution doesn't filter on the server side, does it? From what I can gather, you are filtering the select already executed against your data source. – Merritt Mar 08 '11 at 20:41
0

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>
Eric Ziko
  • 585
  • 1
  • 5
  • 8