ASP.NET MVC 2.0 Implementazione della ricerca in jqgrid

Ciao Sto cercando di usare la ricerca a colonna singola in jqgrid usando MVC 2 IN. NET (VS 2008) questo è il codice che ho finora ma ho bisogno di un esempio per abbinarlo o un suggerimento di ciò che mi manca

jQuery("#list").jqGrid({ url: '/Home/DynamicGridData/', datatype: 'json', mtype: 'POST', search: true, filters: { "groupOp":"AND", "rules": [ {"field":"Message","op":"eq","data":"True"} ] }, multipleSearch: false, colNames: [ 'column1', 'column2'], colModel: [ { name: 'column1', index: 'column1', sortable: true, search: true, sorttype: 'text', autoFit: true,stype:'text', searchoptions: { sopt: ['eq', 'ne', 'cn']} }, { name: 'column2', index: 'column2', sortable: true,search: false, sorttype: 'text', align: 'left', autoFit: true}], pager: jQuery('#pager'), rowNum: 10, rowList: [10, 60, 100], scroll: true, sortname: 'column2', sortorder: 'asc', gridview: true, autowidth: true, rownumbers: true, viewrecords: true, imgpath: '/scripts/themes/basic/images', caption: 'my data grid' }); jQuery("#list").jqGrid('navGrid', '#pager', {add: false, edit: false, del: false}, {}, {}, {}, { multipleSearch: true, overlay: false }); //jQuery("#list").jqGrid('filterToolbar', {stringResult:true, searchOnEnter:true}); jQuery("#list").jqGrid('navButtonAdd', '#pager', { caption: "Finding", title: "Toggle Search Bar", buttonicon: 'ui-icon-pin-s', onClickButton: function() { $("#list")[0].toggleToolbar() } }); jQuery("#list").jqGrid = { search : { caption: "Search...", Find: "Find", Reset: "Reset", odata : ['equal', 'not equal','contains'], groupOps: [ { op: "AND", text: "all" }, { op: "OR", text: "any" } ], matchText: " match", rulesText: " rules" } } }); 

due cose sul cercapersone non stanno arrivando e la ricerca anche se ho la finestra di ricerca che si apre con solo hte column1 come opzione e quando si fa clic sul find sembra che carichi la griglia ma in realtà senza corrispondere al mio valore che scrivo nella casella di testo.

AGGIORNATO: come puoi vedere ho fatto un tentativo con l’argomento serach che non ha avuto successo grazie ancora per il tuo aiuto è apprezzato

 //public ActionResult DynamicGridData(string sidx, string sord, int page, int rows,bool search, string fieldname,string fieldvalue) public ActionResult DynamicGridData(string sidx, string sord, int page, int rows) { var context = new AlertsManagementDataContext(); int pageIndex = Convert.ToInt32(page) - 1; int pageSize = rows; int totalRecords = context.Alerts.Count(); int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize); IQueryable alerts = null; try { //if (!search) //{ alerts = context.Alerts. OrderBy(sidx + " " + sord). Skip(pageIndex * pageSize). Take(pageSize); //} //else //{ // alerts = context.Alerts.Where (fieldname +"='"+ fieldvalue +"'"). // Skip(pageIndex * pageSize). // Take(pageSize); //} } catch (ParseException ex) { Response.Write(ex.Position + " " + ex.Message + " " + ex.Data.ToString()); } //var alerts = // from a in context.Alerts // orderby sidx ascending // select a; var jsonData = new { total = totalPages, page = page, records = totalRecords, rows = ( from alert in alerts select new { id = alert.AlertId, cell = new string[] { "Edit " +"|"+ "Detail ", alert.AlertId.ToString() , alert.Policy.Name , alert.PolicyRule , alert.AlertStatus.Status , alert.Code.ToString() , alert.Message , alert.Category.Name} }).ToArray() }; return Json(jsonData); } 

Probabilmente hai problemi sul lato server. Potresti aggiungere la tua domanda con il codice dell’azione DynamicGridData che usi attualmente. L’azione dovrebbe avere filters come parametro.

