开发者

jqGrid + ASP.NET WebForm (C#) Search abilities

Ohoy there!

I've been struggling with this problem for days, and I'm really starting to loose my temper about this!

I had managed to get informations parsed back to the grid, which can be sorted, but when I'm trying filtering the results, it gets a little bit messy..

I have been programming C# for about 4-5 months, but my Web Forms, Javascript and JQuery (including JSON) is only about 14 days or so, so maybe it's something very basics I do wrong - please be!!

First, I'm wondering if this is the correct JSON-syntax?

{"grid":{"_search":true,"nd":1291150141196,"rows":20,"page":1,"sidx":"Name","sord":"asc","filters":"{\"groupOp\":\"AND\",\"rules\":[{\"field\":\"Phone\",\"op\":\"eq\",\"data\":\"2343444\"}]}"}}

Those backslashes seems incorrect to me, and I've tried filtering them at server side, but no luck - again, only 14 days of experience.

Error message:

    "System.InvalidOperationException"
"Cannot convert object of type 'System.String' to type 'Filter'"
"   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n   at System.Web.Script.Serialization.ObjectConverter.AssignToPropertyOrField(Object propertyValue, Object o, String memberName, JavaScriptSerializer serializer, Boolean throwOnError)\r\n   at System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary`2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n   at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n   at System.Web.Script.Services.WebServiceMethodData.StrongTypeParameters(IDictionary`2 rawParams)\r\n   at System.Web.Script.Services.WebServiceMethodData.CallMethodFromRawParams(Object target, IDictionary`2 parameters)\r\n   at System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext context, WebServiceMethodData methodData, IDictionary`2 rawParams)\r\n   at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)"

My WebMethod:

[WebMethod]
[ScriptMethod]
public string GetAll(GridSettings grid) {

    var query = from p in dc.Customers select p;

    //if (grid._search)
    //    if (grid.filters.groupOp == "AND")
    //    {
    //        foreach (var rule in grid.filters.Rules)
    //            query = query.Where<Customers>(rule.field, rule.data, rule.oper);
    //    }
    //    else if (grid.filters.groupOp == "OR")
    //    {
    //        var temp = (new List<Customers>()).AsQueryable();
    //        foreach (var rule in grid.filters.Rules)
    //        {
    //            var t = query.Where<Customers>(rule.field, rule.data, rule.oper);
    //            temp = temp.Concat<Customers>(t);
    //        }
    //        query = temp.Distinct<Customers>();
    //    }

    query = query.OrderBy<Customers>(grid.sidx, grid.sord);

    List<Customer> result = new List<Customer>();

    foreach (var x in query)
    {
            Customer y = new Customer();
            y.Phone = x.Phone;
            y.Name = x.Name;
            y.Address = x.Address;
            y.Postal = x.Postal;
            y.City = x.City;
            y.Date = x.Date.ToString("dd-MM-yy");
            result.Add(y);
    }

    return JsonConvert.SerializeObject(new PagedList(result, result.Count(), 1, 20));
}

}

