GridView Custom Edit

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.

gridedit

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.

  1: protected void GridView1_RowDataBound(object sender, 
  2:    GridViewRowEventArgs e)
  3: {
  4:    if (e.Row.RowType == DataControlRowType.DataRow)
  5:    {
  6:       foreach (TableCell cell in e.Row.Cells)
  7:       {
  8:          cell.Attributes.Add("editable", "true");
  9:          cell.Attributes.Add("columnName", 
 10:            ((System.Web.UI.WebControls.DataControlFieldCell)
 11:               (cell)).ContainingField.HeaderText);
 12:          cell.Attributes.Add("onmousedown", "EditarPrecio(this);");
 13:       }
 14:    }
 15:  }

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.

grideditCel

  1: function EditarPrecio(td) {
  2:     
  3:     var tdControl = $(td)[0];
  4:     OcultarTxtEditTodos();
  5: 
  6:     if (tdControl != null && tdControl.innerText != "" 
  7:        && $(td).attr("editable") != null 
  8:        && $(td).attr("editable") == "true") {
  9:         var oldValue = tdControl.innerHTML;
 10:         tdControl.innerHTML = '<input id="txtEditPrecios" '
 11:            + 'onblur="OcultarTxtEdit(this, true);" '
 12:            + 'onkeypress="FiltradoKey(event, this);" '
 13:            + 'class="txtEditPrecios" type="text" value="' 
 14:            + oldValue + '" />';
 15:         $(".txtEditPrecios").focus().select();     
 16:     }
 17: }

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” ):

 

  1: function OcultarTxtEdit(val, tabular) {
  2:     if (val != null) {
  3:         var txt = $(val);
  4:         var td = txt[0].parentNode;
  5:         if (txt[0].defaultValue != txt[0].value) {
  6:             td.setAttribute("EditVal", txt[0].value);
  7:             td.className = "txtEdit";
  8:         }
  9:         var tdNext = $(td).next();
 10:         td.innerHTML = txt[0].value;
 11: 
 12:         if (tabular)
 13:             if($(tdNext).length)
 14:                EditarPrecio(tdNext);
 15:             else
 16:                 if($(td).parent('tr').next().children().length)
 17:                 EditarPrecio($(td).parent('tr').next().children()[0])
 18:     }
 19: }

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

grideditCel2

*. OcultarTxtEditTodos():

Oculta todos los inputs de la grid.

  1: function OcultarTxtEditTodos() {
  2:     var txts = $("#txtEditPrecios");
  3:     for (var i = 0; i < txts.length; i++) {
  4:         OcultarTxtEdit($(txts[i]), false); 
  5:     }
  6: }

*. OcultarTxtEditTodos():

Si se presiona la tecla escape salimos de la edición de la celda.

  1: function FiltradoKey(e, txt) {
  2:     var code = (e.keyCode ? e.keyCode : e.which);
  3:     if (code == 27) {
  4:         OcultarTxtEdit(txt, false);
  5:     }
  6: }

YA tenemos nuestra grid con la posibilidad de modificar los registros, con tabulación y cancelación funcionando al 100% !!!!

grideditCel3

grideditCel33

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:

  1: public class ClienteData
  2: {
  3:     public string id { get; set; }
  4:     public string columna { get; set; }
  5:     public string valor { get; set; }
  6: }

*. ActualizarDatos “Servidor”:

Método del servidor que recupera la información del cliente y convierte el objeto Json en una lista de tipos “ClienteData”:

grideditCelDebug

*. 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.

  1: function ActualizarDatos()
  2: {
  3:     var datos = '';
  4:     var txtEditados = $(".txtEdit");
  5:     for (var i = 0; i < txtEditados.length; i++) {      
  6:         if(i > 0)
  7:             datos += ',';
  8:           
  9:         datos += '{"id":"' 
 10:          + txtEditados[i].parentElement.cells[0].innerText
 11:          +'","columna":"'
 12:          + txtEditados[i].getAttribute("columnName")
 13:          + '","valor":"'+txtEditados[i].innerText
 14:          + '"}';
 15:     }       
 16:     var jDatos = JSON.parse('[' + datos.replace(/;/g, ",")+ ']');   
 17:     PageMethods.ActualizarDatos(jDatos, 
 18:       ActualizarDatosOK, ActualizarDatosKO);
 19: }

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.

Aplicaciónimages

Cross-Posting: http://lonetcamp.com

 

13 comentarios en “GridView Custom Edit”

  1. Hola estimado, mi consulta es : Al llamar a PageMethods.ActualizarDatos(jDatos, ActualizarDatosOK, ActualizarDatosKO);

    Que valores toma ActualizarDatosOK, ActualizarDatosKO

    A la espera de tu ayuda.

    Atte. epasapera.

  2. Hola Marc

    Ante todo Gracias por tu aporte no tengo mucho conocimiento de asp net pero si he buscado en la web y esta funcionalidad sobre el GridView sin duda es una herramienta imprescindible y la forma en que está presentada es sencilla y eficiente.

    En mi caso no pude hacerla funcionar por mi falta de experiencia al hacer el mousedoen entra en la funci{on de javascript EditarPrecio pero algo está mal con el objeto this ya que en la línea :

    var tdControl = $(td)[0];

    parecería haber un error ya que no sigue a la próxima instrucción (la depuro con el debug firefox)
    incluso pongo un alert (td.id) para que me devuelva algo pero lo hace en blanco.

    Esta es una porción del código que veo en el debug del firefox supuestamente el objeto this debería reporesentar al td pero si bien entra en la funci{on da el error comentado en la primera instrucción.

    SALAZAR VANESA YANINA
  3. Marc buenas tardes… este tutorial esta de lujo …pero soy novato, intente hacerlo pero no genera error pero de igual forma no me realiza ninguna accio, no se que estoy haciendo mal….te agradeceria mucho que me colaboraras ya que me pidieron un proyecto de las mismas magnitud y ya hacia 1 mes buscaba una solucion hasta que te encontre….espero tu respuesta muchas gracias

  4. Pues sin ver el código es dificil, seguramente hay unerror en el javascript y no se interpreta correctamente. Intenta mirar si le falta algo al script o si el navegador te muestra un error script.

  5. ufff por fin encontre una solucion mucho mas dinamica …la cuestion era de entender la interpretacion …MARC gracias tu ejemplo me sirivio de base para el resultado final que fue exelente

  6. perfecto Condoman, pero los artículos de esa época perdi los ejemplos en el servidor web que me dejó tirado 🙁 . Me alegro que lo soluciones.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *