2010-11-30 30 views
0

Oh là là!jqGrid + ASP.NET WebForm (C#) Capacités de recherche

J'ai lutté avec ce problème pendant des jours, et je commence vraiment à m'énerver à ce sujet!

j'avais réussi à obtenir des informations analysées au réseau électrique, qui peut être triée, mais quand je suis en train de filtrer les résultats, il obtient un peu en désordre ..

Je suis programmation C# environ 4-5 mois, mais mes formulaires Web, Javascript et JQuery (y compris JSON) sont seulement environ 14 jours ou plus, alors peut-être que c'est quelque chose de très basique que je fais mal - s'il vous plaît soyez !! D'abord, je me demande si c'est la bonne syntaxe JSON?

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

Ces antislashs me semble incorrect, et je l'ai essayé de les filtrer à côté du serveur, mais pas de chance - encore une fois, seulement 14 jours d'expérience.

Message d'erreur:

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

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

}

Même par je ne pense pas que ce soit nécessairement, (côté serveur ne filtre pas 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 : 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); 
    } 


} 

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

La solution que j'ai jusque-là, est le résultat des heures et des heures de Goggle, lisant et ... Je vais sur le point de devenir fou !! Oh et pendant que je suis ici - pourquoi diable le bouton de recherche jqGrid apparaît-il X fois dans le #CustomerListPager, lors de la fermeture/ouverture du dialogue, et pourquoi ne demande-t-il pas les données à nouveau? Je dois actualiser la page chaque fois - qui est principalement la raison pour laquelle j'utilise JQuery - je veux éviter cela;)

Merci pour votre temps si vous avez lu jusqu'à présent - j'apprécie cela!

Joyeux décembre!

Nicky.

Répondre

1

Je le fais comme ça et il charge les données ainsi que la recherche peut être effectuée facilement.

c'est la fonction qui est appelée à charger le 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' 
      }); 
     } 
    }); 
} 

Ajouter ce code dans la page .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> 

Après est mon appel de service Web:

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