Even through I don't think it's necessarily, (server side don't filter atm.):

    public class Customer
    {
        public string Phone { get; set; }
        public string Name { get; set; }
        public string Address { get; set;} 
        public string Postal { get; set; }
        public string City { get; set; }
        public string Date { get; set; }    
    }

public class GridSettings
{
    public bool _search { get; set; }
    public Filter filters { get; set; }
    public long nd { get; set; }
    public int rows { get; set; }
    public int page { get; set; }
    public string sidx { get; set; }
    public string sord { get; set; }
}

public class Filter
{
    public string groupOp { get; set; }
    public Rule[] Rules { get; set; }

    public static Filter Create(string json)
    {
        try
        {
            return JsonConvert.DeserializeObject<Filter>(json);
        }
        catch
        {
            return null;
        }
    }
}

public class Rule
{
    private Dictionary<string, WhereOperation> operations = new Dictionary<string, WhereOperation> { 
        { "eq",WhereOperation.Equal },
        { "ne",WhereOperation.NotEqual },
        { "cn",WhereOperation.Contains }
    };

    public string field { get; set; }
    public string op { set; get; }
    public WhereOperation oper { get { return operations[op]; } }
    public string data { get; set; }


}

public static class LinqExtensions
{
    public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string sortColumn, string direction)
    {
        ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
        MemberExpression memberAccess = null;

        string methodName = string.Format("OrderBy{0}", direction.ToLower() == "asc" ? "" : "descending");

        foreach (var property in sortColumn.Split('.'))
        {
            memberAccess = MemberExpression.Property(memberAccess ?? (parameter as Expression), property);
        }
        LambdaExpression orderByLambda = Expression.Lambda(memberAccess, parameter);
        MethodCallExpression result = Expression.Call(
                              typeof(Queryable),
                              methodName,
                              new[] { query.ElementType, memberAccess.Type },
                              query.Expression,
                              Expression.Quote(orderByLambda));

        return query.Provider.CreateQuery<T>(result);
    }

    public static IQueryable<T> Where<T>(this IQueryable<T> query, string column, object value, WhereOperation operation)
    {
        try
        {
            if (string.IsNullOrEmpty(column))
                return query;

            ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
            MemberExpression memberAccess = null;

            foreach (var property in column.Split('.'))
                memberAccess = Expression.Property(memberAccess ?? (parameter as Expression), property);

            if (memberAccess == null)
                return query.Where(p => true);

            Expression conditional = Expression.Call(null, typeof(LinqExtensions).GetMethod("Comparer"), Expression.Convert(memberAccess, typeof(object)), Expression.Convert(Expression.Constant(value), typeof(object)), Expression.Constant(operation));
            MethodCallExpression result = Expression.Call(typeof(Queryable), "Where", new[] { query.ElementType }, query.Expression, Expression.Lambda(conditional, parameter));

            return query.Provider.CreateQuery<T>(result);
        }
        catch
        {
            return query.Where(p => true);
        }
    }

    public static bool Comparer(this object value1, object value2, WhereOperation operation)
    {
        string strValue1 = value1.ToString().ToLowerInvariant().Trim();
        string strValue2 = value2.ToString().ToLowerInvariant().Trim();

        double dblValue1 = -1;
        double dblValue2 = -1;

        bool areNumbers = double.TryParse(strValue1, out dblValue1) && double.TryParse(strValue2, out dblValue2);

        switch (operation)
        {
            case WhereOperation.Equal:
                return areNumbers ? dblValue1 == dblValue2 : strVal开发者_如何学Cue1 == strValue2;
            case WhereOperation.NotEqual:
                return areNumbers ? dblValue1 != dblValue2 : strValue1 != strValue2;
            case WhereOperation.Contains:
                return strValue1.Contains(strValue2);
        }

        return true;
    }

}

public enum WhereOperation
{
    Equal, NotEqual, Contains
}

public class StringValueAttribute : System.Attribute
{
    private string _value;

    public StringValueAttribute(string value)
    {
        _value = value;
    }

    public string Value
    {
        get { return _value; }
    }
}

public class PagedList
{
    IEnumerable _rows;
    int _totalRecords;
    int _pageIndex;
    int _pageSize;
    object _userData;

    public PagedList(IEnumerable rows, int totalRecords, int pageIndex, int pageSize, object userData)
    {
        _rows = rows;
        _totalRecords = totalRecords;
        _pageIndex = pageIndex;
        _pageSize = pageSize;
        _userData = userData;
    }

    public PagedList(IEnumerable rows, int totalRecords, int pageIndex, int pageSize)
        : this(rows, totalRecords, pageIndex, pageSize, null)
    {
    }

    public int total { get { return (int)Math.Ceiling((decimal)_totalRecords / (decimal)_pageSize); } }

    public int page { get { return _pageIndex; } }

    public int records { get { return _totalRecords; } }

    public IEnumerable rows { get { return _rows; } }

    public object userData { get { return _userData; } }

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }


}

Any finally Javascript:

$(function () {
    $("#CustomerList").dialog({
        autoOpen: false,
        show: "explode",
        width: 720,
        height: 450,
        open: function () {
            $("#CustomerListTable").jqGrid({
                datatype: function (pdata) { getListData(pdata, 'Customers', '#CustomerListTable'); },
                colNames: ['Telefon', 'Navn', 'Adresse', 'Post', 'By', 'CVR'],
                colModel: [
                    { name: 'Phone', width: 70, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
                    { name: 'Name', width: 200, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
                    { name: 'Address', width: 200, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
                    { name: 'Postal', width: 60, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
                    { name: 'City', width: 100, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
                    { name: 'CVR', width: 70, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} }
                ],
                caption: "",
                height: 360,
                loadonce: true,
                scroll: 1,
                pager: '#CustomerListPager',
                gridview: true,
                sortname: 'Name',
                sortorder: 'asc'
            });
            $("#CustomerListTable").jqGrid('navGrid', '#CustomerListPager', { del: false, add: false, edit: false }, {}, {}, {}, { multipleSearch: true });

        }
    });
});

function getListData(pdata, controller, table) {
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "Controls/" + controller + ".asmx/GetAll",
        data: "{\"grid\":" + JSON.stringify(pdata) + "}",
        dataType: "json",
        success: function (data, textStatus) {
            if (textStatus == "success") RecievedData(JSON.parse(getMain(data)).rows, table);
        },
        error: function (data, textStatus) {
            alert("Error fetching data");
        }
    });
}
function RecievedData(data, table) {
    var thegrid = $(table);
    thegrid.clearGridData();
    for (var i = 0; i < data.length; i++) thegrid.addRowData(i + 1, data[i]);
    thegrid.removeClass("jqgrid-overlay");
}
function getMain(data) {
    if (data.hasOwnProperty("d")) return data.d;
    else return data;
}

The solution I have this far, is the result of hours and hours of Goggle, reading and experimenting... I'm going about to going nuts!!

Oh and while I'm here - why on earth does the jqGrid search-button show up X times in the #CustomerListPager, when closing / opening the dialog, and why doesn't it request the datas again? I have to refresh the page everytime - which mainly is the reason why I'm using JQuery - i want to avoid that ;)

Thanks for your time if you have read so far - I'm appreciating this!

Happy december!

Nicky.


I do it like this and it loads the data as well as search can be performed easily.

this is the function which is called to load the jqgrid

function FillGrid(WebMethodString, GridName, PagerName, columnModel, columnNames, header) 
{
    // debugger;
    jQuery(GridName).GridUnload();
    jQuery.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: WebMethodString,
        data: '{}', //PageMethod Parametros de entrada
        datatype: "json",
        success: function(msg) {
            $('#dvWait').css('display', 'block');
            // Do interesting things here.
            // debugger;
            var mydata = jQuery.parseJSON(msg.d);
            //console.log(mydata);

            jQuery(GridName).jqGrid({
                datatype: "local",
                data: mydata,
                colNames: columnNames,
                colModel: columnModel,
                pager: jQuery(PagerName),
                rowNum: 25,
                mtype: "GET",
                pagination: true,
                scrollOffset: 0,
                rowList: [10, 20, 25],
                sortname: "WorkOrderID",
                scroll: 1,
                sortorder: "desc",
                multiselect: false,
                viewrecords: true,
                caption: header,
                autowidth: true,
                ignoreCase: true,
                height: 580,
                jsonReader: {
                    repeatItem: false,
                    root: function (obj) { return obj.d.rows; },
                    page: function (obj) { return obj.d.page; },
                    total: function (obj) { return obj.d.total; },
                    records: function (obj) { return obj.d.records; }
                },
                afterInsertRow: function(rowid, rowdata, rowelem) {
                    jQuery(GridName).setCell(rowid, 'WorkOrderID', '', '', { title: '', onclick: 'DisappearPopup(event);' });
                    jQuery(GridName).setCell(rowid, 'Requester', '', '', { title: '', onclick: 'DisappearPopup(event);' });
                    jQuery(GridName).setCell(rowid, 'AssignedTo', '', '', { title: '', onclick: 'DisappearPopup(event);' });
                    jQuery(GridName).setCell(rowid, 'SummaryText', '', '', { title: '', onclick: 'DisappearPopup(event);' });
                    jQuery(GridName).setCell(rowid, 'CreationDate', '', '', { title: '', onclick: 'DisappearPopup(event);' });
                },
                gridComplete: function() {
                    $('#dvMaintbl').css('visibility', 'visible');
                    $('#dvWait').css('display', 'none');
                }
            })
            jQuery(GridName).jqGrid('navGrid', PagerName,
            {
                edit: false,
                add: false,
                del: false,
                searchtext: 'Search',
                refreshtext: 'Reload'
            });
        }
    });
}

Add this code in .aspx page

<script type="text/javascript">
    // debugger;
    jQuery(document).ready(function() {
        FillGrid('Json.asmx/GetAllTroubleTickets', '#grid', '#pager', "put your column model here", "put your column names here", "put header text here");       
    });
</script>

Following is my web service call:

Public Function GetAllTroubleTickets() As String

    Dim strStatus As String = HttpContext.Current.Request.QueryString("status")
    Dim page As Integer = 1

    If HttpContext.Current.Request.Form("page") IsNot Nothing Then
        page = Integer.Parse(HttpContext.Current.Request.Form("page").ToString())
    End If
    Dim rp As Integer = 1
    If HttpContext.Current.Request.Form("rowNum") IsNot Nothing Then
        rp = Integer.Parse(HttpContext.Current.Request.Form("rowNum").ToString())
    End If
    Dim start As Integer = ((Page - 1) * rp)

    If (strStatus = Nothing) Then
        strStatus = "2"
    End If
    Dim dsDatos As DataSet = GetAllTroubleTicketsclass("", "WorkOrderID asc", "1", "4000", "", Convert.ToInt16(strStatus))

    Dim result As String = Jayrock.Json.Conversion.JsonConvert.ExportToString(dsDatos.Tables(0).Rows)
    Return result        

End Function
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