Sie sind auf Seite 1von 12

Luego de varios das de intenso trabajo, hoy he tomado un pequeo espacio de tiempo para dedicar un post al

trabajo con datos en forma de tablas en asp.net


Todos los que hemos trabajado desde hace bastante con asp.net, hemos aprendido a querer al GridView, un
excelente control que nos permite mostrar los datos directamente desde una base de datos y trabajar con
ellos, llamase trabajar a las operaciones de: editar, buscar, agregar y eliminar. Por supuesto que existen
muchas otras opciones que no son el objetivo de este post.
A pesar de que e GridView es una buena herramienta para trabajar, tiene un inconveniente, es un control que
funciona del lado del servidor, lo cual ocasiona un postback hacia el servidor, afectando muchas veces el
rendimiento y obligndonos a controlar los parpadeos de la pgina con controles adicionales.
As que, para evitarnos todo eso, hoy veremos como trabajar con jqGrid, un control basado en jquery para
realizar las operaciones bsicas (CRUD). La principal ventaja de trabajar con este control, es que, al ser creado
en jquery, es del lado del cliente, lo cual hace mucho mas eficiente y por supuesto, cuenta con opciones
adicionales que el gridview no posee.
Antes de continuar, debo recalcar que existe ya un control basado en jqGrid para asp.net, pero este tiene un
costo superior a $300 lo cual para muchos no es accesible, as que tendremos que trabajar con el control
opensource y hacer algunas adaptaciones.
Para todos aquellos que les gusta ver un ejemplo antes de sumergirse en un proceso de estos, les dejo la
pagina de demos
Demos jqgrid
Ahora s, es momento de empezar con nuestro control.
Descarga del control
Lo primero que requerimos para iniciar nuestro trabajo es descargar el control de la pgina oficial, en ella
pueden escoger cuales sern las funciones que desean descargar, generalmente recomiendo que las
descarguen todas.
Descarga jqgrid
Preparando el sitio
Una vez descargado abrimos Visual Studio seleccionamos Archivo>Nuevo>Sitio Web (en blanco sera mejor)
Ahora creamos una nueva carpeta y la llamamos js y ponemos en ella todos los scripts del jqgrid que
descargamos anteriormente.
Nuevamente creamos una nueva carpeta llamada css y de igual forma ponemos hay todos los archivos CSS y
las imgenes. Si en la descarga no estn incluidos los archivos css, no se preocupen, los encontrarn en el
archivo para descargar al final del post.
Con esto, ya estaramos listos para iniciar a codificar el control.
Creando el control
Para este primer acercamiento, veremos como implementar la funcionalidades bsicas. En otros post, veremos
como crear un maestro detalle y como utilizar un SubGrid.
Primer paso, agregar las referencias javascript a la pgina
1: <script type="text/javascript" src="js/jquery-1.5.2.min.js"></script>
2: <script type="text/javascript" src="js/grid.locale-es.js"></script>
3: <script type="text/javascript" src="js/jquery.jqGrid.min.js"></script>
4: <script type="text/javascript" src="js/grid.base.js"></script>
5: <script type="text/javascript" src="js/grid.common.js"></script>
6: <script type="text/javascript" src="js/grid.formedit.js"></script>
7: <script type="text/javascript" src="js/jquery.fmatter.js"></script>
8: <script type="text/javascript" src="js/jsonXml.js"></script>
9: <script type="text/javascript" src="js/jquery.tablednd.js"></script>
10: <script type="text/javascript" src="js/ui.multiselect.js"></script>
11: <script type="text/javascript" src="js/grid.inlinedit.js"></script>
12: <script type="text/javascript" src="js/jQDNR.js"></script>
13: <script type="text/javascript" src="js/jqModal.js"></script>
Si vemos las referencias, nicamente hemos agregado algunas, que sern las que nos brinden las
funcionalidades que requerimos para trabajar con las operaciones bsicas.
Una vez agregadas, crearemos una nueva funcin javascript en la cual codificaremos el jqgrid.
Si vemos la documentacinoriginal de jqGrid, veremos que jqgrid utiliza un atributo llamado colModel para
crear las columnas del grid y que su definicin es manual, es decir, se hace directamente en el control. Algo
as:
1: colNames:['ID Number','Notes'],
2: colModel:[
3: {name:'id',index:'id', width:90, sorttype:"int", editable: true},
4: {name:'note',index:'note', width:200, sortable:false,editable:
true,edittype:"textarea", editoptions:{rows:"2",cols:"10"}}
5: ],
Esto, a mi parecer es algo no muy agradable, porque simplemente obligara a tener que tocar cdigo sensible
del control cada vez que queramos mostrar informacin distinta. As que, me di a la tarea de crear una nueva
funcionalidad para el jqGrid que obtiene una serie de elementos desde un webservice va Json y los mete en
un array de jquery, de forma tal que podamos tener las columnas dinmicas. Este mtodo, lo ejecutare antes
de empezar la definicin del jqGrid, es decir antes de la lnea
1: $("#grid").jqGrid(
Nuestro nuevo mtodo luce as
1: //aca es modificacion
2: $.ajax({
3: dataType: "json",
4: type: "post",
5: url: "JqGridEjemplo.aspx/GetNames",
6: data: "{}",
7: contentType: "application/json;",
8: async: false, //esto es requerido, de otra forma el jqgrid se cargaria
antes que el grid
9: success: function (data) {
10: var cars = JSON.parse(data.d);
11: $.each(cars, function (index, car) {
12: colMode.push({ name: car.Name, index: car.index, width:
car.width, align: 'left', editable: true, editrules: { edithidden: true }, hidden: false });
13: })
14:
15: } //or
16:
17: }),
El mtodo anterior no tiene mucho especial que explicar:
1. Primero con el type=post hacemos referencia a la forma en que obtendremos los datos.
2.Con el data:{} le decimos al json que no vamos a enviarle parmetros
3. La url que direcciona al webservice
4. A la variable cars le asignamos el valor obtenido del Json
5. y Por ultimo con un each recorremos cada campo y lo metemos en el arreglo.
El cdigo del Jqgrid
Al igual que el procedimiento anterior, para el jqgri tenemos que especificar los tipos de datos, la url y en este
caso algunos parmetros que luego utilizaremos para traer los datos
1: $("#grid").jqGrid(
2: {
3: datatype: function () {
4: $.ajax(
5: {
6: url: "JqGridEjemplo.aspx/GetPersons", //PageMethod
7:
8: data: "{'pPageSize':'" + $('#grid').getGridParam("rowNum") +
9: "','pCurrentPage':'" + $('#grid').getGridParam("page") +
10: "','pSortColumn':'" + $('#grid').getGridParam("sortname") +
11: "','pSortOrder':'" + $('#grid').getGridParam("sortorder") + "'}",
//PageMethod Parametros de entrada
12:
13: dataType: "json",
14: type: "post",
15: contentType: "application/json; charset=utf-8",
16: complete: function (jsondata, stat) {
17: if (stat == "success")
18:
jQuery("#grid")[0].addJSONData(JSON.parse(jsondata.responseText).d);
19: else
20: alert(JSON.parse(jsondata.responseText).Message);
21: }
22: });
23: },
24: jsonReader: //Set the jsonReader to the JQGridJSonResponse squema to bind
the data.
25: {
26: root: "Items",
27: page: "CurrentPage",
28: total: "PageCount",
29: records: "RecordCount",
30: repeatitems: true,
31: cell: "Row",
32: id: "ID" //index of the column with the PK in it
33: },
Luego, establecemos las columnas utilizando el colmodel y algunos parmetros de configuracin de nuestro
grid
1: colModel: colMode,
2:
3: pager: "#pager", //Pager.
4: loadtext: 'Cargando datos...',
5: recordtext: "{0} - {1} de {2} elementos",
6: emptyrecords: 'No hay resultados',
7: pgtext: 'Pg: {0} de {1}', //Paging input control text format.
8: rowNum: "10", // PageSize.
9: rowList: [10, 20, 30], //Variable PageSize DropDownList.
10: viewrecords: true, //Show the RecordCount in the pager.
11: multiselect: true,
12: sortname: "Name", //Default SortColumn
13: sortorder: "asc", //Default SortOrder.
14: width: "800",
15: height: "230",
16: caption: "Personas",
17: ondblClickRow: function (id) {
18: gdCustomers.restoreRow(lastSel);
19: gdCustomers.editRow(id, true);
20: lastSel = id;
21: }
Jqgrid tiene la posibilidad de mostrar en su barra inferior las opciones de insert,delete, add, update y refresh,
as que las configuraremos de la siguiente manera
1: }).navGrid("#pager", { edit: true, add: true, search: true, del: true },
2: { url: "jqGridEjemplo.aspx/EditData", closeAfterEdit: true },
3: { url: "jqGridEjemplo.aspx/EditData", closeAfterAdd: true },
4: { url: "jqGridEjemplo.aspx/DeleteData" });
Ac vemos que al pager, le estamos diciendo que si vamos a permitir todas las opciones y adems, para cada
una de ellas estamos asignando una direccin en especifico, que de igual forma, apuntan a un procedimiento
en un webservice. Estas opciones son completamente configurables y por supuesto que bueno estar
deshabilitadas o no presentes por ahora, tenemos que colocarlas manualmente, luego trabajaremos en hacerlo
de forma dinmica.
Para concluir con la configuracin de nuestro jqgrid, necesitamos configurar las opciones de agregar y borrar
utilizando el mtodo jquery.extend, de otra forma aunque configuremos el jqgrid estas opciones nos
devolveran un error.
1: jQuery.extend(jQuery.jgrid.edit, {
2: ajaxEditOptions: { contentType: "application/json" },
3: recreateForm: true,
4: serializeEditData: function (postData) {
5: return JSON.stringify(postData);
6: }
7: });
8:
9: jQuery.extend(jQuery.jgrid.del, {
10: ajaxDelOptions: { contentType: "application/json" },
11: serializeDelData: function (postData) {
12:
13: return JSON.stringify(postData);
14: }
15: });
16:
17:
18:
19: });
Finalizando el cdigo completo seria
1: <script type="text/javascript">
2: var $table = $('#grid');
3: var lastSel;
4: var colMode = [];
5: jQuery(document).ready(function () {
6: //aca es modificacion
7: $.ajax({
8: dataType: "json",
9: type: "post",
10: url: "JqGridEjemplo.aspx/GetNames",
11: data: "{}",
12: contentType: "application/json;",
13: async: false, //esto es requerido, de otra forma el jqgrid se cargaria
antes que el grid
14: success: function (data) {
15: var cars = JSON.parse(data.d);
16: $.each(cars, function (index, car) {
17: colMode.push({ name: car.Name, index: car.index, width:
car.width, align: 'left', editable: true, editrules: { edithidden: true }, hidden: false });
18: })
19:
20: } //or
21:
22: }),
23: //ac
24: $("#grid").jqGrid(
25: {
26: datatype: function () {
27: $.ajax(
28: {
29: url: "JqGridEjemplo.aspx/GetPersons", //PageMethod
30:
31: data: "{'pPageSize':'" + $('#grid').getGridParam("rowNum") +
32: "','pCurrentPage':'" + $('#grid').getGridParam("page") +
33: "','pSortColumn':'" + $('#grid').getGridParam("sortname") +
34: "','pSortOrder':'" + $('#grid').getGridParam("sortorder") + "'}",
//PageMethod Parametros de entrada
35:
36: dataType: "json",
37: type: "post",
38: contentType: "application/json; charset=utf-8",
39: complete: function (jsondata, stat) {
40: if (stat == "success")
41:
jQuery("#grid")[0].addJSONData(JSON.parse(jsondata.responseText).d);
42: else
43: alert(JSON.parse(jsondata.responseText).Message);
44: }
45: });
46: },
47: jsonReader: //Set the jsonReader to the JQGridJSonResponse squema to bind
the data.
48: {
49: root: "Items",
50: page: "CurrentPage",
51: total: "PageCount",
52: records: "RecordCount",
53: repeatitems: true,
54: cell: "Row",
55: id: "ID" //index of the column with the PK in it
56: },
57:
58: colModel: colMode,
59:
60: pager: "#pager", //Pager.
61: loadtext: 'Cargando datos...',
62: recordtext: "{0} - {1} de {2} elementos",
63: emptyrecords: 'No hay resultados',
64: pgtext: 'Pg: {0} de {1}', //Paging input control text format.
65: rowNum: "10", // PageSize.
66: rowList: [10, 20, 30], //Variable PageSize DropDownList.
67: viewrecords: true, //Show the RecordCount in the pager.
68: multiselect: true,
69: sortname: "Name", //Default SortColumn
70: sortorder: "asc", //Default SortOrder.
71: width: "800",
72: height: "230",
73: caption: "Personas",
74: ondblClickRow: function (id) {
75: gdCustomers.restoreRow(lastSel);
76: gdCustomers.editRow(id, true);
77: lastSel = id;
78: }
79: }).navGrid("#pager", { edit: true, add: true, search: true, del: true },
80: { url: "jqGridEjemplo.aspx/EditData", closeAfterEdit: true },
81: { url: "jqGridEjemplo.aspx/EditData", closeAfterAdd: true },
82: { url: "jqGridEjemplo.aspx/DeleteData" });
83:
84:
85: jQuery.extend(jQuery.jgrid.edit, {
86: ajaxEditOptions: { contentType: "application/json" },
87: recreateForm: true,
88: serializeEditData: function (postData) {
89: return JSON.stringify(postData);
90: }
91: });
92:
93: jQuery.extend(jQuery.jgrid.del, {
94: ajaxDelOptions: { contentType: "application/json" },
95: serializeDelData: function (postData) {
96:
97: return JSON.stringify(postData);
98: }
99: });
100:
101:
102:
103: });
104:
105: </script>
Ahora que la configuracin el grid esta completa, es hora de trabajar el html donde se mostrarn los datos,
siendo tan sencillo como agregar una tabla y un div
1: <table id="grid">
2: </table>
3: <div id="pager">

