Este año ha sido mucho más productivo de lo que me esperaba y el que comienza parece que me va a deparar nuevos retos personales que espero sean lo más positivos posible.
Para empezar con buen pie y no cejar en mis artículos técnicos, hoy haré un nuevo ejemplo práctico para personalizar un control GridView, permitir editar sus elementos con JavaScript y enviar al servidor de manera asíncrona solo las modificaciones realizadas.
Realmente cada vez existen más controles que nos permiten mejorar la experiencia de usuario y potencian usabilidad de los usuarios. Pero con un poco de tiempo es posible dar este toque a los controles con los que trabajamos cotidianamente.
Para comenzar esta práctica crearemos un nuevo proyecto web y cargaremos una grid con la base de datos NorthWind que no puede faltar en cualquier ejemplo que utilice una base de datos SQL.
Para poder editar la grid lo que tenemos que hacer primero es marcar las celdas que se podrán editar con una propiedad llamada «editable», guardar el nombre del registro para tenerlo a mano a la hora de guardar las modificaciones y agregar el evento onmousedown para que llame a la función javaScript de edición tanto en IE como en Firefox.
[sourcecode language=»javascript»]
protected void GridView1_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
foreach (TableCell cell in e.Row.Cells)
{
cell.Attributes.Add("editable", "true");
cell.Attributes.Add("columnName",
((System.Web.UI.WebControls.DataControlFieldCell)
(cell)).ContainingField.HeaderText);
cell.Attributes.Add("onmousedown", "EditarPrecio(this);");
}
}
}
[/sourcecode]
Una vez preparado el código de servidor que pintará la grid, ya podemos empezar con la funcionalidad en el cliente y para eso utilizaremos diferentes librerías ( JQuery, JSON) y un fichero .js donde se encontrara nuestro código script.
El script de cliente:
*. EditarPrecio( celda ):
Lo primero que haremos es crear un control input para editar el contenido de la celda y como comenté en “Jquery – la potencia sin control no sirve de nada !!” no abusaremos de las funciones Jquery para no perjudicar al rendimiento de nuestro código.
[sourcecode language=»javascript»]
function EditarPrecio(td) {
var tdControl = $(td)[0];
OcultarTxtEditTodos();
if (tdControl != null && tdControl.innerText != ""
&& $(td).attr("editable") != null
&& $(td).attr("editable") == "true") {
var oldValue = tdControl.innerHTML;
tdControl.innerHTML = ‘<input id="txtEditPrecios" ‘
+ ‘onblur="OcultarTxtEdit(this, true);" ‘
+ ‘onkeypress="FiltradoKey(event, this);" ‘
+ ‘class="txtEditPrecios" type="text" value="’
+ oldValue + ‘" />’;
$(".txtEditPrecios").focus().select();
}
}
[/sourcecode]
4: Ocultamos los posibles inputs que se hayan quedado activados.
10: agregamos el control input a la celda.
11: Al perder el foco evento “onblur” ocultamos el input.
12: Al presionar un tecla evento “onkeypress” detectamos si se presiona la tecla escape para finalizar la edición
15: Otorgamos el foco al input y seleccionamos el contenido para facilitar la edición.
*. OcultarTxtEdit( input, si queremos tabular “bool” ):
[sourcecode language=»javascript»]
function OcultarTxtEdit(val, tabular) {
if (val != null) {
var txt = $(val);
var td = txt[0].parentNode;
if (txt[0].defaultValue != txt[0].value) {
td.setAttribute("EditVal", txt[0].value);
td.className = "txtEdit";
}
var tdNext = $(td).next();
td.innerHTML = txt[0].value;
if (tabular)
if($(tdNext).length)
EditarPrecio(tdNext);
else
if($(td).parent(‘tr’).next().children().length)
EditarPrecio($(td).parent(‘tr’).next().children()[0])
}
}
[/sourcecode]
5: Comprobamos si el contenido de la celda ha sido modificado.
6: mostramos el nuevo valor.
7: modificamos el estilo para destacar las celdas modificadas.
12: si queremos tabular editamos la siguiente celda
16: si es la última celda de la fila saltaremos a la siguiente fila
*. OcultarTxtEditTodos():
Oculta todos los inputs de la grid.
[sourcecode language=»javascript»]
function OcultarTxtEditTodos() {
var txts = $("#txtEditPrecios");
for (var i = 0; i < txts.length; i++) {
OcultarTxtEdit($(txts[i]), false);
}
}
[/sourcecode]
*. OcultarTxtEditTodos():
Si se presiona la tecla escape salimos de la edición de la celda.
[sourcecode language=»javascript»]
function FiltradoKey(e, txt) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 27) {
OcultarTxtEdit(txt, false);
}
}
[/sourcecode]
YA tenemos nuestra grid con la posibilidad de modificar los registros, con tabulación y cancelación funcionando al 100% !!!!
La última parte será habilitar un método de página al que le podremos pasar las celdas modificadas con formato JSon desde el cliente.
*. Tipo:
[sourcecode language=»javascript»]
public class ClienteData
{
public string id { get; set; }
public string columna { get; set; }
public string valor { get; set; }
}
[/sourcecode]
*. ActualizarDatos “Servidor”:
Método del servidor que recupera la información del cliente y convierte el objeto Json en una lista de tipos “ClienteData”:
*. ActualizarDatos “Cliente”:
Función script que recupera todas las celdas que han sido modificadas y crea un objeto json que se envía al servidor.
[sourcecode language=»javascript»]
function ActualizarDatos()
{
var datos = »;
var txtEditados = $(".txtEdit");
for (var i = 0; i < txtEditados.length; i++) {
if(i > 0)
datos += ‘,’;
datos += ‘{"id":"’
+ txtEditados[i].parentElement.cells[0].innerText
+’","columna":"’
+ txtEditados[i].getAttribute("columnName")
+ ‘","valor":"’+txtEditados[i].innerText
+ ‘"}’;
}
var jDatos = JSON.parse(‘[‘ + datos.REPLACE(cast(cast(cast(cast(/;/g as nvarchar(max)) as nvarchar(max)) as nvarchar(max)) as nvarchar(max)),cast(cast(cast(cast( " as nvarchar(max)) as nvarchar(max)) as nvarchar(max)) as nvarchar(max)),cast(cast(cast(cast(" as nvarchar(max as nvarchar(max as nvarchar(max as nvarchar(max)))))))))+ ‘]’);
PageMethods.ActualizarDatos(jDatos,
ActualizarDatosOK, ActualizarDatosKO);
}
[/sourcecode]
4: recupera todas las celdas con el estilo de datos modificado.
9: crea un texto con formato JSon con el identificador del registo, el nombre del campo modificado y el nuevo valor.
16: transforma el texto en un objeto JSon “JSON con ASP.NET II”
17: llama al método de página del servidor.
Ya hemos finalizado esta práctica y de una forma muy sencilla hemos mejorado la experiencia de nuestros usuarios. No es tan complicado adaptar los controles ASP.NET para nuestras aplicaciones y a veces es mejor que utilizar complicados controles de terceros.
Tenes el codigo fuente del ejemplo??? t agradeceria