ASP.NET MVC 2.0 Implementation of searching in jqgrid
Asked Answered
C

4

26

Hi I am trying to use the single column search in jqgrid using MVC 2 IN .NET (VS 2008) this is the code I have so far but I need an example to match it with or a tip of what I am missing

jQuery("#list").jqGrid({
    url: '/Home/DynamicGridData/',
    datatype: 'json',
    mtype: 'POST',
    search: true,
    filters: {
        "groupOp":"AND",
        "rules": [
            {"field":"Message","op":"eq","data":"True"}
        ]
    },
    multipleSearch: false,
    colNames: [ 'column1', 'column2'],
    colModel: [
        { name: 'column1', index: 'column1', sortable: true, search: true,
          sorttype: 'text', autoFit: true,stype:'text',
          searchoptions: { sopt: ['eq', 'ne', 'cn']} },
        { name: 'column2', index: 'column2', sortable: true,search: false,
          sorttype: 'text', align: 'left', autoFit: true}],
    pager: jQuery('#pager'),
    rowNum: 10,
    rowList: [10, 60, 100],
    scroll: true,
    sortname: 'column2',
    sortorder: 'asc',
    gridview: true,
    autowidth: true,
    rownumbers: true,
    viewrecords: true,
    imgpath: '/scripts/themes/basic/images',
    caption: 'my data grid'
});

jQuery("#list").jqGrid('navGrid', '#pager', {add: false, edit: false, del: false},
                       {}, {}, {}, { multipleSearch: true, overlay: false });
//jQuery("#list").jqGrid('filterToolbar', {stringResult:true, searchOnEnter:true});
jQuery("#list").jqGrid('navButtonAdd', '#pager',
                      { caption: "Finding", title: "Toggle Search Bar",
                        buttonicon: 'ui-icon-pin-s',
                        onClickButton: function() { $("#list")[0].toggleToolbar() }
                      });

jQuery("#list").jqGrid = {
    search : {
        caption: "Search...",
        Find: "Find",
        Reset: "Reset",
        odata : ['equal', 'not equal','contains'],
        groupOps: [ { op: "AND", text: "all" }, { op: "OR", text: "any" } ],
        matchText: " match",
        rulesText: " rules"
    }
}                              

});

two things paging is not coming up and search although I have the search window opening with just hte column1 as an option and when clicking the find it seems like it loads the grid but actually without matching my value that I type in the text box.

UPDATED: as you can see I made an attempt with the serach argument that did not succeed thanks again for your help it is appreciated

//public ActionResult DynamicGridData(string sidx, string sord, int page, int rows,bool search, string fieldname,string fieldvalue)
public ActionResult DynamicGridData(string sidx, string sord, int page, int rows)
{
    var context = new  AlertsManagementDataContext();
    int pageIndex = Convert.ToInt32(page) - 1;
    int pageSize = rows;
    int totalRecords = context.Alerts.Count();
    int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);

    IQueryable<Alert> alerts = null;
    try
    {
       //if (!search)
       //{
           alerts = context.Alerts.
           OrderBy(sidx + " " + sord).
           Skip(pageIndex * pageSize).
           Take(pageSize);
       //}
       //else
       //{
       //    alerts = context.Alerts.Where (fieldname +"='"+ fieldvalue +"'").
       //    Skip(pageIndex * pageSize).
       //    Take(pageSize);
       //}
    }
    catch (ParseException ex)
    {
        Response.Write(ex.Position + "  " + ex.Message + "  " + ex.Data.ToString());
    }

    //var alerts =
    //    from a in context.Alerts
    //    orderby sidx ascending
    //    select a;

    var jsonData = new {
        total = totalPages,
        page = page,
        records = totalRecords,

        rows = (
          from alert in alerts

          select new {
            id = alert.AlertId,
            cell = new string[] {
                "<a href=Home/Edit/"+alert.AlertId +">Edit</a> " +"|"+
                    "<a href=Home/Details/"+alert.AlertId +">Detail</a> ",
                alert.AlertId.ToString() ,
                alert.Policy.Name ,
                alert.PolicyRule ,
                alert.AlertStatus.Status ,
                alert.Code.ToString() ,
                alert.Message ,
                alert.Category.Name}
        }).ToArray()
    };

    return Json(jsonData);
}
Calices answered 31/3, 2011 at 13:40 Comment(1)
I modified the title and the tags of the question to include the information about ASP.NET MVC. You can correct the text one more time yourself.Tribunate
T
25

