jqGrid + ASP.NET WebForm (C #) Возможности поиска - PullRequest
0 голосов
/ 01 декабря 2010

Ой там!

Я боролся с этой проблемой в течение многих дней, и я действительно начинаю выходить из себя по этому поводу!

Мне удалось проанализировать информацию обратно в таблицу, которую можно отсортировать, но когда я пытаюсь отфильтровать результаты, она становится немного грязной ..

Я программирую на C # около 4-5 месяцев, но мои веб-формы, Javascript и JQuery (включая JSON) всего около 14 дней или около того, так что, может быть, это что-то очень общее, я ошибаюсь - пожалуйста, будьте !!

Во-первых, мне интересно, правильный ли это синтаксис JSON?

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

Эти обратные слеши мне кажутся неправильными, и я попытался отфильтровать их на стороне сервера, но не повезло - опять же, всего 14 дней опыта.

Сообщение об ошибке:

    "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)"

Мой веб-метод:

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

}

Даже через это я не думаю, что это обязательно, (серверная сторона не фильтрует атм.):

    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 : strValue1 == 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);
    }


}

Любой наконец-то 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;
}

Решение, которое у меня есть, это результат часов и часов изумления, чтения и экспериментов ... Я собираюсь сходить с ума !!

Да, и пока я здесь - с какой стати кнопка поиска jqGrid отображается X раз в #CustomerListPager при закрытии / открытии диалога, и почему он не запрашивает данные снова? Мне приходится обновлять страницу каждый раз - в основном это причина, по которой я использую JQuery - я хочу этого избежать;)

Спасибо за ваше время, если вы до сих пор читали - я ценю это!

Счастливого декабря!

Nicky.

1 Ответ

1 голос
/ 27 января 2011

Я делаю это так, и он загружает данные, а поиск может быть легко выполнен.

это функция, которая вызывается для загрузки 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'
            });
        }
    });
}

Добавить этокод на странице .aspx

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

Ниже приведен мой вызов веб-службы:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...