Los datos a mostrar, los traeremos de SQL utilizando un procedimiento almacenado que luce asi
1: USE [JqGrid]
2: GO
3: /****** Object: StoredProcedure [dbo].[GetPersons] Script Date: 05/19/2011
13:29:50 ******/
4: SET ANSI_NULLS ON
5: GO
6: SET QUOTED_IDENTIFIER ON
7: GO
8:
9: -- GetPersons 3, 4, 'LastName', 'desc'
10:
11: ALTER procedure [dbo].[GetPersons]
12:
13: @PageSize int ,
14: @CurrentPage int ,
15: @SortColumn varchar(20),
16: @SortOrder varchar(4)
17:
18: as
19:
20: declare @RecordCount int
21: declare @PageCount int
22: declare @PageIndex int
23:
24: Select @RecordCount = count(ID)
25: from Person
26:
27: set @PageCount = Ceiling(cast (@RecordCount as float) / cast (@PageSize as float))
28:
29: if (@CurrentPage > @PageCount) set @CurrentPage = @PageCount
30:
31: set @PageIndex = @CurrentPage - 1
32:
33: Select RecordCount = @RecordCount, PageCount = @PageCount, CurrentPage = @CurrentPage
34:
35: declare @Query varchar(300)
36:
37: set @Query =
38: 'Select ID, Name, LastName, BirthDate, Weight,
39: RowNumber = ROW_NUMBER() OVER (ORDER BY ' + @SortColumn + ' ' + @SortOrder + ')
40: from Person'
41:
42: set @Query =
43: 'Select ID, Name, LastName, BirthDate, Weight
44: from (' + @Query + ' )as result
45: where RowNumber BETWEEN ' + cast(@PageSize * @PageIndex + 1 as varchar(10)) + '
46: AND ' + cast(@PageSize * (@PageIndex + 1) as varchar(10))
47:
48:
49: Exec (@Query)
Si observamos bien el Stored Procedure veremos que recibe algunos parmetros que estamos enviando por
Json cuando la url que carga los datos es activada.
El primer metodo que utilizaremos para cargar los datos con base en el stored procedure ser
1: internal static JQGridJsonResponse GetPersonasJSon(int pPageSize, int pPageNumber,
string pSortColumn, string pSortOrder)
2: {
3: SqlConnection sqlCon = new
SqlConnection(ConfigurationManager.ConnectionStrings["DataConnection"].ConnectionString);
4: SqlCommand command = new SqlCommand("GetPersons", sqlCon);
5: command.CommandType = CommandType.StoredProcedure;
6: command.Parameters.Add("PageSize", SqlDbType.Int).Value = pPageSize;
7: command.Parameters.Add("CurrentPage", SqlDbType.Int).Value = pPageNumber;
8: command.Parameters.Add("SortColumn", SqlDbType.VarChar, 20).Value =
pSortColumn;
9: command.Parameters.Add("SortOrder", SqlDbType.VarChar, 4).Value = pSortOrder;
10:
11: DataSet dataSet = new DataSet();
12: SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
13: dataAdapter.Fill(dataSet);
14:
15: var persons = new List<Person>();
16: foreach (DataRow row in dataSet.Tables[1].Rows)
17: {
18: Person person = new Person
19: {
20: ID = Convert.ToInt32(row["ID"]),
21: Name = row["Name"].ToString(),
22: LastName = row["LastName"].ToString(),
23: BirthDate = Convert.ToDateTime(row["BirthDate"]),
24: Weight = Convert.ToSingle(row["Weight"])
25: };
26: persons.Add(person);
27: }
28:
29: return new
JQGridJsonResponse(Convert.ToInt32(dataSet.Tables[0].Rows[0]["PageCount"]),
Convert.ToInt32(dataSet.Tables[0].Rows[0]["CurrentPage"]),
30: Convert.ToInt32(dataSet.Tables[0].Rows[0]["RecordCount"]), persons);
31: }
Sin embargo, este mtodo solo llena los datos, pero aun no los devuelve, eso lo haremos a travs de un
webservice de la siguiente forma
1: [WebMethod]
2: [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
3: public static JQGridJsonResponse GetPersons(int pPageSize, int pCurrentPage, string
pSortColumn, string pSortOrder)
4: {
5: return GetPersonasJSon(pPageSize, pCurrentPage, pSortColumn, pSortOrder);
6: }
Es importante que las lneas ResponseFormat=ResponseFormat.Json estn incluidas para que la
informacin que se envi sea codificada de la forma correcta.
Tambin debemos notar que ambos metodos hacen referencia a JQGridJsonResponse que es una clase
definida para almacenar los datos y llenar cada item
1: /// <summary>
2: /// Respuesta JSON para JQGrid.
3: /// </summary>
4: public class JQGridJsonResponse
5: {
6: #region Passive attributes.
7:
8: private int _pageCount;
9: private int _currentPage;
10: private int _recordCount;
11: private List<JQGridItem> _items;
12:
13: #endregion
14:
15: #region Properties
16:
17: /// <summary>
18: /// Cantidad de pginas del JQGrid.
19: /// </summary>
20: public int PageCount
21: {
22: get { return _pageCount; }
23: set { _pageCount = value; }
24: }
25: /// <summary>
26: /// Pgina actual del JQGrid.
27: /// </summary>
28: public int CurrentPage
29: {
30: get { return _currentPage; }
31: set { _currentPage = value; }
32: }
33: /// <summary>
34: /// Cantidad total de elementos de la lista.
35: /// </summary>
36: public int RecordCount
37: {
38: get { return _recordCount; }
39: set { _recordCount = value; }
40: }
41: /// <summary>
42: /// Lista de elementos del JQGrid.
43: /// </summary>
44: public List<JQGridItem> Items
45: {
46: get { return _items; }
47: set { _items = value; }
48: }
49:
50: #endregion
51:
52: #region Active attributes
53:
54: /// <summary>
55: /// Constructor.
56: /// </summary>
57: /// <param name="pItems">Lista de elementos a mostrar en el JQGrid</param>
58: public JQGridJsonResponse(int pPageCount, int pCurrentPage, int pRecordCount,
List<Person> pPersons)
59: {
60: _pageCount = pPageCount;
61: _currentPage = pCurrentPage;
62: _recordCount = pRecordCount;
63: _items = new List<JQGridItem>();
64: foreach (Person person in pPersons)
65: _items.Add(new JQGridItem(person.ID, new List <string> {
person.ID.ToString(),person.Name, person.LastName, person.BirthDate.ToShortDateString(),
person.Weight.ToString() }));
66: }
67:
68:
69:
70: #endregion
71: }
Pero, nuevamente debemos tener cuidado, ya que esta clase llama a otra clase que contiene los atributos del
grid llamada JQGridItem
1:
2: /// <summary>
3: /// Item del JQGrid. Elemento de la propiedad Items de la clase JsonJQGridResponse.
4: /// </summary>
5: public class JQGridItem
6: {
7: #region Passive attributes
8:
9: private long _id;
10: private List<string> _row;
11:
12: #endregion
13:
14: #region Properties
15:
16: /// <summary>
17: /// RowId de la fila.
18: /// </summary>
19: public long ID
20: {
21: get { return _id; }
22: set { _id = value; }
23: }
24: /// <summary>
25: /// Fila del JQGrid.
26: /// </summary>
27: public List<string> Row
28: {
29: get { return _row; }
30: set { _row = value; }
31: }
32:
33: #endregion
34:
35: #region Active Attributes
36:
37: /// <summary>
38: /// Contructor.
39: /// </summary>
40: public JQGridItem(long pId, List<string> pRow)
41: {
42: _id = pId;
43: _row = pRow;
44: }
45:
46: #endregion
47: }
Con esto, nuestro jqGrid sera totalmente funcional para mostrar los datos, paginar y ordenar pero an no lo
es para guardar, editar o borrar.
Estos mtodo al igual que los anteriores, sern definidos en un webservice y sern ms sencillos de utilizar
pues bsicamente reciben los datos mediante Json y lo dems se traduce en cdigo que ya conocemos.
1: [WebMethod]
2: [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
3: public static void DeleteData(string id,string oper)
4: {
5:
6: if (String.Compare(oper, "del", StringComparison.Ordinal) == 0)
7: {
8: using (SqlConnection conn = new
SqlConnection(ConfigurationManager.ConnectionStrings["DataConnection"].ConnectionString))
9: {
10: using (SqlCommand command = new SqlCommand("delete from person where
id=@id", conn))
11: {
12: conn.Open();
13: command.Parameters.AddWithValue("@id", id);
14: command.ExecuteNonQuery();
15: }
16: }
17:
18:
19:
20: }
21:
22: }
1: [WebMethod]
2: [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
3: public static void EditData(string BirthDate, string LastName, string Name, string
Weight, string id, string oper)
4: {
5: if (String.Compare(id, "_empty", StringComparison.Ordinal) == 0 ||
6: String.Compare(oper, "add", StringComparison.Ordinal) == 0)
7: {
8:
9: using (SqlConnection conn = new
SqlConnection(ConfigurationManager.ConnectionStrings["DataConnection"].ConnectionString))
10: {
11: using (SqlCommand command = new SqlCommand("insert into person
(name,lastname,birthdate,weight)values(@name,@lname,@date,@peso)", conn))
12: {
13: conn.Open();
14: command.Parameters.AddWithValue("@id", id);
15: command.Parameters.AddWithValue("@name", Name);
16: command.Parameters.AddWithValue("@lname", LastName);
17: command.Parameters.AddWithValue("@date",
Convert.ToDateTime(BirthDate));
18: command.Parameters.AddWithValue("@peso", double.Parse(Weight));
19: command.ExecuteNonQuery();
20: }
21: }
22:
23: }
24: else if (String.Compare(oper, "edit", StringComparison.Ordinal) == 0)
25: {
26: using (SqlConnection conn = new
SqlConnection(ConfigurationManager.ConnectionStrings["DataConnection"].ConnectionString))
27: {
28: using (SqlCommand command = new SqlCommand("update person set
name=@name,lastname=@lname,birthdate=@date,weight=@peso where id=@id", conn))
29: {
30: conn.Open();
31: command.Parameters.AddWithValue("@id", id);
32: command.Parameters.AddWithValue("@name", Name);
33: command.Parameters.AddWithValue("@lname", LastName);
34: command.Parameters.AddWithValue("@date",
Convert.ToDateTime(BirthDate));
35: command.Parameters.AddWithValue("@peso", double.Parse(Weight));
36: command.ExecuteNonQuery();
37: }
38: }
39: }
40:
41:
42: }

Finalmente as se ver el trabajo

Ejemplo de descarga

Das könnte Ihnen auch gefallen