Probably you have problem on the server side. Could you append your question with the code of DynamicGridData action which you currently use. The action should have filters as the parameter.

Some parts of your current code are definitively wrong. For example jqGrid is the jQuery plugin. So the methods of jQuery will be extended with the main jqGrid method which you use as jQuery("#list").jqGrid(...);. So after the initializing of jqGrid jQuery("#list").jqGrid will be a function. In you code (the last statement) you overwrite the jQuery("#list").jqGrid method with the object { search: { ... } }. What you should do instead is

jQuery.extend(jQuery.jgrid.search, {
    odata : ['equal', 'not equal','contains']
});

like for example here is described how to overwrite the emptyrecords default value. You don't need to include the values which are already the same in the default jqGrid settings.

Moreover if you use searchoptions: { sopt: ['eq', 'ne', 'cn']} on all searchable columns you don't need to do the change.

In the text of your question you don't explained what you want to do. Your current code is so that you use the filter Message equal to true at the initial grid loading. Strange is that there are no column with the name Message in the grid. If you want just send some additional information to the server you should better use postData parameter:

postData: {Message:true}

I continue to recommend you to remove garbage from the jqGrid definition like imgpath and multipleSearch parameters of jqGrid and sortable: true, search: true, sorttype: 'text', autoFit: true, stype:'text', align: 'left' which are either unknown or default.

UPDATED: The original code of the Phil Haack demo is very old and it use LINQ to SQL. Like I wrote before (see here) Entity Framework (EF) allows to use sorting, paging and filtering/searching without any AddOns like LINQ Dynamic Query Library in form System.Linq.Dynamic. So I made the demo you you which is modification of the the Phil Haack demo to EF.

Because you use the old version of Visual Studio (VS2008 with ASP.NET MVC 2.0) I made the demo also in VS2008.

You can download my VS2008 demo from here and VS2010 demo here.

In the code I show (additionally to the usage of Advanced Searching and Toolbar Searching in ASP.NET MVC 2.0) how to return exception information from ASP.NET MVC in JSON format and how to catch the information with the loadError method and display the corresponding error message.

To construct the Where statement from the ObjectQuery represented EF object I define the following helper class:

public class Filters {
    public enum GroupOp {
        AND,
        OR
    }
    public enum Operations {
        eq, // "equal"
        ne, // "not equal"
        lt, // "less"
        le, // "less or equal"
        gt, // "greater"
        ge, // "greater or equal"
        bw, // "begins with"
        bn, // "does not begin with"
        //in, // "in"
        //ni, // "not in"
        ew, // "ends with"
        en, // "does not end with"
        cn, // "contains"
        nc  // "does not contain"
    }
    public class Rule {
        public string field { get; set; }
        public Operations op { get; set; }
        public string data { get; set; }
    }

