El editor de DataTables (III). Formatear y comprobar datos.

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

En el artículo anterior hemos visto un uso básico del editor de DataTables. Tuvo un interesante valor didáctico, pero no nos valdría para un caso real de uso, ya que adolece de severas limitaciones. Por ejemplo, la fecha de ingreso de los miembros del personal no debería poder teclearse libremente, para que el usuario no pueda meter la pata. En su lugar, se debería mostrar un datepicker que obligue a respetar un formato de fecha en la introducción de datos. Lo mismo ocurre con el salario. No debe aparece el signo del euro en el campo, y debemos forzar un formato correcto de introducción de datos. Además, antes de enviar el formulario, en los casos de nuevo registro y edición, debemos hacer una comprobación previa. Si algún dato no se ajusta al formato esperado (por ejemplo, letras en el campo del salario). Si algo no está bien, debemos avisar al usuario, y cancelar el envío del formulario, hasta que todos los campos pasen la validación. Eso le da un toque mucho más profesional a nuestra aplicación. Por supuesto, nunca podremos evitar completamente que el usuario meta la pata. Algunos usuarios lo hacen cada vez que tienen la más mínima oportunidad de ello, pero paliaremos mucho esos errores.

Presta especial atención a este artículo porque vamos a conocer muchas opciones de configuración nuevas. No son difíciles de entender. De hecho, estoy racionalmente seguro de que, cuando leas el código, y lo pruebes, lo entenderás casi sin leer el texto del artículo. No obstante, si es mucha materia nueva y te la detallaré paso a paso.

LOS SCRIPTS SECUNDARIOS

Los scripts secundarios no presentan novedades respecto a los del artículo anterior. Simplemente los hemos renombrado a datos_externos_editor_03.php y crud_editor_03.php. Otro elemento que tampoco cambia respecto al script anterior es la tabla de personal que empleamos. Estos tres elementos te los he dejado para descargar en un comprimido en este enlace. Simplemente, descomprímelo, guarda los scripts en la ruta correspondiente en tu ordenador (localhost/datatables, si sigues la misma nomenclatura que yo en los artículos) y, si no la tienes, importa la tabla en MySQL.

EL SCRIPT PRIMARIO

Aquí es donde se cuece todo. Lo hemos llamado articulo_editor_03.php, y su listado es el siguiente:

Vale.. Visto así impone un poco, pero ten en cuenta dos cosas. Primera. Sin el editor y sin la configuración que hacemos del mismo, obtener los resultados que obtenemos llevaría mucho más código, y muchísimo más tiempo de desarrollo. Y la segunda. Si has seguido todos los artículos de DataTables verás que tampoco es para llevarse las manos a la cabeza. Vamos a ir viendo que hacemos. No comentaremos tódo el código. Sólo las novedades de este artículo con respecto a lo que ya sabemos, que corresponden a las líneas resaltadas en el listado.

En las líneas 9 y 43 vemos que incluimos, por CDN, jQueryUI. Lo vamos a usar para el datepicker del campo relativo a la fecha de ingreso en los formularios de nuevo y edición.

En la línea 51 vemos que incluimos la librería de JavaScript moment.js. Se trata de una librería JavaScript especializada en la gestión de datos de fecha y hora, que el editor de DataTables necesita si queremos poder darle a la fecha un formato adecuado en el formulario. Si no, por defecto, las fechas irán en el formato ISO 8601 que, si bien es lo mejor para las bases de datos y la operativa interna, desde luego no lo es para un formulario para el usuario. Dado que, como te digo, el editor va a necesitar esta librería, la incluimos antes de empezar a trabajar.

En el artículo anterior ya aprendimos a crear un objeto de la clase editor, basado en el complemento editor de DataTables. Aquí vamos a empezar a ver novedades con respecto a aquél. Lo primero es la definición de los textos, en un idioma distinto del inglés, del campo de fecha, entre las líneas 85 y 90:

datetime: {
    previous:    'Anterior',
    next:        'Siguiente',
    months:        ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
    weekdays:    ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb']
}