Alcune parti del tuo codice attuale sono definitivamente errate. Ad esempio, jqGrid è il plugin jQuery. Quindi i metodi di jQuery verranno estesi con il metodo jqGrid principale che si usa come jQuery("#list").jqGrid(...); . Quindi dopo l’inizializzazione di jqGrid jQuery("#list").jqGrid sarà una funzione. Nel codice utente (l’ultima istruzione) si sovrascrive il jQuery("#list").jqGrid Metodo jQuery("#list").jqGrid con l’object { search: { ... } } . Quello che dovresti fare invece è

 jQuery.extend(jQuery.jgrid.search, { odata : ['equal', 'not equal','contains'] }); 

come per esempio qui viene descritto come sovrascrivere il valore predefinito di emptyrecords . Non è necessario includere i valori che sono già gli stessi nelle impostazioni predefinite di jqGrid.

Inoltre se usi searchoptions: { sopt: ['eq', 'ne', 'cn']} su tutte le colonne ricercabili non hai bisogno di fare la modifica.

Nel testo della tua domanda non hai spiegato cosa vuoi fare. Il tuo codice attuale è in modo che tu usi il Message filter a true al caricamento iniziale della griglia. Strano è che non ci sono colonne con il nome Message nella griglia. Se vuoi solo inviare alcune informazioni aggiuntive al server, dovresti usare meglio il parametro postData :

 postData: {Message:true} 

Continuo a raccomandarti di rimuovere i rifiuti dalla definizione jqGrid come imgpath e parametri multipleSearch di jqGrid e sortable: true, search: true, sorttype: 'text', autoFit: true, stype:'text', align: 'left' che sono sconosciuti o predefiniti.

AGGIORNATO : Il codice originale della demo di Phil Haack è molto vecchio e utilizza LINQ to SQL. Come ho scritto prima (vedi qui ) Entity Framework (EF) consente di utilizzare l’ordinamento, il paging e il filtraggio / ricerca senza AddOn come LINQ Dynamic Query Library in forma System.Linq.Dynamic . Così ti ho reso la tua demo che modifica la demo di Phil Haack in EF.

Poiché si utilizza la versione precedente di Visual Studio (VS2008 con ASP.NET MVC 2.0) ho realizzato la demo anche in VS2008.

È ansible scaricare la demo VS2008 da qui e la demo VS2010 qui .

Nel codice che mostro (oltre all’utilizzo di Ricerca avanzata e Ricerca barra degli strumenti in ASP.NET MVC 2.0) come restituire le informazioni sulle eccezioni da ASP.NET MVC in formato JSON e come catturare le informazioni con il metodo loadError e visualizzare il corrispondente messaggio di errore.