    public GroupOp groupOp { get; set; }
    public List<Rule> rules { get; set; }
    private static readonly string[] FormatMapping = {
        "(it.{0} = @p{1})",                 // "eq" - equal
        "(it.{0} <> @p{1})",                // "ne" - not equal
        "(it.{0} < @p{1})",                 // "lt" - less than
        "(it.{0} <= @p{1})",                // "le" - less than or equal to
        "(it.{0} > @p{1})",                 // "gt" - greater than
        "(it.{0} >= @p{1})",                // "ge" - greater than or equal to
        "(it.{0} LIKE (@p{1}+'%'))",        // "bw" - begins with
        "(it.{0} NOT LIKE (@p{1}+'%'))",    // "bn" - does not begin with
        "(it.{0} LIKE ('%'+@p{1}))",        // "ew" - ends with
        "(it.{0} NOT LIKE ('%'+@p{1}))",    // "en" - does not end with
        "(it.{0} LIKE ('%'+@p{1}+'%'))",    // "cn" - contains
        "(it.{0} NOT LIKE ('%'+@p{1}+'%'))" //" nc" - does not contain
    };
    internal ObjectQuery<T> FilterObjectSet<T> (ObjectQuery<T> inputQuery) where T : class {
        if (rules.Count <= 0)
            return inputQuery;

        var sb = new StringBuilder();
        var objParams = new List<ObjectParameter>(rules.Count);

        foreach (Rule rule in rules) {
            PropertyInfo propertyInfo = typeof (T).GetProperty (rule.field);
            if (propertyInfo == null)
                continue; // skip wrong entries

            if (sb.Length != 0)
                sb.Append(groupOp);

            var iParam = objParams.Count;
            sb.AppendFormat(FormatMapping[(int)rule.op], rule.field, iParam);

            // TODO: Extend to other data types
            objParams.Add(String.Compare(propertyInfo.PropertyType.FullName,
                                         "System.Int32", StringComparison.Ordinal) == 0
                              ? new ObjectParameter("p" + iParam, Int32.Parse(rule.data))
                              : new ObjectParameter("p" + iParam, rule.data));
        }

        ObjectQuery<T> filteredQuery = inputQuery.Where (sb.ToString ());
        foreach (var objParam in objParams)
            filteredQuery.Parameters.Add (objParam);

        return filteredQuery;
    }
}

In the example I use only two datatypes integer (Edm.Int32) and string (Edm.String). You can easy expand the example to use more types based as above on the propertyInfo.PropertyType.FullName value.

The controller action which provide the data to the jqGrid will be pretty simple:

public JsonResult DynamicGridData(string sidx, string sord, int page, int rows, bool _search, string filters)
{

    var context = new HaackOverflowEntities();
    var serializer = new JavaScriptSerializer();
    Filters f = (!_search || string.IsNullOrEmpty (filters)) ? null : serializer.Deserialize<Filters> (filters);
    ObjectQuery<Question> filteredQuery =
        (f == null ? context.Questions : f.FilterObjectSet (context.Questions));
    filteredQuery.MergeOption = MergeOption.NoTracking; // we don't want to update the data
    var totalRecords = filteredQuery.Count();

    var pagedQuery = filteredQuery.Skip ("it." + sidx + " " + sord, "@skip",
                                        new ObjectParameter ("skip", (page - 1) * rows))
                                 .Top ("@limit", new ObjectParameter ("limit", rows));
    // to be able to use ToString() below which is NOT exist in the LINQ to Entity
    var queryDetails = (from item in pagedQuery
                        select new { item.Id, item.Votes, item.Title }).ToList();

    return Json(new {
                    total = (totalRecords + rows - 1) / rows,
                    page,
                    records = totalRecords,
                    rows = (from item in queryDetails
                            select new[] {
                                item.Id.ToString(),
                                item.Votes.ToString(),
                                item.Title
                            }).ToList()
                });
}

To send the exception information to the jqGrid in JSON form I replaced the standard [HandleError] attribute of the controller (HomeController) to the [HandleJsonException] which I defined as the following:

// to send exceptions as json we define [HandleJsonException] attribute
public class ExceptionInformation {
    public string Message { get; set; }
    public string Source { get; set; }
    public string StackTrace { get; set; }
}
public class HandleJsonExceptionAttribute : ActionFilterAttribute {
    // next class example are modification of the example from
    // the http://www.dotnetcurry.com/ShowArticle.aspx?ID=496
    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null) {
            filterContext.HttpContext.Response.StatusCode =
                (int)System.Net.HttpStatusCode.InternalServerError;

            var exInfo = new List<ExceptionInformation>();
            for (Exception ex = filterContext.Exception; ex != null; ex = ex.InnerException) {
                PropertyInfo propertyInfo = ex.GetType().GetProperty ("ErrorCode");
                exInfo.Add(new ExceptionInformation() {
                    Message = ex.Message,
                    Source = ex.Source,
                    StackTrace = ex.StackTrace
                });
            }
            filterContext.Result = new JsonResult() {Data=exInfo};
            filterContext.ExceptionHandled = true;
        }
    }
}

