Come implementare più ricerche in jqGrid

Ho un jqGrid che sto usando con asp.Net Web Forms, mostra le informazioni richieste correttamente dal database, tuttavia mostra anche l’opzione di ricerca, ma se provo a cercare, diciamo First Name che è uguale a Lijo, semplicemente non mostra quel record. Il record esiste. So che mi mancano alcune cose necessarie per la ricerca sicuramente, ecco il codice

 $(function() { $("#UsersGrid").jqGrid({ url: 'ModCust.ashx', datatype: 'json', height: 250, width: 800, colNames: ['Application No', 'First Name', 'Middle Name', 'Last Name'], colModel: [ { name: 'cApplicationNo', index: 'cApplicationNo', width: 100, sortable: true}, { name: 'cFirstName', width: 100, sortable: true}, { name: 'cMiddleName', width: 100, sortable: true }, { name: 'cLastName', width: 100, sortable: true }, ], cmTemplate: { title: false}, rowNum: 10, rowList: [10, 20, 30], pager: '#UsersGridPager', sortname: 'cApplicationNo', viewrecords: true, sortorder: 'asc', caption: 'Customer Details' }); $("#UsersGrid").jqGrid('navGrid', '#UsersGridPager', { edit: false, add: false, del: false }); });  

Ecco il mio gestore ModCust.ashx

 using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Data.SqlClient; using System.Web; using System.Web.Script.Serialization; namespace CwizBankApp { public struct JQGridResults { public int page; public int total; public int records; public JQGridRow[] rows; } public struct JQGridRow { public string id; public string[] cell; } [Serializable] public class User { public string ApplicationNo { get; set; } public string FirstName { get; set; } public string MiddleName { get; set; } public string LastName { get; set; } } ///  /// Summary description for $codebehindclassname$ ///  public class ModCust : IHttpHandler { public void ProcessRequest(HttpContext context) { HttpRequest request = context.Request; HttpResponse response = context.Response; string _search = request["_search"]; string numberOfRows = request["rows"]; string pageIndex = request["page"]; string sortColumnName = request["sidx"]; string sortOrderBy = request["sord"]; int totalRecords; //Collection users = GetDummyUsers(numberOfRows, pageIndex, sortColumnName, sortOrderBy, out totalRecords); Collection users = GetUsers(numberOfRows, pageIndex, sortColumnName, sortOrderBy, out totalRecords); string output = BuildJQGridResults(users, Convert.ToInt32(numberOfRows), Convert.ToInt32(pageIndex), Convert.ToInt32(totalRecords)); response.Write(output); } private string BuildJQGridResults(Collection users, int numberOfRows, int pageIndex, int totalRecords) { JQGridResults result = new JQGridResults(); List rows = new List(); foreach (User user in users) { JQGridRow row = new JQGridRow(); row.id = user.ApplicationNo; row.cell = new string[4]; row.cell[0] = user.ApplicationNo; row.cell[1] = user.FirstName; row.cell[2] = user.MiddleName; row.cell[3] = user.LastName; rows.Add(row); } result.rows = rows.ToArray(); result.page = pageIndex; result.total = (totalRecords + numberOfRows - 1) / numberOfRows; result.records = totalRecords; return new JavaScriptSerializer().Serialize(result); } private Collection GetDummyUsers(string numberOfRows, string pageIndex, string sortColumnName, string sortOrderBy, out int totalRecords) { var data = new Collection { new User(){ FirstName = "Bill", LastName = "Gates", ApplicationNo= "1", MiddleName = "Bill Gates"} }; totalRecords = data.Count; return data; } private Collection GetUsers(string numberOfRows, string pageIndex, string sortColumnName, string sortOrderBy, out int totalRecords) { Collection users = new Collection(); string connectionString = "Server=Server;Database=CwizData;Trusted_Connection=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = new SqlCommand()) { command.Connection = connection; command.CommandText = "select cApplicationNo,cFirstName,cMiddleName,cLastName from Data_Customer_Log"; command.CommandType = CommandType.Text; // StoredProcedure; SqlParameter paramPageIndex = new SqlParameter("@PageIndex", SqlDbType.Int); paramPageIndex.Value = Convert.ToInt32(pageIndex); command.Parameters.Add(paramPageIndex); SqlParameter paramColumnName = new SqlParameter("@SortColumnName", SqlDbType.VarChar, 50); paramColumnName.Value = sortColumnName; command.Parameters.Add(paramColumnName); SqlParameter paramSortorderBy = new SqlParameter("@SortOrderBy", SqlDbType.VarChar, 4); paramSortorderBy.Value = sortOrderBy; command.Parameters.Add(paramSortorderBy); SqlParameter paramNumberOfRows = new SqlParameter("@NumberOfRows", SqlDbType.Int); paramNumberOfRows.Value = Convert.ToInt32(numberOfRows); command.Parameters.Add(paramNumberOfRows); SqlParameter paramTotalRecords = new SqlParameter("@TotalRecords", SqlDbType.Int); totalRecords = 0; paramTotalRecords.Value = totalRecords; paramTotalRecords.Direction = ParameterDirection.Output; command.Parameters.Add(paramTotalRecords); connection.Open(); using (SqlDataReader dataReader = command.ExecuteReader()) { User user; while (dataReader.Read()) { user = new User(); user.ApplicationNo =Convert.ToString(dataReader["cApplicationNo"]); user.FirstName = Convert.ToString(dataReader["cFirstName"]); user.MiddleName = Convert.ToString(dataReader["cMiddleName"]); user.LastName = Convert.ToString(dataReader["cLastName"]); users.Add(user); } } //totalRecords =(int)(paramTotalRecords.Value); // totalRecords = 0; } return users; } } public bool IsReusable { get { return false; } } } } 

Qualcuno può aiutarmi con questo, Qualsiasi suggerimento è benvenuto, grazie

Nella tua domanda hai usato principalmente il progetto demo dalla mia vecchia risposta . Tutte le altre risposte successive che mostrano come implementare la ricerca avanzata, il paging e l’ordinamento sul server (ad esempio questo o questo ) ho utilizzato tecnologie ASP.NET più recenti, principalmente ASP.NET MVC. Dall’altra parte il codice delle demo si può decidere nelle seguenti parti:

  1. Il codice server che fornisce un’interfaccia che può essere utilizzata da jqGrid per ottenere la risposta JSON. Può essere azione controller ASP.NET MVC, metodo WFC, WebMethod del servizio Web ASMX o General ASHX Handler come si utilizza.
  2. Il codice server che analizza il parametro di input inviato da jqGrid. I nomi predefiniti dei parametri sono page , rows , sidx , sord , _search , filters . Si possono rinominare i parametri usando prmNames opzione prmNames di jqGrid.
  3. Accesso al database La parte del codice server dipende dalla tecnologia che si utilizza. Può essere ad esempio Entity Framework, LINQ to SQL o più vecchio, ma con buone prestazioni SqlCommand con SqlDataReader .
  4. Codifica dei risultati come JSON. Si può usare ad esempio JavaScriptSerializer standard o DataContractJsonSerializer o JSON framework ad alte prestazioni Json.NET (conosciuto come Newtonsoft.JSON). Microsoft utilizza e supporta il serializzatore Json.NET open source nella nuova versione di ASP.NET MVC 4.0 e API Web ASP.NET. Uno può includere Json.NET nel progetto ASP.NET e può aggiornarlo all’ultima versione recente utilizzando NuGet .
  5. Gestire sul server le eccezioni e riportare le informazioni sugli errori ai client (jqGrid) nel formato JSON. Il codice è leggermente diverso dipende dalla tecnologia utilizzata sul server. Il codice client nel callback loadError di jqGrid dovrebbe decodificare le informazioni di errore e visualizzarle in qualche modo. In caso di utilizzo ASP.NET MVC ho mostrato nella risposta come implementare HandleJsonExceptionAttribute attributo HandleJsonExceptionAttribute che può essere utilizzato come [HandleJsonException] posto dello standard [HandleError] . In caso di utilizzo di WCF, è ansible utilizzare WebFaultException (vedere qui ). Nel caso di General ASHX Handler si può usare Application_Error di Global.asax per lo scopo.
  6. Opzionalmente è ansible includere nell’impostazione del codice server di ETag nell’intestazione HTTP. Permette di controllare la cache lato client sul lato server. Se il client ha bisogno di dati JSON precedentemente restituiti dal server invierà automaticamente la parte If-None-Match nella richiesta HTTP al server che contiene ETag dalla precedente risposta del server. Il server può verificare se i dati del server vengono modificati dall’ultima risposta. Alla fine il server restituirà i nuovi dati JSON o una risposta vuota che consente al client di utilizzare i dati della vecchia risposta.
  7. È necessario scrivere codice JavaScript che crei jqGrid.

Ho realizzato il progetto dimostrativo che dimostra tutti i passaggi precedenti. Contiene un piccolo Database che riempio con informazioni su alcuni dei famosi matematici. La demo mostra la griglia inserisci la descrizione dell'immagine qui dove è ansible utilizzare l’ordinamento, il paging, il filtro della barra degli strumenti o la ricerca avanzata. In caso di un errore (ad esempio se si interrompe il servizio di Windows “SQL Server (SQLEXPRESS)”) verrà visualizzato il messaggio di errore simile al seguente: inserisci la descrizione dell'immagine qui

Il codice C # che implementa l’handle ASHX nella demo è

 using System; using System.Globalization; using System.Net; using System.Security.Cryptography; using System.Text; using System.Web; using Newtonsoft.Json; namespace jqGridASHX { // ReSharper disable InconsistentNaming public class jqGridData : IHttpHandler { // ReSharper restore InconsistentNaming public void ProcessRequest (HttpContext context) { // to be able to use context.Response.Cache.SetETag later we need the following: context.Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate); // to use with HTTP GET we want be sure that caching of data work correct // so we request revalidation of data by setting in HTTP header the line // "Cache-Control: private, max-age=0" context.Response.Cache.SetMaxAge (new TimeSpan (0)); string numberOfRows = context.Request["rowsPerPage"]; int nRows, iPage; if (String.IsNullOrEmpty (numberOfRows) || !int.TryParse (numberOfRows, NumberStyles.Integer, CultureInfo.InvariantCulture, out nRows)) nRows = 10; // default value string pageIndex = context.Request["pageIndex"]; if (String.IsNullOrEmpty(pageIndex) || !int.TryParse(pageIndex, NumberStyles.Integer, CultureInfo.InvariantCulture, out iPage)) iPage = 10; // default value string sortColumnName = context.Request["sortByColumn"]; string sortOrder = context.Request["sortOrder"]; string search = context.Request["isSearching"]; string filters = context.Request["filters"]; // we can use high-performance Newtonsoft.Json string str = JsonConvert.SerializeObject ( MyData.GetDataForJqGrid ( nRows, iPage, sortColumnName, !String.IsNullOrEmpty (sortOrder) && String.Compare (sortOrder, "desc", StringComparison.Ordinal) == 0 ? MyData.SortOrder.Desc : MyData.SortOrder.Asc, search != null && String.Compare (search, "true", StringComparison.Ordinal) == 0, filters)); context.Response.ContentType = "application/json"; // calculate MD5 from the returned data and use it as ETag byte[] hash = MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(str)); string newETag = Convert.ToBase64String(hash); // compare ETag of the data which already has the client with ETag of response string incomingEtag = context.Request.Headers["If-None-Match"]; if (String.Compare(incomingEtag, newETag, StringComparison.Ordinal) == 0) { // we don't need return the data which the client already have context.Response.SuppressContent = true; context.Response.StatusCode = (int)HttpStatusCode.NotModified; return; } context.Response.Cache.SetETag(newETag); context.Response.Write(str); } public bool IsReusable { get { return false; } } } } 

Usa Newtonsoft.Json per la serializzazione JSON e usa l’hash MD5 come ETag .

Il metodo MyData.GetDataForJqGrid fornisce i dati dal database. Nella demo uso principalmente il codice della risposta , quindi utilizzo Entity Framework per accedere al database:

 using System; using System.Data.Objects; using System.Globalization; using System.Linq; using Newtonsoft.Json; namespace jqGridASHX { public static class MyData { public enum SortOrder { Asc, Desc } public static Object GetDataForJqGrid(int nRows, int iPage, string sortColumnName, SortOrder sortOrder, bool isSearch, string filters) { var context = new MyDatabaseEntities(); var f = (!isSearch || string.IsNullOrEmpty(filters)) ? null : JsonConvert.DeserializeObject(filters); ObjectQuery filteredQuery = f == null ? context.Users : f.FilterObjectSet(context.Users); filteredQuery.MergeOption = MergeOption.NoTracking; // we don't want to update the data var totalRecords = filteredQuery.Count(); var pagedQuery = filteredQuery.Skip( "it." + (String.IsNullOrEmpty(sortColumnName) ? "Id" : sortColumnName) + " " + sortOrder, "@skip", new ObjectParameter("skip", (iPage - 1) * nRows)) .Top("@limit", new ObjectParameter("limit", nRows)); // to be able to use ToString() below which is NOT exist in the LINQ to Entity // we should include in queryDetails only the properies which we will use below var queryDetails = (from item in pagedQuery select new { item.Id, item.FirstName, item.LastName, item.Birthday }).ToArray(); return new { total = (totalRecords + nRows - 1) / nRows, page = iPage, records = totalRecords, rows = (from item in queryDetails select new[] { // In the demo we send Id as the 4-th element of row array. // The value will be not displayed in the grid, but used as rowid // (the id attribute of the  in the ) item.FirstName, item.LastName, item.Birthday == null? String.Empty : ((DateTime)item.Birthday).ToString("yyyy-MM-dd"), item.Id.ToString (CultureInfo.InvariantCulture) }).ToArray() }; } } }

dove la class Filters

 using System; using System.Collections.Generic; using System.Data.Objects; using System.Text; namespace jqGridASHX { public class Filters { // ReSharper disable InconsistentNaming 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 rules { get; set; } // ReSharper restore InconsistentNaming 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 FilterObjectSet(ObjectQuery inputQuery) where T : class { if (rules.Count < = 0) return inputQuery; var sb = new StringBuilder(); var objParams = new List(rules.Count); foreach (var rule in rules) { var 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); ObjectParameter param; switch (propertyInfo.PropertyType.FullName) { case "System.Int32": // int param = new ObjectParameter("p" + iParam, Int32.Parse(rule.data)); break; case "System.Int64": // bigint param = new ObjectParameter("p" + iParam, Int64.Parse(rule.data)); break; case "System.Int16": // smallint param = new ObjectParameter("p" + iParam, Int16.Parse(rule.data)); break; case "System.SByte": // tinyint param = new ObjectParameter("p" + iParam, SByte.Parse(rule.data)); break; case "System.Single": // Edm.Single, in SQL: float param = new ObjectParameter("p" + iParam, Single.Parse(rule.data)); break; case "System.Double": // float(53), double precision param = new ObjectParameter("p" + iParam, Double.Parse(rule.data)); break; case "System.Boolean": // Edm.Boolean, in SQL: bit param = new ObjectParameter("p" + iParam, String.Compare(rule.data, "1", StringComparison.Ordinal) == 0 || String.Compare(rule.data, "yes", StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(rule.data, "true", StringComparison.OrdinalIgnoreCase) == 0); break; default: // TODO: Extend to other data types // binary, date, datetimeoffset, // decimal, numeric, // money, smallmoney // and so on. // Below in the example for DateTime and the nullable DateTime if (String.Compare(propertyInfo.PropertyType.FullName, typeof(DateTime?).FullName, StringComparison.Ordinal) == 0 || String.Compare(propertyInfo.PropertyType.FullName, typeof(DateTime).FullName, StringComparison.Ordinal) == 0) { // we use below en-US locale directly param = new ObjectParameter("p" + iParam, DateTime.Parse(rule.data, new CultureInfo("en-US"), DateTimeStyles.None)); } else { param = new ObjectParameter("p" + iParam, rule.data); } break; } objParams.Add(param); } var filteredQuery = inputQuery.Where(sb.ToString()); foreach (var objParam in objParams) filteredQuery.Parameters.Add(objParam); return filteredQuery; } } } 

Il codice di Global.asax.cs è

 using System; using System.Collections.Generic; using System.Net; using System.Reflection; using System.Web; using Newtonsoft.Json; namespace jqGridASHX { internal class ExceptionInformation { public string Message { get; set; } public string Source { get; set; } public string StackTrace { get; set; } public string ErrorCode { get; set; } } public class Global : HttpApplication { protected void Application_Error(object sender, EventArgs e) { if (Request.ContentType.Contains("application/json")) { Response.Clear(); Response.StatusCode = (int)HttpStatusCode.InternalServerError; Response.Cache.SetMaxAge(new TimeSpan(0)); Response.ContentType = "application/json"; var exInfo = new List(); for (var ex = Server.GetLastError(); ex != null; ex = ex.InnerException) { PropertyInfo propertyInfo = ex.GetType().GetProperty ("HResult"); exInfo.Add (new ExceptionInformation { Message = ex.Message, Source = ex.Source, StackTrace = ex.StackTrace, ErrorCode = propertyInfo != null && propertyInfo.GetValue (ex, null) is int ? "0x" + ((int)propertyInfo.GetValue (ex, null)).ToString("X") : String.Empty }); } Response.Write(JsonConvert.SerializeObject(exInfo)); Context.Server.ClearError(); } } } } 

Sul lato client ho usato la pagina HTML puro per mostrare in gran parte chiaro che è ansible includere la soluzione in qualsiasi progetto di Web Form inclusivo del progetto. La pagina ha il seguente codice

 < !DOCTYPE html>   https://stackoverflow.com/q/10698254/315935               

dove è MyPage.js

 ///  ///  ///  ///  $(function () { "use strict"; $("#list").jqGrid({ url: "jqGridData.ashx", colNames: ["First Name", "Last Name", "Birthday"], colModel: [ { name: "FirstName", width: 200 }, { name: "LastName", width: 180 }, { name: "Birthday", width: 100, formatter: "date", align: "center", searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"], dataInit: function (elem) { $(elem).datepicker({ dateFormat: "m/d/yy", minDate: "1/1/1753", defaultDate: "4/30/1777", autoSize: true, changeYear: true, changeMonth: true, showButtonPanel: true, showWeek: true }); }} } ], jsonReader: { cell: "", // The Id value will be sent as the 4-th element of row array. // The value will be not displayed in the grid, but used as rowid // (the id attribute of the  in the ) id: "3" }, rowNum: 10, rowList: [10, 20, 30], pager: "#pager", rownumbers: true, viewrecords: true, sortname: "Birthday", sortorder: "desc", caption: "Famous Mathematicians" }).jqGrid("navGrid", "#pager", { edit: false, add: false, del: false }) .jqGrid('filterToolbar', { stringResult: true, searchOnEnter: true, defaultSearch: "cn" }); });

e Common.js :

 ///  ///  ///  $.extend($.jgrid.defaults, { height: "100%", altRows: true, altclass: "myAltRowClass", shrinkToFit: false, gridview: true, rownumbers: true, viewrecords: true, datatype: "json", sortable: true, scrollrows: true, headertitles: true, loadui: "block", viewsortcols: [false, "vertical", true], prmNames: { nd: null, page: "pageIndex", rows: "rowsPerPage", sort: "sortByColumn", order: "sortOrder", search: "isSearching" }, ajaxGridOptions: { contentType: "application/json" }, ajaxRowOptions: { contentType: "application/json", type: "PUT", async: true }, ajaxSelectOptions: { contentType: "application/json", dataType: "JSON" }, serializeRowData: function (data) { var propertyName, propertyValue, dataToSend = {}; for (propertyName in data) { if (data.hasOwnProperty(propertyName)) { propertyValue = data[propertyName]; if ($.isFunction(propertyValue)) { dataToSend[propertyName] = propertyValue(); } else { dataToSend[propertyName] = propertyValue; } } } return JSON.stringify(dataToSend); }, resizeStop: function () { var $grid = $(this.bDiv).find('>:first-child>.ui-jqgrid-btable:last-child'), shrinkToFit = $grid.jqGrid('getGridParam', 'shrinkToFit'), saveState = $grid.jqGrid('getGridParam', 'saveState'); $grid.jqGrid('setGridWidth', this.newWidth, shrinkToFit); if ($.isFunction(saveState)) { saveState.call($grid[0]); } }, gridComplete: function () { $("#" + this.id + "_err").remove(); }, loadError: function (xhr) { var response = xhr.responseText, errorDetail, errorHtml, i, l, errorDescription; if (response.charAt(0) === '[' && response.charAt(response.length - 1) === ']') { errorDetail = $.parseJSON(xhr.responseText); var errorText = ""; for (i = 0, l = errorDetail.length; i < l; i++) { if (errorText.length !== 0) { errorText += "
"; } errorDescription = errorDetail[i]; errorText += "" + errorDescription.Source + ""; if (errorDescription.ErrorCode) { errorText += " (ErrorCode: " + errorDescription.ErrorCode + ")"; } errorText += ": " + errorDescription.Message; } errorHtml = '

' + errorText + '

'; $("#" + this.id + "_err").remove(); $(this).closest(".ui-jqgrid").before(errorHtml); } } }); $.extend($.jgrid.search, { multipleSearch: true, recreateFilter: true, closeOnEscape: true, searchOnEnter: true, overlay: 0 });

AGGIORNATO : Ho apportato alcuni piccoli miglioramenti: incluso json2.js (vedi qui ) per supportare JSON.stringify nei vecchi browser Web, il formato fisso della data in jQuery UI Datepicker e il supporto incluso per DateType e DateType? ( System.Nullable ) nella class Filters . Quindi puoi scaricare la versione corrente del progetto dalla stessa posizione .