En este caso, no lo vamos a necesitar ya que, cómo hemos dicho, para la fecha vamos a usar el datepicker de jQueryUI. Estos textos serían relevantes si fuésemos a usar un campo de fecha HTML 5, que es un poco más “soso” a mi gusto. Los ponemos, únicamente, para que te conste como los incluiríamos si no fuéramos a usar jQueryUI.

Entre las íneas 97 y 119 vemos cómo definimos el campo de fecha:

{
    label: 'F. Ingreso:',
    name: 'fecha_de_ingreso',
    type: 'date',
    def: function(){return new Date();},
    dateFormat: 'dd-mm-yy',
    attr: {readonly:true},
    opts:{
        buttonImage:'editor/images/calendar.png',
        buttonImageOnly: true,
        buttonText: 'Elegir fecha',
        dayNames: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
        dayNamesMin: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá'],
        dayNamesShort: ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'],
        firstDay: 1,
        monthNames: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
        monthNamesShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
        changeMonth: true,
        changeYear: true,
        prevText: "Anterior",
        nextText: "Siguiente"
    }
},

Las propiedades label y name se usan como en cualquier otro campo. Ninguna novedad en eso.

Atención. La propiedad buttonImage hace referencia al icono que abre y cierra el datpicker. En las versiones actuales del editor el fabricante ha dejado de incluir la carpeta images, por lo que deberás crear tú dicha carpeta e incluir en ella el icono adecuado. Puedes usar este mismo (), haciendo clic derecho sobre él y seleccionando Guardar imagen como....

La propiedad type se refiere, como sabes, al tipo de dato del campo. Con el valor date le indicamos que es un campo de fecha.

La propiedad def se refiere al valor por defecto. Si usamos el formulario para edición de un registro, en el campo ya hay un valor. Sin embargo, en el caso de usarlo para crear un nuevo registro, en el campo podemos querer que aparezca, por defecto, la fecha del día en curso, que es lo que indicamos aquí.

La propiedad dateFormat establece el formato en que se mostrará la fecha en el formulario, y en el que el usuario debe introducirla. Y aquí es donde el editor necesita la librería moment.js que decíamos antes. Si no la hemos incluido, esta línea dará un error de JavaScript, y lo que estamos haciendo no funcionará.

La propiedad attr permite asociarle al campo cualquier atributo que pudiéramos usar en HTML, si estuviéramos creando el campo “a mano”. En este caso le asignamos el atributo readonly, como el valor true, porque, al ser un campo de fecha, queremos que el usario tenga que emplear el datepicker que le proporcionamos, y no pueda teclear nada directamente, para minimizar posibles errores.

Cuando el editor detecta que se ha incluido jQueryUI, automáticamente lo selecciona para el datepicker, por lo que no necesitamos indicárselo. Sin embargo, si es necesario establecer las opciones del datepicker de jQueryUI que estableceríamos si fuéramos a usarlo de modo independiente en un formulario cualquiera. En el caso del editor de DataTables, estas opciones se establecen en opts, y corresponden con las del datepicker, que puedes ver en este enlace.