On the client side I used the following JavaScript code:

var myGrid = $('#list'),
    decodeErrorMessage = function(jqXHR, textStatus, errorThrown) {
        var html, errorInfo, i, errorText = textStatus + '\n' + errorThrown;
        if (jqXHR.responseText.charAt(0) === '[') {
            try {
                errorInfo = $.parseJSON(jqXHR.responseText);
                errorText = "";
                for (i=0; i<errorInfo.length; i++) {
                   if (errorText.length !== 0) {
                       errorText += "<hr/>";
                   }
                   errorText += errorInfo[i].Source + ": " + errorInfo[i].Message;
                }
            }
            catch (e) { }
        } else {
            html = /<body.*?>([\s\S]*)<\/body>/.exec(jqXHR.responseText);
            if (html !== null && html.length > 1) {
                errorText = html[1];
            }
        }
        return errorText;
    };
myGrid.jqGrid({
    url: '<%= Url.Action("DynamicGridData") %>',
    datatype: 'json',
    mtype: 'POST',
    colNames: ['Id', 'Votes', 'Title'],
    colModel: [
        { name: 'Id', index: 'Id', key: true, width: 40,
            searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'] }
        },
        { name: 'Votes', index: 'Votes', width: 40,
            searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'] }
        },
        { name: 'Title', index: 'Title', width: 400,
            searchoptions: { sopt: ['cn', 'nc', 'bw', 'bn', 'eq', 'ne', 'ew', 'en', 'lt', 'le', 'gt', 'ge'] }
        }
    ],
    pager: '#pager',
    rowNum: 10,
    rowList: [5, 10, 20, 50],
    sortname: 'Id',
    sortorder: 'desc',
    rownumbers: true,
    viewrecords: true,
    altRows: true,
    altclass: 'myAltRowClass',
    height: '100%',
    jsonReader: { cell: "" },
    caption: 'My first grid',
    loadError: function(jqXHR, textStatus, errorThrown) {
        // remove error div if exist
        $('#' + this.id + '_err').remove();
        // insert div with the error description before the grid
        myGrid.closest('div.ui-jqgrid').before(
            '<div id="' + this.id + '_err" style="max-width:'+this.style.width+
            ';"><div class="ui-state-error ui-corner-all" style="padding:0.7em;float:left;"><span class="ui-icon ui-icon-alert" style="float:left; margin-right: .3em;"></span><span style="clear:left">' +
                        decodeErrorMessage(jqXHR, textStatus, errorThrown) + '</span></div><div style="clear:left"/></div>')
    },
    loadComplete: function() {
        // remove error div if exist
        $('#' + this.id + '_err').remove();
    }
});
myGrid.jqGrid('navGrid', '#pager', { add: false, edit: false, del: false },
              {}, {}, {}, { multipleSearch: true, overlay: false });
myGrid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: true, defaultSearch: 'cn' });
myGrid.jqGrid('navButtonAdd', '#pager',
            { caption: "Filter", title: "Toggle Searching Toolbar",
                buttonicon: 'ui-icon-pin-s',
                onClickButton: function() { myGrid[0].toggleToolbar(); }
            });

As the result if one types any non-numeric text (like 'ttt') in the searching toolbar one receive exception the controller action code (in Int32.Parse(rule.data)). One the client side one will see the following message:

enter image description here

I send from the controller to the jqgrid the information about all internal exceptions. So for example, the error in connection to the SQL server will looks like

enter image description here

In the real world one verify the users input and throws exception with application oriented error message. I used in the demo specially no such kind of validation to show that all kind of exception will be cached and display by jqGrid.

UPDATED 2: In the answer you will find the modified VS2010 demo (downloadable from here) which demonstrate the usage of jQuery UI Autocomplete. Another answer extend the code more to export the grid contain in Excel format.

