ASP.NET MVC 2.0在jqgrid中实现搜索 [英] ASP.NET MVC 2.0 Implementation of searching in jqgrid

查看:189
本文介绍了ASP.NET MVC 2.0在jqgrid中实现搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在jqgrid中使用MVC 2 IN .NET(VS 2008)中的单列搜索,这是迄今为止我已经编写的代码,但是我需要一个例子来匹配它,或者我缺少的一个提示

  jQuery(#list)jqGrid({
url:'/ Home / DynamicGridData /',
数据类型:'json',
mtype:'POST',
搜索:true,
过滤器:{
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:'我的数据网格'
});

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:查找,标题:切换搜索栏,
buttonicon:'ui -icon-pin-s',
onClickButton:function(){$(#list)[0] .toggleToolbar()}
});

jQuery(#list)。jqGrid = {
搜索:{
标题:搜索...,
查找:查找,
重置:重置,
odata:['equal','not equal','contains'],
groupOps:[{op:AND,text:all} ,{op:OR,text:any}],
matchText:match,
rulesText:rules
}
}

});

两件事情没有出现在
和搜索,虽然我有搜索窗口打开只是hte column1作为一个选项,当点击发现似乎它加载网格,但实际上没有匹配我的值在文本框中输入。



更新:,您可以看到我尝试了没有成功的serach参数,感谢您的帮助,感谢您的赞赏。

  // 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)。
跳过(pageIndex * pageSize)。
Take(pageSize);
//}
// else
// {
// alerts = context.Alerts.Where(fieldname +='+ fieldvalue +')。
//跳过(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 =(
从警报中提醒

选择新的{
id = alert.AlertId,
cell = new string [] {
< a href = Home /编辑/+ alert.AlertId +>编辑< / a>+|+
< a href =首页/细节/+ alert.AlertId +>细节< / a> ,
alert.AlertId.ToString(),
alert.Policy.Name,
alert.PolicyRule,
alert.AlertStatus.Status,
alert.Code。 ToString(),
alert.Message,
alert.Category.Name}
})ToArray()
};

return Json(jsonData);
}


解决方案

可能你有问题服务器端。您可以使用当前使用的 DynamicGridData 操作的代码附加问题。该操作应该有过滤器作为参数。



您当前代码的某些部分显然是错误的。例如 jqGrid 是jQuery插件。所以jQuery的方法将被扩展为主要的 jqGrid 方法,你用作$ code> jQuery(#list)jqGrid(...) ; 。所以在初始化jqGrid jQuery(#list)后,jqGrid 将会是一个函数。在你的代码(最后一个语句)中,覆盖 jQuery(#list)。jqGrid 方法与对象 {search:{... }} 。你应该做的是

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

像例如您将找到经过修改的VS2010演示(可从此处下载),演示使用jQuery UI自动完成。 另一个答案将代码扩展为以Excel格式导出网格包含。


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

解决方案

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:

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

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.

这篇关于ASP.NET MVC 2.0在jqgrid中实现搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