Per build l’istruzione Where dall’object EF rappresentato da ObjectQuery, definisco la seguente class helper:

 public class Filters { 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; } 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 ('%'[email protected]{1}))", // "ew" - ends with "(it.{0} NOT LIKE ('%'[email protected]{1}))", // "en" - does not end with "(it.{0} LIKE ('%'[email protected]{1}+'%'))", // "cn" - contains "(it.{0} NOT LIKE ('%'[email protected]{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 (Rule rule in rules) { PropertyInfo 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); // TODO: Extend to other data types objParams.Add(String.Compare(propertyInfo.PropertyType.FullName, "System.Int32", StringComparison.Ordinal) == 0 ? new ObjectParameter("p" + iParam, Int32.Parse(rule.data)) : new ObjectParameter("p" + iParam, rule.data)); } ObjectQuery filteredQuery = inputQuery.Where (sb.ToString ()); foreach (var objParam in objParams) filteredQuery.Parameters.Add (objParam); return filteredQuery; } } 

Nell’esempio utilizzo solo due integer dati integer ( Edm.Int32 ) e string ( Edm.String ). È ansible espandere facilmente l’esempio per utilizzare più tipi basati come sopra sul valore propertyInfo.PropertyType.FullName .

L’azione del controller che fornisce i dati a jqGrid sarà piuttosto semplice:

 public JsonResult DynamicGridData(string sidx, string sord, int page, int rows, bool _search, string filters) { var context = new HaackOverflowEntities(); var serializer = new JavaScriptSerializer(); Filters f = (!_search || string.IsNullOrEmpty (filters)) ? null : serializer.Deserialize (filters); ObjectQuery filteredQuery = (f == null ? context.Questions : f.FilterObjectSet (context.Questions)); filteredQuery.MergeOption = MergeOption.NoTracking; // we don't want to update the data var totalRecords = filteredQuery.Count(); var pagedQuery = filteredQuery.Skip ("it." + sidx + " " + sord, "@skip", new ObjectParameter ("skip", (page - 1) * rows)) .Top ("@limit", new ObjectParameter ("limit", rows)); // to be able to use ToString() below which is NOT exist in the LINQ to Entity var queryDetails = (from item in pagedQuery select new { item.Id, item.Votes, item.Title }).ToList(); return Json(new { total = (totalRecords + rows - 1) / rows, page, records = totalRecords, rows = (from item in queryDetails select new[] { item.Id.ToString(), item.Votes.ToString(), item.Title }).ToList() }); } 

Per inviare le informazioni sull’eccezione a jqGrid nel modulo JSON ho sostituito l’attributo [HandleError] standard del controller ( HomeController ) per [HandleJsonException] che ho definito come segue:

 // to send exceptions as json we define [HandleJsonException] attribute public class ExceptionInformation { public string Message { get; set; } public string Source { get; set; } public string StackTrace { get; set; } } public class HandleJsonExceptionAttribute : ActionFilterAttribute { // next class example are modification of the example from // the http://www.dotnetcurry.com/ShowArticle.aspx?ID=496 public override void OnActionExecuted(ActionExecutedContext filterContext) { if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null) { filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError; var exInfo = new List(); for (Exception ex = filterContext.Exception; ex != null; ex = ex.InnerException) { PropertyInfo propertyInfo = ex.GetType().GetProperty ("ErrorCode"); exInfo.Add(new ExceptionInformation() { Message = ex.Message, Source = ex.Source, StackTrace = ex.StackTrace }); } filterContext.Result = new JsonResult() {Data=exInfo}; filterContext.ExceptionHandled = true; } } } 

Sul lato client ho usato il seguente codice JavaScript:

 var myGrid = $('#list'), decodeErrorMessage = function(jqXHR, textStatus, errorThrown) { var html, errorInfo, i, errorText = textStatus + '\n' + errorThrown; if (jqXHR.responseText.charAt(0) === '[') { try { errorInfo = $.parseJSON(jqXHR.responseText); errorText = ""; for (i=0; i([\s\S]*)<\/body>/.exec(jqXHR.responseText); if (html !== null && html.length > 1) { errorText = html[1]; } } return errorText; }; myGrid.jqGrid({ url: '<%= Url.Action("DynamicGridData") %>', datatype: 'json', mtype: 'POST', colNames: ['Id', 'Votes', 'Title'], colModel: [ { name: 'Id', index: 'Id', key: true, width: 40, searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'] } }, { name: 'Votes', index: 'Votes', width: 40, searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'] } }, { name: 'Title', index: 'Title', width: 400, searchoptions: { sopt: ['cn', 'nc', 'bw', 'bn', 'eq', 'ne', 'ew', 'en', 'lt', 'le', 'gt', 'ge'] } } ], pager: '#pager', rowNum: 10, rowList: [5, 10, 20, 50], sortname: 'Id', sortorder: 'desc', rownumbers: true, viewrecords: true, altRows: true, altclass: 'myAltRowClass', height: '100%', jsonReader: { cell: "" }, caption: 'My first grid', loadError: function(jqXHR, textStatus, errorThrown) { // remove error div if exist $('#' + this.id + '_err').remove(); // insert div with the error description before the grid myGrid.closest('div.ui-jqgrid').before( '
' + decodeErrorMessage(jqXHR, textStatus, errorThrown) + '
') }, loadComplete: function() { // remove error div if exist $('#' + this.id + '_err').remove(); } }); myGrid.jqGrid('navGrid', '#pager', { add: false, edit: false, del: false }, {}, {}, {}, { multipleSearch: true, overlay: false }); myGrid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: true, defaultSearch: 'cn' }); myGrid.jqGrid('navButtonAdd', '#pager', { caption: "Filter", title: "Toggle Searching Toolbar", buttonicon: 'ui-icon-pin-s', onClickButton: function() { myGrid[0].toggleToolbar(); } });

Come risultato, se si digita un testo non numerico (come ‘ttt’) nella barra degli strumenti di ricerca si riceve un’eccezione sul codice di azione del controller (in Int32.Parse(rule.data) ). Uno sul lato client vedrà il seguente messaggio:

inserisci la descrizione dell'immagine qui

Invio dal controller a jqgrid le informazioni su tutte le eccezioni interne. Ad esempio, l’errore in connessione al server SQL sarà simile

inserisci la descrizione dell'immagine qui

Nel mondo reale si verifica l’input degli utenti e si genera un’eccezione con un messaggio di errore orientato all’applicazione. Ho usato nella demo appositamente per questo tipo di convalida per dimostrare che tutti i tipi di eccezione saranno memorizzati nella cache e visualizzati da jqGrid.

AGGIORNATO 2 : Nella risposta troverai la demo VS2010 modificata (scaricabile da qui ) che dimostra l’utilizzo del completamento automatico dell’interfaccia utente jQuery. Un’altra risposta estendere il codice più per esportare la griglia contenere in formato Excel.

Controlla sotto i link:

  • jqGrid e ASP.NET MVC – Ricerca <- ASP.NET MVC LinqToSql
  • jqGrid in ASP.NET MVC 3 e Razor <- lotto di campioni, ASP.NET MVC 3, Rasoio
  • jqGrid in ASP.NET MVC – Helper fortemente tipizzato <- stessi campioni come sopra ma con helper fortemente tipizzato e Entity Framework Code-First

Ho fatto un tentativo con argomento di ricerca che non ha avuto successo

 public ActionResult DynamicGridData(string sidx, string sord, int page, int rows) { var context = new AlertsManagementDataContext(); int pageIndex = Convert.ToInt32(page) - 1; int pageSize = rows; int totalRecords = context.Alerts.Count(); int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize); IQueryable alerts = null; try { //if (!search) // { alerts = context.Alerts. OrderBy(sidx + " " + sord). Skip(pageIndex * pageSize). Take(pageSize); // } //else // { // alerts = context.Alerts.Where (fieldname +"='"+ fieldvalue +"'"). // Skip(pageIndex * pageSize). // Take(pageSize); // } } catch (ParseException ex) { Response.Write(ex.Position + " " + ex.Message + " " + ex.Data.ToString()); } //var alerts = // from a in context.Alerts // orderby sidx ascending // select a; var jsonData = new { total = totalPages, page = page, records = totalRecords, rows = ( from alert in alerts select new { id = alert.AlertId, cell = new string[] { "Edit " +"|"+ "Detail ", alert.AlertId.ToString() , alert.Policy.Name , alert.PolicyRule , alert.AlertStatus.Status , alert.Code.ToString() , alert.Message , alert.Category.Name} }).ToArray() }; 

return Json (jsonData); }

È molto più facile di quanto pensi per la ricerca lato server. I tuoi indici nella tua griglia si imbatteranno nella chiamata JSON come argomenti. Inoltre c’è un parametro nell’argomento GridSettings che verrà impostato su true se si tratta di una ricerca. Si chiama IsSearch. C’è anche un ordinamento e una colonna nell’argomento GridSettings che ti aiuteranno a build dy

Quindi, avresti qualcosa di simile ..

 public JsonResult GetUsers(GridSettings gridSettings, string FirstName, string LastName) { // conditional logic and queries here and return results) }