Tribunate answered 31/3, 2011 at 14:41 Comment(36)
mainly I am trying to search based on a column (Message was the column I tried to reduce the names and make them more general for ease of reading) and add the pagin back to my grid.Calices
I couldnt attach my code in the comment so I posted it as an answer sorry!Calices
I checked on #439159 and the only issue I have how is the code getting the search , fieldname and searchstring from the grid is this set by default or a setting that I am missing somewhereCalices
@Sue: First of all I moved the code which you posted from the answer to the question. Do you use some common Database to the example or one own? I am busy now, but I'll try to correct your code later. Is the usage of LINQ to SQL is important for you or an Entity Framework (EF) database access is exactly so interesting? I ask because in EF it is easier to create dynamic queries based only on text input strings like you as has in case of jqGrid.Tribunate
Thanks again, I guess I am learning many things with this assignment.I am using LINQ TO SQL at this time working on pre existing code, and actually I did a little bit of progress by pasisng the search bool as true when the search is clicked (another stackoverflow thread sample) but I am having problem finding the search column and the value searched but whenever you have time I will appreciate your helpCalices
Oleg, do you know how to make sure that the searchField searchString and searchOper are being passed correctly to the code/action side?Calices
@Sue: If you remove multipleSearch:true searching option then the searching dialog will send _search, searchField, searchString, searchOper (the case is important) parameter in the request to the server. Without multipleSearch:true the format of the searching toolbar will be other like: parameters send to the server will be like the column names (column2 or/and column2). So one use mostly multipleSearch:true and convert in the server method the filters parameter to object with JavaScriptSerializer or DataContractJsonSerializer.Tribunate
Oleg, I did get the params after removing the multiplesesarch how can I use the javascriptserializer? any examples? this is what i plan to do IQueryable<tblname> = context.table.Where(searchField + "='" + searchString + "'"). Skip(pageIndex * pageSize). Take(pageSize);Calices
One more thing any good resource book/site for more in depth view on this subject?Calices
@Sue: The JavaScriptSerializer or DataContractJsonSerializer you need to use only if you use multipleSearch:true. If you remove the parameter the input data don't need be converted. If you use LINQ to SQL you will still have the main problem to construct "Where" with the string parameters. The System.Linq.Dynamic could help you. If you will use Entity Framework instead all will be much more simple. See here for more information.Tribunate
yes what you say makes sense, and thanks abudantently for your help, I am trying to work on the where method I will keep looking but if you came across any examples please share with me.Calices
Hi again Oleg, did you get a chance to look at my code? I know you said you are busy, I wanted to ask you about the context.table.where.skip.take, when I use this for pagin it works just find but when I try and use it for search (and by debugging I can see the column name and the string value that I am testing with is being transferred successful) it does not work, so alerts = context.Alerts.Where( searchField +"="+ searchString). Skip(pageIndex * pageSize). Take(pageSize); what am I missing,Calices
@Sue: I prepared code example for you which use multipleSearch:true and JavaScriptSerializer to decode filters. I bring my children to bath and bed and then post the code and url to download the whole project. First of all I'll append my answer with the most important parts and will comment it later.Tribunate
Hey Oleg, I just found my problem it was syntax problem with where ... anyways I will be very interested to look at your example (when you post it) as the next step for me is to work with multiple searchCalices
@Sue: You can download the demo which I promised you from here: ok-soft-gmbh.com/jqGrid/jqGridDemo.zipTribunate
@Sue: I refresh my demo from yesterday. Under http://www.ok-soft-gmbh.com/jqGrid/jqGridDemo0.zip is the old demo and the new one is hereTribunate
@Sue: You ask me about the code example, but after I prepared the demo for you and posted it you don't write any comments more. Do you tried my code? Is it helpful? Is you problem is solved now?Tribunate
Hey Oleg, I truly apologize (especially with this delay) I did use your code it was very helpful, I did not use all features yet but I regularly come back to this code as I work on my project, GREAT WORK!! I also followed your comments on tpeczek's commentsCalices
In fact the difference with my code is mostly linq to Entities and I am trying to understand the filtering that you created and shift to thatCalices
@Sue: My main idea is that the usage of ObjectQuery<T> in case of Entity Framework is better as the usage of IQueryable<T> because IQueryable<T> not support string parameters which you receive as input from jqGrid. If you use IQueryable<T> you will have to include in your project System.Linq.Dynamic.dll or the source code of LINQ Dynamic Query Library like tpeczek do (it is more as 4000 rows of code). The usage of ObjectQuery<T> is more effective in case of the usage of Entity Framework. It is my main statement.Tribunate
@Oleg, what version of Visual studio are required for open your demo project? I couldn't got it open using Visual Sutido 2008 Pro Version 9.0.30729.4462 QFE, it says something like some features not supported by this version, and Visual Studio Web Developer 2010 will failed to convert it.Emad
@pstar: If you use VS2010 you can download the project here. Do you need VS2008 you should install MVC 2.0. On my current computer I have no VS2008 more. I used VS2008 Ultimate, but it should sure work on Professional version too. What error exactly you receive?Tribunate
@Oleg, Under Visual Studio 2008 "The project file 'projectPath' cannot be opened. The project type is not supported by this installation."Emad
@Oleg, the VS2010 one works fine in my machine, I wouldn't worry about the VS2008 one. Thanks again for your help.Emad
@pstar: The mennsage "The project type is not supported" means probably that ASP.NET MVC 2.0 are not installed on your computer. If you open csproj file in notepad you can find the line <ProjectTypeGuids> which has {F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}. The guid {F85E285D-A4E0-4152-9332-AB1D724D3325} means ASP.NET MVC 2.0 project. You can download it from here.Tribunate
@pstar: {349c5851-65df-11da-9384-00065b846f21} is Web application project and {fae04ec0-301f-11d3-bf4b-00c04f79efbc} for C#. There all installed by default in VS2008. So I suppose you should just need to install ASP.NET MVC 2.0 from the link at the end of my previous commment.Tribunate
@pstar: You are welcome! VS2010 project is more recent and if you have VS2010 SP1 installed i recommend you to use it better.Tribunate
@Oleg: this sample contains html = /<body.*?>([\s\S]*)<\/body>/.exec(jqXHR.responseText); which produces error in jslint. There is answer #1732848 with 4350 upvotes which strongly recommends not to use regexps to parse html. I posted question about replacing this statement in #7348528Joycejoycelin
@Andrus: I known the warning (the error) of JSLint. I understand that one can write more exact RegEx which describes all possible <body> attributes, but I think that one needs it not really. If you has some better suggestion you are welcome. I would just use /*jslint regexp: true */ option to switch off the error. In the same way if I use ++ no time in the expressions like x + ++y which are difficult to read I use frequently plusplus options of JSLint to allow constructs like for (i = 0; i < length; i++) {...}. More important is to use i after the <\/body>/.Tribunate
@Oleg: Four issues: 1. More important is to use use i. Maybe to fix code for this. 2. If jquery form plugin is used to post images , filterContext.HttpContext.Request.IsAjaxRequest() returns false and thus controller returns invalid response on error. 3. Also responseText is null in this case and this causes exception in browser. 4. If working offline responseText is undefined, so in this case also exception occurs in browserJoycejoycelin
@Oleg: FilterExpression class should find base type from nullable type also.Joycejoycelin
if like operator is used, like special characters % and _ should escaped in search parameter.Joycejoycelin
you have any example where you have done server side sorting and paging in asp.net?Malefic
@Learning: The above code do this. See the code of DynamicGridData . You can remove some parts of the code. If you are beginner I recommend you to consider exactly whether you really need server side paging. Client side paging/sorting/filtering works quickly enough for some 1000 of rows. Try the demo and this one with 4000 and 40000 rowsTribunate
but you have done this in asp.net mvc and i am using just simple asp.netMalefic
@Learning: Please write more exactly what you need. ASP.NET MVC is still ASP.NET. You asked about an example "in asp.net". What technology you you exactly? For example another answer provides an example of usage ASHX (IHttpHandler with ProcessRequest and IsReusable). Probably it's what you are looking for?Tribunate
M
3

