Introducción
Un requerimiento que siempre surge en SharePoint tiene que ver con manejar relaciones de maestro-detalle. He visto y utilizado diferentes formas, con ventajas y desventajas que siempre dependen del escenario en que nos encontremos. En este artículo vamos a mostrar un ejemplo para WSS 3.0 que utiliza programación del lado del cliente.
Funcionalidades que necesitamos
En esta lista detallo lo que necesitamos. A lo largo del artículo veremos cómo implementaremos cada caso:
· ¿Cómo vincular en las listas al padre y al hijo?
· ¿Cómo mostrar los hijos de un padre?
· ¿Cómo tener un botón que dispare la creación un hijo para el padre seleccionado?
· ¿Cómo crear un hijo sin tener que completar manualmente los datos del padre?
· ¿Cómo ocultar los datos del padre en el momento de editar el hijo?
¿Cómo vincular en las listas el padre y al hijo?
Para vincular, yo prefiero usar el campo ID del padre como referencia en el hijo. No creo que ese campo necesite ser de tipo “búsqueda”, con lo cual, simplemente creamos en el hijo un campo con estas características:
· Nombre = Padre (o lo que se adapte mejor a nuestro caso)
· Tipo = Texto
· Obligatorio
¿Cómo mostrar los hijos de un padre?
Una forma sencilla para evitar programación es usar las conexiones entre elementos web. Con lo cual, simplemente creamos una página de elementos web en donde:
· Agregamos en la parte superior una lista del padre
· Agregamos en la parte inferior la lista con los hijos
· Conectamos los dos elementos web, vinculando el ID del elemento web de arriba con el Padre del elemento web de abajo.
¿Cómo tener un botón que dispare la creación un hijo para el padre seleccionado?
Para disparar la creación de un hijo, vamos a agregar un botón llamado “Nuevo” en cada fila de la lista padre. Este botón puede ser simplemente un enlace. En principio existen al menos tres enfoques para agregar este botón:
· Mediante un flujo de trabajo
· Mediante un manejador de eventos
· Mediante código JavaScript
En este caso vamos a trabajar con código JavaScript. ¿Por qué? Porque las dos primeras opciones son asincrónicas y puede generar la necesidad de que el usuario tenga que actualizar la pantalla luego del alta del padre, para poder ver el botón “Nuevo”. Esto es difícil de explicar al usuario final.
Nuestro enfoque consistirá en:
· Un elemento web de edición de contenido (CEWP) que ejecute código Java Script que reemplace la columna ID por el nuevo botón.
· Para ello trabajaremos con jQuery
· El contenido de la CEWP lo almacenaremos en un archivo en una librería, para facilitar futuros cambios: maestro_dedalle_boton_nuevo.html
A continuación vemos el código necesario.
<script type="text/javascript">
// Agregar esta CEWP debajo de la vista de la lista Padre
// Parámetros importantes
// Posición en que se encuentra la columna ID
var posicion_id = 3;
// Nombre de la lista hija
var lista_hija = "Registros SP";
// Texto para el botón o imagen
var texto_boton = "<img style='border: none;' src='/_layouts/images/itann.gif'/ title='Agregar registro' >";
// Estilo del botón nuevo
var estilo_boton = "";
// Título columna
var titulo_columna = "Agregar";
// Fin de Parámetros importantes
// Id de ítem
var identificador;
// URL del sitio
var sitio= window.location.href;
var origen = encodeURIComponent(sitio);
var posicion_listas = sitio.indexOf("Lists/");
sitio = sitio.substring(0, posicion_listas);
// URL de nuevo elemento en el hijo
var nuevo_hijo = sitio + "Lists/" + lista_hija + "/NewForm.aspx?source=" + origen + "&padre=";
// Cambiar Título de columna
$(".ms-listviewtable > tbody > tr > th #diidSortID").text(titulo_columna);
// Cambiar columna
// Asumo que la lista usa la vista standar que posee la clase .ms-listviewtable
$(".ms-listviewtable > tbody > tr > td:nth-child("+posicion_id+")").each(function( index ) {
// Obtengo el ID del elemento
identificador = $( this ).text();
// Cambio el ID por el botón nuevo
$( this ).html("<a style='" + estilo_boton + "' href='" + nuevo_hijo + identificador + "'>" + texto_boton + "</a>") ;
});
</script>
En la imagen, podemos ver cómo se ve la lista antes y cómo se ve luego:
¿Cómo crear un hijo sin tener que completar manualmente los datos del padre?
Dentro de la pantalla NewForm vamos a realizar lo siguiente:
· Completar el valor del campo Padre
· Ocultar el campo Padre (la fila completa)
A continuación el código necesario:
<script type="text/javascript">
// Agregar esta CEWP en la parte de abajo de la pantalla NewForm.aspx
// Para que se abra el editor, utilizar ?toolpaneview=2
// Parámetros importantes
// Nombre del campo Padre
var campo_padre = "ID.";
// Fin de Parámetros importantes
// Completamos el valor del campo Padre
var valor_padre = url_param("padre");
$('input[title="' + campo_padre + '"]').attr("value",valor_padre);
$('input[title="' + campo_padre + '"]').parent().parent().parent().css("display","none");
// Función para leer un valor de parámetro de URL
function url_param ( name ){
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
</script>
¿Cómo ocultar los datos del padre en el momento de editar el hijo?
Esto aplica tanto a la pantalla de edición, como a la pantalla de display. A continuación el código requerido:
Para la pantalla DispForm:
<script type="text/javascript">
// Agregar esta CEWP en la parte de abajo de la pantalla DispForm.aspx
// Para que se abra el editor, utilizar ?toolpaneview=2
// Parámetros importantes
// Nombre del campo Padre
var campo_padre = "ID_x002e_";
// Fin de Parámetros importantes
// Ocultar la fila
$('a[name="SPBookmark_' + campo_padre + '"]').parent().parent().parent().css("display","none");
</script>
Para la pantalla EditForm:
<script type="text/javascript">
// Agregar esta CEWP en la parte de abajo de la pantalla EditForm.aspx
// Para que se abra el editor, utilizar ?toolpaneview=2
// Parámetros importantes
// Nombre del campo Padre
var campo_padre = "ID.";
// Fin de Parámetros importantes
// Ocultar la fila
$('input[title="' + campo_padre + '"]').parent().parent().parent().css("display","none");
</script>
Conclusión
Hemos visto un método bastante simple y efectivo para crear relaciones de maestro detalle en SharePoint 2007. No requiere programación del lado del servidor y soporta cambios futuros a las listas al no requerir la programación de pantallas a medida.
Espero les resulte útil. Hasta la próxima.