XForms/Listas de Selección a partir de archivos

De Wikilibros, la colección de libros de texto de contenido libre.
Saltar a: navegación, buscar

Motivacion[editar]

Las personas que diseñan formularios frecuentemente tienen que mantener muchas tablas de coldigo. dichas tablas de codigo pueden cambiar frecuentemente o pude haber tambien procesos de actualización de bases de datos centralizadas. Asi que quieres que cada formulario dinamicamente obtenga el contenido de datos de un archivo XML o de un webservice.

Este programa de ejemplo demuestra como leer una lista de codigos con etiquetas directamente de un archivo o webservice. En este ejemplo el archivo que contiene los codigos es simplemente un archivo XML bien formado en el mismo directorio que el formulario.

Enlace a la aplicacion funcionando[editar]

Nota: no soy el autor original de este ejemplo solamente lo tomo con fines ilustrativos.
Lista de selección a partir de archivos

Cargando una instancia de XML de un archivo local o un webservice[editar]

El siguiente fragmento de codigo usualmente ubicado en la etiqueta HTML "head", demuestra como leer datos XML desde un archivo en el mismo directorio que el formulario usando el atributo "src" de la instancia.

Cargando una tabla de codigo simple a una instancia simple[editar]

<html>
   <xf:model>
      <xf:instance src="XMLSchemaTypeCode.xml" id="XMLSchemaTypeCode"/>
   </xf:model>
</html>

Cargando datos de un Webservice[editar]

Es común tener en un solo Webservice cargadas todas las tablas de datos. A este servicio se le pueden pasar parametros tales como el nombre de la tabla de datos, asi como una persona es parte de un grupo. Esto puede reducir la lista de opciones para listas largas.

<html>
   <xf:model>
      <xf:instance id="ApprovalCodes" src="/db/mdr/services/all-codes.xq?code=ApprovalCodes&group=editor"/>
   </xf:model>
</html>

Cargando todos los datos en una sola instancia[editar]

el problema de cargar codigos individualmente en instancias individuales es que debes realizar un get HTTP por cada una de las tablas de datos. Esto no es un problema para formularios con una o dos listas de seleccion pequeñas. Pero para formularios largos con muchas listas de selección éstos get pueden retrasar el tiempo de respuesta del formulario. La solucion es cargar todas las tablas en una sola instancia con una sola solucitud get HTTP. cada tabla de datos puede ser entonces seleccionada de esta instancia.

<html>
   <xf:model>
      <xf:instance src="/db/mdr/services/all-codes.xq?form=DataElementManager&group=admin"/>
   </xf:model>
</html>

En este segundo ejempo todos los datos en el formulario completo estan siendo generados por un sevicio del Registro de Metadata(MDR por la sigla en inglés). los datos retornados por este servidor son una coleccion de codigos para cada control de seleccion del formulario.

Esto buscara por un archivo XML bien formado en el directorio actual y lo cargara en la instancia del modelo.

Notese que en este caso al modelo se le da un id. Esto es necesario para permitir que multiples tablas de datos sean leidas en su propio y separado modelo.

Previsualización[editar]

El usuario selecciona el valor del drop-down list. el valor en la salida es actualizado inmediatamente.

Listaseleccion.jpg

Notese que la etiqueta en la imagen no es la misma que en el esquema.

Programa ejemplo[editar]

<html
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xf="http://www.w3.org/2002/xforms" >
   <head>
      <title>Select List From File</title>
 
      /* the default model */
      <xf:model>
         <xf:instance xmlns="">
            <MyData>
                  <MyXMLSchemaTypeCode/>
            </MyData>
         </xf:instance>
      </xf:model>
 
      /* read the codes from an external file into this model */
      <xf:model id="XMLSchemaTypeCode">
         <xf:instance src="XMLSchemaTypeCode.xml"/>
      </xf:model>
 
   </head>
   <body>
      <p>This selection list was read from a file.</p>
      <xf:select1  ref="/MyData/MyXMLSchemaTypeCode">
         <xf:label>Select XML Schema data type: </xf:label>
         <xf:itemset model="XMLSchemaTypeCode" nodeset="/XMLSchemaTypeCode/item">
            <xf:label ref="label"/>
            <xf:value ref="value"/>
         </xf:itemset>
      </xf:select1>
      <br />
      <xf:output ref="/MyData/MyXMLSchemaTypeCode">
         <xf:label>Value of MyXMLSchemaTypeCode: </xf:label>
      </xf:output>
   </body>
</html>

Ejemplo de datos[editar]