Check out below links:

Millsaps answered 2/4, 2011 at 18:37 Comment(5)
I find very good the idea to provide ASP.NET MVC example used jqGrid, but some parts of your current implementation is a little dirty. For example you should include loadError (see [HandleJsonException] attribute and decodeErrorMessage in my example). From the side of searching all your examples supports only two operations: 'eq' and 'ne'. At least 'cn' or 'bw' operation should be included. The manual JSON deserialization in the old "MVC - Searching" I find the wrong way. Sorry for so many critique point, but your example shows much more MVC as jqGrid best practices.Tribunate
Some other small things like <style type="text/css">/* fix the size of the pager */input.ui-pg-input { width: auto; }</style> or the usage of height:'100%' instead of height:'auto' (because of IE9 bug) can improve your examples. The usage of width:'auto' is not supported by jqGrid. The usage of '#jqgpProducts' is better as $('#jqgpProducts'). One should not include default properties like align:'left', search: true, stype: 'text' and so on small things. I wanted only explain more what I mean under the best practices of jqGrid.Tribunate
One more advice: you can remove the horizontal scrolling bar from the jqGrids of your examples if you either modify the default Site.css of MVC project or include <style type="text/css"> table { border-style:none; border-collapse:separate; } table td { border-style:none; }</style> in the _Layout.cshtml after the <link> which includes site.css.Tribunate
@Tribunate Every critique point which is constructive is a good critique point :). I will consider all of your suggestions in next iterations. Some of them actually have already been changed (for example strongly typed helper generates pager: '#{0}Pager' instead of pager: $('#{0}Pager')). If you would have any more suggestions don't hesitate to let me know - especially if they consider the strongly typed helper (you may even drop me an issue on CodePlex) because I really want to make it an usable piece of software.Millsaps
OK! I'll look at the code one more time carefully and post my suggestions to you on the CodePlex.Tribunate
C
1