En la línea 123 vemos como definir una información complementaria a un campo, para que el usuario la lea. Lo que incluimos como contenido de la propiedad fieldInfo se muestra, en una tipografía más reducida que la normal, debajo del campo al que le asociamos esta propiedad (en este ejemplo, el campo relativo al salario.

PREVALIDACIÓN EN EL LADO DEL CLIENTE

Lo que aparece a continuación, entre las líneas 128 y 194 es una validación previa de los datos introducidos, de modo que, si hay algún error (por ejemplo, un salario con letras) no se envíe el formulario para procesar. En su lugar, se informará al usuario, y se focalizará el campo que presente errores. Veamos cómo opera este mecanismo.

Los objetos creados sobre el editor de DataTables pueden detectar varios eventos, que iremos conociendo, mediante el método on(). Este es similar, en cuanto a sintaxis y uso, a su homónimo de jQuery, pero orientado a su uso con los objetos editor específicamente, ya que puede detectar los eventos de estos. En este caso, detectamos el evento preSubmit. Este evento se dispara cuando el usuario pulsa el botón de envío del formulario, y justo antes de que se efectúe dicho envío, lo que es ideal para validaciones, ya que, si no se validan correctamente los datos, se puede interrumpir el proceso de envió.

Además, el método on() recibe, cómo segundo argumento, una función callback, que será la encargada de efectuar la validación. Esta recibe tres argumentos:

  • El propio evento que se ha detectado.
  • Los datos del formulario, en un sólo objeto.
  • La acción que se estaba llevando a cabo en el momento de dispararse el evento.

Fíjate en la forma en que invocamos a este detector para el evento preSubmit:

objetoEditor.on('preSubmit', function(e, data, action){

Como ves, se aplica, directamente, sobre el objeto que hemos creado para usar el editor de DatTables.

Dentro de la función de callback que empleamos para la validación, lo primero que hacemos es comprobar cual es la acción que se ha pedido, ya que, si es la de eliminar uno o más registros (remove), no hay nada que prevalidar. En ese caso, se permite, directamente, el envío del formulario, así:

if (action == 'remove') return true;

Por lo tanto, todo lo demás que hay en la función sólo se empleará en caso de que la acción sea la creación de un nuevo registro (create), o la edición de uno o más registros (edit).

Lo siguiente que encontramos es una comprobación de que el nombre no esté vacío, o no contenga, únicamente, espacios en blanco. Empezamos recuperando el contenido del campo en una variable de JavaScript:

var dato_nombre = objetoEditor.field('nombre').val();

A partir de aquí hay que tener en cuenta si estamos haciendo una edición de múltiples registros. Eso lo averiguamos con el método isMultiValue(). Si estamos haciendo una edición de múltiples registros, y hemos tecleado algo en el campo nombre, este método devuelve un valor true. Se la edición es de un sólo registro, o si, en caso de múltiples registros, no hemos tecleado nada, para respetar los contenidos originales de este campo, el método devuelve false. También devuelve false si la operación es create. Si este método devuelve false, debemos recortar los espacios al principio y al final del contenido del campo, así:

if (!objetoEditor.field('nombre').isMultiValue()) dato_nombre = dato_nombre.trim();

Si el campo está vacío y el método isMultiValue() devuelve false, es cuando se debe entender que hay un error, y debemos informar de ello al usuario. El método error() coloca un texto en rojo debajo del campo que le indicamos. Además, debemos focalizar ese campo e interrumpir el envío. Si no hay error, debemos eliminar el mensaje en rojo de debajo del campo, y pasar a comprobar el siguiente campo:

if (dato_nombre == "" && !objetoEditor.field('nombre').isMultiValue()){
    objetoEditor.field('nombre').error('Debes teclear el nombre.');
    objetoEditor.field('nombre').focus();
    return false;
} else {
    objetoEditor.field('nombre').error('');
}

El resto de los campos, si sigues el código, se validan de la misma manera. En el momento que se detecte un error, se informará al usuario, y se interrumpirá el envío.

Un caso más delicado es el del último campo, relativo al salario. No sólo se valida cómo los demás, sino que, además, se comrueba que sea un número en coma flotante, con el punto cómo separador de los decimales, y con dos cifras decimales, así:

var dato_salario_bruto_anual = objetoEditor.field('salario_bruto_anual').val();
...
if (dato_salario_bruto_anual != parseFloat(dato_salario_bruto_anual).toFixed(2) && !objetoEditor.field('salario_bruto_anual').isMultiValue()){
    objetoEditor.field('salario_bruto_anual').error('El salario bruto anual no tiene el formato correcto.');
    objetoEditor.field('salario_bruto_anual').focus();
    return false;
} else {
    objetoEditor.field('salario_bruto_anual').error('');
}

Y ya está. Si hemos superado las validaciones, se envía (por fín) el formulario, y se procesa con el script secundario adecuado, que ya conocemos del artículo anterior.

Los scripts y la base de datos puedes descargarlos de este enlace.

     

Un comentario:

  1. Pingback: El editor de DataTables (IV). Datos de múltiples tablas. – El desván de Jose

Deja un comentario

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