<?xml version="1.0" encoding="UTF-8"?>
<XMLSchemaTypeCode>
   <label>XML Schema Type:</label>
   <item>
      <label>Date and Time</label>
      <value>dateTime</value>
   </item>
   <item>
      <label>Time (HH:MM:SS-06:00)</label>
      <value>time</value>
   </item>
   <item>
      <label>Date (yyyy-mm-dd)</label>
      <value>date</value>
   </item>
   <item>
      <label>Year and Month</label>
      <value>gYearMonth</value>
   </item>
   <item>
      <label>Year (nnnn)</label>
      <value>gYear</value>
   </item>
   <item>
      <label>Month and Day</label>
      <value>gMonthDay</value>
   </item>
   <item>
      <label>Day of Month (1 .. 31)</label>
      <value>gDay</value>
   </item>
   <item>
      <label>Month (1 .. 12)</label>
      <value>gMonth</value>
   </item>
   <item>
      <label>String</label>
      <value>string</value>
   </item>
   <item>
      <label>Boolean (true/false)</label>
      <value>boolean</value>
   </item>
   <item>
      <label>Base 64 Binary</label>
      <value>base64Binary</value>
   </item>
   <item>
      <label>Decimal (0.00)</label>
      <value>decimal</value>
   </item>
   <item>
      <label>Any URI</label>
      <value>anyURI</value>
   </item>
   <item>
      <label>Integer (...,-2,-1,0,1,2,...)</label>
      <value>integer</value>
   </item>
   <item>
      <label>Non-Positive Integer (...,-2,-1,0)</label>
      <value>nonPositiveInteger</value>
   </item>
   <item>
      <label>Negative Integer (...,-2,-1)</label>
      <value>negativeInteger</value>
   </item>
   <item>
      <label>Long (-9,223,372T .. 9,223,372T)</label>
      <value>long</value>
   </item>
   <item>
      <label>Int (-2,147,483,648 .. 2,147,483,647)</label>
      <value>int</value>
   </item>
   <item>
      <label>Short (-32,768 .. 32,767)</label>
      <value>short</value>
   </item>
   <item>
      <label>Byte (-128 .. 127)</label>
      <value>byte</value>
   </item>
   <item>
      <label>Non-negative Integer (0..N)</label>
      <value>nonNegativeInteger</value>
   </item>
    <item>
      <label>Positive Integer (1..N)</label>
      <value>positiveInteger</value>
   </item>
   <item>
      <label>Unsigned Long (0 .. 18,446,744T)</label>
      <value>unsignedLong</value>
   </item>
   <item>
      <label>Unsigned Int (0 .. 4,294,967,295)</label>
      <value>unsignedInt</value>
   </item>
   <item>
      <label>Unsigned Short (0.. 65,535)</label>
      <value>unsignedShort</value>
   </item>
   <item>
      <label>Unsigned Byte (0..255)</label>
      <value>unsignedByte</value>
   </item>
</XMLSchemaTypeCode>

Extrayendo datos de un XML REST webservice[editar]

Se puede reemplazar el atributo src con una ruta directamente a un XML REST webservice. por ejemplo, si se ponen todas las tablas de datos en los recursos de un proyecto, la ruta luciria como asi:

<xf:instance src="../resources/code-tables/PersonGenderCode.xml"/>

o si los datos del sistemas estan almacenados en un solo archivo XML y se tiene un wrapper XQuery or if your system codes are stored in a single XML file and you have a wrapper XQuery

<xf:instance src="../resources/code-tables/get-codes-for.xq?element=PersonGenderCode"/>

Listas de seleccion a partir de una sola instancia[editar]

para mantener los formulario rapidos, usualmente es mejor hacer una sola operacion HTTP GET para todos los datos. Los formularios que tienen varias listas de seleccion, tomaran mas tiempo para cargar si cada una de las listas realiza una operacion HTTP GET. Para grandes formularios es facil obtener una mejora de velocidad de 10x en tiempos de cargado.

Estructura de instacia de tablas de datos[editar]

El siguiente es un ejemplo de la estructura de todos los datos cargados en una sola instancia

<xf:instance id="code-tables">
   <code-tables>
      <code-table>
         <code-table-name>MyElementCode</code-table-name>
         <items>
            <item>
               <label>Joe Smith</label>
               <value>42</value>
            </item>
            <item>
               <label>Sue Johnson</label>
               <value>47</value>
            </item>
         <items>
      </code-table>
      <code-table>
         <code-table-name>ColorCode</code-table-name>
         <items>
            <item>
               <label>Red</label>
               <value>1</value>
            </item>
            <item>
               <label>Orange</label>
               <value>2</value>
            </item>
         <items>
      </code-table>
   </code-tables>
</xf:instance>

Ejemplo Select1[editar]

una vez los datos estan cargados en el modelo, cada uno de los controles de select pueden obtener sus datos directamente desde el modelo usando el elemento <xf:itemset>. Itemset trabaja igual que Repeat y usa nodeset (no usa ref) para obtener todos sus valores. Aca hay un ejemplo de como obtener el conjunto de datos desde la instancia de tabla de datos.

<xf:select1 ref="instance('save-data')/MyElementName">
   <xf:label>My Element:</xf:label>
   <xf:itemset nodeset="instance('code-tables')/code-table[code-table-name='MyElementCode']/items/item">
       <xf:label ref="label"/>
       <xf:value ref="value"/>
   </xf:itemset>
</xf:select1>

Notese que el predicado [code-table-name='MyElementCode'] pondra unicamente los elementos para ese codigo en la lista de seleccion.