I have made an attempt with search argument that did not succeed

public ActionResult DynamicGridData(string sidx, string sord, int page, int rows)
{
  var context = new  AlertsManagementDataContext();
  int pageIndex = Convert.ToInt32(page) - 1;
  int pageSize = rows;
  int totalRecords = context.Alerts.Count();
  int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
  IQueryable<Alert> alerts = null;
  try
  {
      //if (!search)
      //   {
      alerts = context.Alerts.
      OrderBy(sidx + " " + sord).
      Skip(pageIndex * pageSize).
      Take(pageSize);
      //     }
      //else
      //    {
      //        alerts = context.Alerts.Where (fieldname +"='"+ fieldvalue +"'").
      //         Skip(pageIndex * pageSize).
      //         Take(pageSize);
      //    }
      }
   catch (ParseException ex)
  {
     Response.Write(ex.Position + "  " + ex.Message + "  " + ex.Data.ToString());
  }
//var alerts =
//    from a in context.Alerts
//    orderby sidx ascending
//    select a;
   var jsonData = new {
                     total = totalPages,
                     page = page,
                     records = totalRecords,
   rows = ( from alert in alerts                            
                select new {
                            id = alert.AlertId,
                            cell = new string[] { 
                                "<a href=Home/Edit/"+alert.AlertId +">Edit</a> " +"|"+ "<a href=Home/Details/"+alert.AlertId +">Detail</a> ",
                                alert.AlertId.ToString() , 
                                alert.Policy.Name , 
                                alert.PolicyRule , 
                                alert.AlertStatus.Status , 
                                alert.Code.ToString() , 
                                alert.Message , 
                                alert.Category.Name}
                        }).ToArray()
                  };

return Json(jsonData); }

Calices answered 31/3, 2011 at 14:47 Comment(0)
H
0

It's a lot easier than you think for server side search. Your indexes in your grid will come across in the json call as arguments. Also there is a parameter in the GridSettings argument that will be set to true if it is a search.. It's called IsSearch. There is also a sortorder and column in the GridSettings argument that will help you build dy

So, you'd have something like this..

public JsonResult GetUsers(GridSettings gridSettings, string FirstName, string LastName)
{  
    // conditional logic and queries here and return results)
}
Holler answered 3/6, 2015 at 14:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.