Validación de campos en un formulario personalizado de Shrepoint 2007 con JavaScript – Part III

Parte III – Formularios personalizados de lista en Sharepoint 2007

Una vez que tenemos construido el formulario personalizado para la lista de Sharepoint y está funcionando correctamente vamos a colocar las validaciones necesarias para que no se pueda guardar un elemento hasta que los datos ingresados en la misma están correctos o los campos obligatorios fueron ingresados.

Como comentamos anteriormente Sharepoint nos provee mecanismos para la validación de los datos ingresados en cada campo de la lista, pero los mismos son ejecutados en el Servidor, lo que implica que nuestro formulario tenga que ir al servidor para realizar la misma y retornar al cliente si se produjo un error. Este mecanismo es rápido cuando nos encontramos en un ambiente de Intranet, pero cuando el ambiente es de Extranet o Internet la rapidez con la cual se ejecute la validación dependerá de la velocidad que contemos y de que tan cargado de trabajo se encuentre el servidor donde está alojada la solución Sharepoint.

Lo que nos llevo a nosotros a implementar esta solución fue que el servidor de Sharepoint tiene exposición a Internet y además el formulario que debíamos realizar era bastante complejo y las validaciones que debíamos realizar eran también complejas, debido a que algunas de ellas dependían de otros campos ingresados en el dicho formulario.

No podíamos utilizar código servidor para realizar las mismas puesto que no teníamos permisos y acceso al servidor de producción para instalar un Assembly con el código necesario para realizar las validaciones. Este problema es muy común en servidores administrados por terceros y donde nosotros no podemos instalar directamente ninguna solución (WSP o CAB) en el server o ni siquiera podemos colocar el Assembly en el directorio Bin de ejecución de nuestra aplicación.

Utilizando JavaScript colocado en el formulario hemos desarrollado una solución rápida y sencilla para resolver este problema, la cual nos permitió realizar todas las validaciones necesarias.

En este ejemplo que estamos haciendo vamos a colocar la validación de un campo de la lista y la misma se llevara a cabo cuando el usuario presione el botón Guardar, que está en el formulario. El problema principal que debemos sortear es poder anticiparnos al evento click del botón Guardar desde JavaScript, puesto que el control de Sharepoint "SharePoint:SaveButton" que utilizamos en el formulario para guardar no expone públicamente un evento el cual podamos programar. La solución a este problema la tenemos utilizando una función de JavaScript llamada "attachEvent" que nos permite registrarnos a cualquier evento de un control indicándole el evento que queremos registrarnos y un puntero a la función JavaScript que manejara dicho evento cuando se produzca. Tampoco podemos registrarnos al evento click del control (Submit) puesto que cuando nuestra función es notificada de que se produjo el mismo el formulario ya paso por el proceso de Submit y la pagina se está enviando al servidor y no podemos cancelar este proceso, lo que vamos hacer es registrarnos al evento "onmouseup" el cual se produce antes y podemos cancelar todos los eventos producidos, con esto logramos que el formulario no sea enviando al servidor hasta que la validación este correcta. Esta función "attachEvent" pertenece a cada control por lo que tenemos que buscar el control dentro del formulario, para eso podemos utilizar las funciones JavaScript getElementById o getElementByName. A la primera función le tenemos que pasar el ID del control y a la segunda el Name del control, pero en ambos casos son generados por Sharepoint en la renderización del formulario, por lo cual tenemos dos opciones de ver cuál es el ID del control en el cliente (browser). La primera opción es inspeccionar el código fuente y sacar todos los Ids que necesitamos o si no podemos utilizar una función que nos extraiga el Name a partir del tagName, identifier, title dle control que colocamos en nuestro formulario Sharepoint. La implementación de esta función fue extraída de la siguiente página "Microsoft SharePoint Designer Team Blog" y nos permite en tiempo de ejecución saber el name del control al que queremos registrarnos. Una vez tengamos el Name, utilizamos la función getElementByName para obtener una referencia al control en la página y así poder registrarnos al evento correspondiente.

Debido a que nos encontramos en un formulario de Sharepoint y el mismo tiene una Master Page asociada, no contamos con el tag body para poder colocar nuestro código en el evento Load del formulario, pero dentro de los JavaScript que nos provee Sharepoint contamos con una función que nos permite poner una función nuestra JavaScript en la pila de funciones que serán disparadas en el evento Load del mismo cuando se cargue, esta función se llama "_spBodyOnLoadFunctionNames.push".

En la siguiente sección (Ver Sección 1) vamos a ver cómo nos registrarnos al evento "onmouseup" de los dos botones que están en nuestro formulario.

Sección 1

_spBodyOnLoadFunctionNames.push("EventButton"); //Función que registra una función de JavaScript para que sea disparada en el evento Load del formulario.

function EventButton()
{
    var objAceptar = getTagFromIdentifierAndTitle("input","SaveItem","");//Se registra al evento "onmouseup" del botón aceptar
    objAceptar.attachEvent("onmouseup",AceptarClick);
    var objCancelar = getTagFromIdentifierAndTitle("input","GoBack","");//Se registra al evento "onmouseup" del botón cancelar.
    objCancelar.attachEvent("onmouseup",CancelarClick);
}

En la sección anterior nos registrarnos a los eventos de los botones Aceptar y Cancelar del formulario de Sharepoint realizados y establecimos una manejador para cada uno de los controles adjuntos. Podríamos registrar un manejador genérico para ambas funciones y que en el mismo ejecutar las validaciones necesarias. Ahora vamos a ver el código de cada una de las funciones registradas, en la siguiente sección (Ver Sección 2) vamos a ver el código para manejar el evento del botón Aceptar y en la sección 3 (Ver Sección 3) vamos a ver el código para el evento del botón Cancelar.

Sección 2

function AceptarClick()
{
    var lCancelarEvento = false;
    var lTxtTitulo = null;
    lTxtTitulo = getTagFromIdentifierAndTitle("input", "TextField", "Título");
    if(lTxtTitulo.value == "")
    {
        alert("El campo Título no puede estar vacio.");
        lTxtTitulo.focus();
    }
    return lCancelarEvento;
}

Sección 3

function CancelarClick()
{
    var lCancelarEvento = false;
    alert("Cancelo la creación del nuevo item");
    return lCancelarEvento;
}

En la próxima sección (Ver Sección 4) vamos a ver el código de la función "getTagFromIdentifierAndTitle" la cual nos permite obtener una referencia al control que queremos de forma dinámica.

Sección 4

function getTagFromIdentifierAndTitle(tagName, identifier, title)
{
    var len = identifier.length;
    var tags = document.getElementsByTagName(tagName);
    for (var i=0; i < tags.length; i++) {
        var tempString = tags[i].id;
        if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length – len))
        {
            return tags[i];
        }
    }
    return null;
}

Hemos completado el código necesario para llevar a cabo las validaciones en nuestro formulario, vamos a ver como quedan las mismas cuando probamos el formulario, la siguiente imagen (Ver Imagen 1) muestra como se dispara el evento del botón Aceptar y en la imagen 2 (Ver Imagen 2) muestra como se dispara el evento del botón Cancelar.
Imagen 1
Botón_Aceptar
Imagen 2
Botón_Cancelar

Espero que esta serie de artículos le haya servido de utilidad como nos sirvió a nosotros para implementar una solución diferente para realizar validaciones.