ASP.NET MVC 2.0 Implementación de la búsqueda en jqgrid

Hola, estoy tratando de usar la búsqueda de una sola columna en jqgrid usando MVC 2 IN .NET (VS 2008) este es el código que tengo hasta ahora, pero necesito un ejemplo para unirlo o una pista de lo que me falta

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

dos cosas no están apareciendo y buscar aunque tengo la ventana de búsqueda abriendo con solo la columna 1 como una opción y cuando hago clic en el hallazgo parece que carga la grilla pero en realidad no coincide con mi valor que escribo en el cuadro de texto.

ACTUALIZADO: como puedes ver hice un bash con el argumento de SERA que no tuvo éxito gracias de nuevo por tu ayuda, se aprecia

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

Probablemente tengas problemas en el lado del servidor. ¿Podría agregar su pregunta al código de la acción DynamicGridData que usa actualmente? La acción debe tener filters como parámetro.

Algunas partes de su código actual son definitivamente incorrectas. Por ejemplo, jqGrid es el complemento jQuery. Entonces, los métodos de jQuery se extenderán con el método principal jqGrid que se usa como jQuery("#list").jqGrid(...); . Entonces, después de la inicialización de jqGrid jQuery("#list").jqGrid será una función. En su código (la última statement) sobrescribe el método jQuery("#list").jqGrid con el objeto { search: { ... } } . Lo que debes hacer es en cambio

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

como por ejemplo aquí se describe cómo sobrescribir el valor predeterminado de los valores de emptyrecords . No es necesario que incluya los valores que ya son los mismos en la configuración jqGrid predeterminada.

Además, si usa las searchoptions: { sopt: ['eq', 'ne', 'cn']} en todas las columnas de búsqueda, no necesita hacer el cambio.

En el texto de tu pregunta, no explicas lo que quieres hacer. Su código actual es para que use el filtro Message igual a true en la carga de la grilla inicial. Extraño es que no hay una columna con el nombre Message en la grilla. Si solo desea enviar información adicional al servidor, debería usar el parámetro postData :

 postData: {Message:true} 

Sigo recomendando eliminar basura de la definición de imgpath como multipleSearch parámetros imgpath y multipleSearch de jqGrid y ordenar sortable: true, search: true, sorttype: 'text', autoFit: true, stype:'text', align: 'left' que son desconocidos o predeterminados

ACTUALIZADO : El código original de la demo de Phil Haack es muy antiguo y usa LINQ to SQL. Como escribí antes (ver aquí ), Entity Framework (EF) permite usar clasificación, paginación y filtrado / búsqueda sin AddOns como LINQ Dynamic Query Library en el formulario System.Linq.Dynamic . Así que hice la demostración tu que es la modificación de la demo de Phil Haack a EF.

Debido a que utiliza la versión anterior de Visual Studio (VS2008 con ASP.NET MVC 2.0) también hice la demostración en VS2008.

Puede descargar mi demostración VS2008 desde aquí y la demostración VS2010 aquí .

En el código que muestro (además del uso de Búsqueda avanzada y búsqueda de barra de herramientas en ASP.NET MVC 2.0) cómo devolver información de excepción de ASP.NET MVC en formato JSON y cómo capturar la información con el método loadError y mostrar el correspondiente mensaje de error.

Para construir la instrucción Where del objeto EF representado en ObjectQuery , defino la siguiente clase de ayuda:

 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 ('%'+@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 (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; } } 

En el ejemplo, utilizo solo dos tipos de datos integer ( Edm.Int32 ) y string ( Edm.String ). Puede expandir fácilmente el ejemplo para usar más tipos basados ​​en el valor de propertyInfo.PropertyType.FullName .

La acción del controlador que proporciona los datos a jqGrid será bastante simple:

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

Para enviar la información de la excepción al jqGrid en formato JSON, reemplacé el atributo [HandleError] estándar del controlador ( HomeController ) por el [HandleJsonException] que [HandleJsonException] como el siguiente:

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

En el lado del cliente, utilicé el siguiente código 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(); } });

Como resultado, si se escribe un texto no numérico (como ‘ttt’) en la barra de herramientas de búsqueda, se recibe una excepción del código de acción del controlador (en Int32.Parse(rule.data) ). Uno del lado del cliente verá el siguiente mensaje:

enter image description here

Envío desde el controlador a jqgrid la información sobre todas las excepciones internas. Entonces, por ejemplo, el error en la conexión al servidor SQL se verá como

enter image description here

En el mundo real uno verifica la entrada de los usuarios y arroja una excepción con un mensaje de error orientado a la aplicación. Usé en la demostración especialmente ningún tipo de validación para mostrar que todo tipo de excepción será almacenada en caché y mostrada por jqGrid.

ACTUALIZADO 2 : en la respuesta encontrará la demo VS2010 modificada (descargable desde aquí ) que demuestra el uso de Autocompletar de la interfaz de usuario jQuery. Otra respuesta extender el código más para exportar la cuadrícula contener en formato Excel.

Mira los enlaces a continuación:

  • jqGrid y ASP.NET MVC – Búsqueda <- ASP.NET MVC LinqToSql
  • jqGrid en ASP.NET MVC 3 y Razor <- muchas muestras, ASP.NET MVC 3, Razor
  • jqGrid en ASP.NET MVC – Helper fuertemente tipado <- muestras idénticas a las anteriores, pero con helper fuertemente tipado y Entity Framework Code-First

He intentado con un argumento de búsqueda que no tuvo éxito

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

devolver Json (jsonData); }

Es mucho más fácil de lo que piensas para la búsqueda en el servidor. Sus índices en su grilla aparecerán en la llamada json como argumentos. También hay un parámetro en el argumento GridSettings que se establecerá en verdadero si es una búsqueda. Se llama IsSearch. También hay un orden y columna en el argumento GridSettings que te ayudará a construir dy

Entonces, tendrías algo como esto …

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