Wie implementiert man mehrere Suchen in jqGrid?

Ich habe ein jqGrid, das ich mit asp.Net Web Forms verwende, es zeigt die erforderlichen Informationen korrekt aus der database, aber es zeigt auch die Suchoption, aber wenn ich versuche zu suchen, sagen wir First Name, der gleich Lijo ist, es Es erscheint einfach nicht. Das Album existiert. Ich weiß, dass mir ein paar Sachen fehlen, die man für die Suche braucht. Hier ist der Code

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

Hier ist mein ModCust.ashx-Handler

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

Kann mir jemand dabei helfen, Irgendwelche Vorschläge sind willkommen, danke

   

In deiner Frage hast du meistens das Demo-Projekt von meiner alten Antwort benutzt . Alle anderen späteren Antworten, die zeigen, wie Advanced Searching, Paging und Sortierung auf dem Server implementiert wird (zum Beispiel dieser oder dieser ), verwendete ich neuere ASP.NET-Technologien, hauptsächlich ASP.NET MVC. Auf der anderen Seite kann der Code aus den Demos in folgenden Teilen entschieden werden:

  1. Der Servercode, der eine Schnittstelle bereitstellt, die von jqGrid verwendet werden kann, um eine JSON-Antwort zu erhalten. Es kann ASP.NET MVC Controller-Aktion, WFC-Methode, WebMethod von ASMX-Web-Service oder General ASHX Handler wie Sie verwenden.
  2. Der Servercode, der den Eingabeparameter analysiert, der von jqGrid gesendet wird. Die Standardnamen der Parameter sind page , sidx , sord , _search , _search , filters . Man kann die Parameter mit der Option prmNames von jqGrid umbenennen.
  3. Zugriff auf die database Der Teil des Servercodes hängt von der verwendeten Technologie ab. Es kann zum Beispiel Entity Framework, LINQ to SQL oder mehr alt sein, aber mit guter performance SqlCommand mit SqlDataReader .
  4. Codierung der Ergebnisse als JSON. Man kann zum Beispiel den Standard- JavaScriptSerializer oder den DataContractJsonSerializer oder das Hochleistungs-JSON-Framework Json.NET (bekannt als Newtonsoft.JSON) verwenden. Microsoft verwendet und unterstützt den Open Source Json.NET-Serializer in der neuen Version von ASP.NET MVC 4.0 und ASP.NET Web API. Man kann Json.NET in das ASP.NET-Projekt aufnehmen und mit NuGet auf die letzte aktuelle Version aktualisieren.
  5. Behandeln der Ausnahmen auf dem Server und Melden der Fehlerinformationen an die Clients (jqGrid) im JSON-Format. Der Code ist ein wenig unterschiedlich abhängig von der Technologie auf dem Server verwendet. Der Client-Code in loadError Callback von jqGrid sollte die Fehlerinformationen dekodieren und in irgendeiner Form anzeigen. Im Falle der Verwendung von ASP.NET MVC habe ich in der Antwort gezeigt , wie man das HandleJsonExceptionAttribute Attribut implementiert, das als [HandleJsonException] anstelle des Standards [HandleError] . Im Falle der Verwendung von WCF kann WebFaultException (siehe hier ). Im Falle von General ASHX Handler kann Application_Error von Global.asax zu diesem Zweck verwendet werden.
  6. Optional kann man in der Server-Code-Einstellung von ETag in den HTTP-Header aufnehmen. Es ermöglicht, den clientseitigen Cache auf der Serverseite zu steuern. Wenn der Client JSON-Daten benötigt, die zuvor vom Server zurückgegeben wurden, sendet er automatisch den If-None-Match Teil in der HTTP-Anforderung an den Server, die ETag von der vorherigen Serverantwort enthält. Der Server kann überprüfen, ob die Serverdaten seit der letzten Antwort geändert wurden. Am Ende gibt der Server entweder die neuen JSON-Daten oder eine leere Antwort zurück, die es dem Client erlaubt, die Daten der alten Antwort zu verwenden.
  7. Man muss JavaScript-Code schreiben, der jqGrid erzeugt.

Ich habe das Demo-Projekt gemacht, das alle obigen Schritte demonstriert. Es enthält eine kleine database, die ich mit Informationen über einige der berühmten Mathematiker fülle. Die Demo zeigt das Gitter an Bildbeschreibung hier eingeben wo man Sortieren, Paging, Toolbar-Filterung oder erweiterte Suche verwenden kann. Im Falle eines Fehlers (zum Beispiel, wenn Sie Windows-Dienst “SQL Server (SQLEXPRESS)” stoppen) sehen Sie die Fehlermeldung wie folgt: Bildbeschreibung hier eingeben

Der C # -Code, der ASHX-Handle in der Demo implementiert, ist

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

Es verwendet Newtonsoft.Json für JSON-Serialisierung und verwendet MD5-Hash als ETag .

Die Methode MyData.GetDataForJqGrid liefert die Daten aus der database. In der Demo verwende ich hauptsächlich den Code aus der Antwort , also verwende ich Entity Framework, um auf die database zuzugreifen:

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

wo die 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; } } } 

Der Code von Global.asax.cs ist

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

Auf der Client-Seite habe ich reine HTML-Seite verwendet , um größtenteils klar zu zeigen, dass Sie die Lösung in jedes beliebige Projekt inklusive Web-Formular-Projekt aufnehmen können. Die Seite hat den folgenden Code

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

Wo ist 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" }); });

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

AKTUALISIERT : Ich habe ein paar kleine Verbesserungen vorgenommen: inklusive json2.js (siehe hier ) um JSON.stringify in alten Webbrowsern zu unterstützen, festes Datumsformat im jQuery UI Datepicker und Unterstützung für DateType und DateType? ( System.Nullable ) in der class Filters . So können Sie die aktuelle Version des Projekts vom selben Ort herunterladen.