Llenado programatico de tablas repetibles en formularios InfoPath Form Services

Aquí una técnica que resulta interesante cuando trabajamos con formularios InfoPath Form Services de SharePoint Server 2007. Resulta que cuando usamos InfoPath 2007 combinado con Forms Services perdemos un tanto de funcionalidad como controles, opciones de filtrado y de conexión a datos externos es por ello que en ocasiones debemos de utilizar alternativas un tanto artesanal para simular el comportamiento esperado. Hoy quiero compartir una alternativa para poder presentar un listado de cuadros de verificación para permitir al usuario seleccionar más de una opción dentro de sus formularios InfoPath Form Services.

Una lista repetible en InfoPath es una especie de tabla de información vinculada a alguna fuente de datos que permite mostrar un arreglo de renglones con columnas y con sus correspondientes controles para el llenado o captura tabular, esta lista ya incluye la funcionalidad para agregar o eliminar renglones de forma automática. Bajo este contexto, el de mostrar una lista de cuadros de verificación para multi selección usaremos una lista para mostrar en una columna el  cuadro de verificación y en la otra su descripción, deshabilitaremos las opciones de edición de la lista para crear un efecto de despliegue.

image

Tomamos la lita repetible y la arrastramos sobre nuestro formulario, al hacerlo nos solicita que seleccionemos de cuantas columnas  requerimos la lista y seleccionamos dos.

image

El resultado es una lista repetible de forma tabular. Analisemos el esquema que InfoPath ha generado para representar esta lista con la finalidad de apreciar los nombres de los campos que estaremos utilizando en este ejemplo. group2 es un campo de tipo Grupo con la capacidad de auto repetir su contenido que en este caso son los campos field1 y field2

image

A continuacion dentro de nuestro fomulario transformamos a feld1 en cuadro de verificacion.

image

Realizamos el mismo procedimiento para la siguiente columna field2 solo que la cambiaremos a cuadro de expresion. Tambien podemos jugar con las propiedades de la lista repetible para esconder el encabezado y eliminar los bordes para generar el efecto deseado. Esto lo hacemos seleccionando las propiedades del objeto y accediendo a la pestaña de Display para deshabilitar la opcon de incluir el encabezado o Include Header. Asi mismo dentro de la pestaña Data deshabilitamos las opciones por defecto Default Settings y la de mostrar botón de inserción. Esto nos quita la opción de agregar soporte para agregar, modificar y eliminar elementos de forma automática..

image

Ya tenemos la estructura lista para poder codificar y cargar sobre ella una lista de datos que puede provenir de cualquier otra fuente de información.
A continuación desde InfoPath cargamos Visual Studio for Applications seleccionando del menú de herramientas la opción de programación y evento de carga.

image

No olvidemos primeramente guardar nuestro formulario y configurar un par de opciones dentro de la configuración de formulario o Form Options. En primer lugar dentro de Security and Trust especificamos nuestro formulario como Full Trust, esto se debe a que estaremos ejecutando código.

image

Y dentro de la sección programming seleccionemos que lenguaje de programación deseamos usar y en que carpeta guardaremos el código.

image 

Ya dentro de Visual Studio for Applications tenemos el código correspondiente al evento de carga del formulario. Es aquí donde puedes conectarte a otra fuente de datos ya sea de forma programática o directamente desde InfoPath.

De momento haremos el llenado manual de la lista repetible mediante el siguiente código de programación.

private const string STR_XPATH_Grupo = "/my:myFields/my:group1/my:group2";
        private const string STR_XPATH_Nodo = "/my:myFields/my:group1/my:group2/my:field2";
      
        private void CargaLista()
        {     
            // creamos una instancia de nuestro esquema principal
            XPathNavigator DOM = MainDataSource.CreateNavigator();

            // obtenemos una referencia del nodo repetible 
            XPathNavigator tableItem = DOM.SelectSingleNode(STR_XPATH_Grupo, this.NamespaceManager);
            XPathNavigator tableItemNode = null;
            
            // clonamos un elemento y lo asignamos a otra variable
            tableItemNode = tableItem.Clone();

            // obtenemos la ruta de donde estaremos actualizando la informacion dentro del elemento clonado          
            XPathNavigator target = tableItemNode.SelectSingleNode(STR_XPATH_Nodo, this.NamespaceManager);

            // establecemos la informacion a desplegar dentro del elemento clonado
            target.SetValue("hola");

            // insertamos el elemento clonado en la lista repetible
            tableItem.InsertAfter(tableItemNode);

            target = null;
            tableItemNode = null;


        }

 

El resultado:.

image

 

A continuación dejo una rutina un poco más elaborada donde se muestra como cargar una lista repetible que proviene de una fuente de datos externa configurada dentro de InfoPath.

  • En dataSource enviamos el nombre de nuestra conexión a otra fuente de datos configurada en InfoPath.
  • En tableRow enviamos la ruta XPath que apunta a grupo repetible de una lista repetible.
  • En fieldName especificamos el nombre del campo que deseamos mostrar en la descripción de la lista repetible.
  • En targetXPath especificamos la ruta XPath del nodo descripción de nuestra lista repetible.
 private void LoadSPListToRepeatingTable(string dataSource, string tableRow, string fieldName, string targetXPath)
        {       


            XPathNodeIterator list = DataSources[dataSource].CreateNavigator().Select("/xml/rs:data/z:row", this.NamespaceManager);
            XPathNavigator DOM = MainDataSource.CreateNavigator();
            XPathNavigator tableItem = DOM.SelectSingleNode(tableRow, this.NamespaceManager);
            XPathNavigator tableItemNode = null;
          

            foreach (XPathNavigator listItem in list)
            {

                if (tableItem != null)
                    tableItemNode = tableItem.Clone();


                string value = listItem.SelectSingleNode(fieldName, NamespaceManager).Value;
                XPathNavigator target = tableItemNode.SelectSingleNode(targetXPath, this.NamespaceManager);
                target.SetValue(value);
                tableItem.InsertAfter(tableItemNode);

                target = null;
                tableItemNode = null;


            }
            tableItem.DeleteSelf();
            tableItem = null;
            DOM = null;

        }

 

La invocación de esta rutina es:

           LoadSPListToRepeatingTable("Areas", "/my:myFields/my:Inicio/my:areas/my:areaRow", "@ows_LinkTitle", "/my:myFields/my:Inicio/my:areas/my:areaRow/my:areaDescripcion");

 

EL resultado seria algo asi:

image

Leave a Reply

Your email address will not be published. Required fields are marked *