Las listas de opciones son de gran ayuda para los formularios de las aplicaciones, nos podemos encontrar listas desplegables, listas de tipo radiobutton o listas con checkbox. Vamos a ver como es el uso de estos elementos en gvHidra.
Nos podemos encontrar con listas estáticas o listas dinámicas, básicamente la diferencia se encuentra en el origen de datos que las rellenarán. Su implementación es bastante similar aunque con algunas diferencias. Vamos a describir lo que tienen en común los dos tipos de listas.
Empezaremos viendo lo más sencillo, que es incluir una lista en la plantilla (tpl). El plugin a utilizar es el CWLista, vamos a hacer hincapié en el parámetro es "datos", el resto se puede ver su definición y uso en el Apéndice Documentación de Plugins. En el parámetro datos nos vendrán los datos que compondrán la lista en cuestión, la variable asignada siempre deberá tener la misma estructura, la que vemos en el ejemplo, siendo la palabra "defaultData_" reservada.
{CWLista nombre="codigoProvincia" textoAsociado="Provincia" editable="true" dataType=$dataType_claseManejadora.codigoProvincia
datos=$defaultData_claseManejadora.codigoProvincia}
Pasamos a la parte que le corresponde a la clase manejadora del panel. En ella debemos definir la lista mediante la clase gvHidraList, este método define el tipo y contenido de la lista, para ello se le pasan unos parámetros:
Nombre del campo destino de la lista (campo obligatorio). Será el mismo nombre que le hayamos puesto en la tpl al plugin CWLista (p.ej. "codigoProvincia")
Cadena que identifica la fuente de datos (campo opcional). Este campo pasa a ser obligatorio en el caso de las listas dinámicas.
DSN de conexión (campo opcional). Permite incluir un DSN de conexión para indicar una conexión alternativa a la propia del panel. Si no se indica ninguna se cogerá por defecto el DSN del panel. Por ejemplo, podemos tener un panel trabajando en PostgreSQKL y que un campo tenga una lista desplegable que lea los datos en MySQL.
A partir de la clase gvHidraList() podemos utilizar los siguientes métodos para acabar de perfilar la lista:
addOption($valor, $descripcion): Nos permite añadir opciones a la lista.
setSelected($valor): Con este método le indicaremos qué opción aparecerá seleccionada por defecto.
setMultiple($multiple): Pasándole un parámetro booleano (true/false) indicaremos si es o no una lista múltiple.
setSize($size): Indicaremos el número de elementos visibles cuando estamos en una lista que es múltiple. Por defecto tendrá un size=5.
setDependence($listasCamposTpl, $listasCamposBD,$tipoDependencia=0): Método que permite asigar dependencia en una lista, es decir, si tenemos una lista cuyos valores dependen del valor de otros campos, necesitamos indicarlo con este método.
$listasCamposTpl: Será un array que contiene la lista de campos de la tpl de los cuales depende la lista.Array que, indexado en el mismo orden que el anterior, realiza la correspondencia de los campos del array anterior con los de la Base de Datos.
$listaCamposBD: Será un array que, indexado en el mismo orden que el anterior, realiza la correspondencia de los campos de la tpl con los de la base de datos.
$tipoDependencia: Un entero con el que le indicaremos si es una dependencia fuerte->0 o débil->1 (si no tiene valor el campo dependiente lo ignora).
Nota: No se pueden crear listas dependientes con clausulas group by, ya que gvHidra internamente modifica en cada caso el valor de la where y en estos casos produce un error. De momento se pueden resolver usando una subconsulta con el group by en el from.
$listaProvincias = new gvHidraList('codigoProvincia','PROVINCIAS');
$this->addList($listaProvincias);
$listaMunicipios = new gvHidraList('codigoMunicipio','MUNICIPIOS');
$listaMunicipios->setDependence(array('codigoProvincia'),array('tcom_municipios.cpro'));
$this->addList($listaMunicipios);
setRadio($radio): Pasándole un parámetro booleano a true tendremos una lista de radiobuttons.
Una vez hemos definido los datos que compondrán la lista y cómo la queremos, tenemos que añadir la lista al panel, para ello utilizamos el método addList() del panel.
$listaProvincias = new gvHidraList('codigoProvincia','PROVINCIAS'); $this->addList($listaProvincias);
Como su propio nombre indica, el origen de datos de estas listas vendrá dado por un conjunto de valores indicados de forma estática.
Por lo tanto tendremos que definir la lista únicamente en el constructor de la clase manejadora.
Primero crearemos la lista haciendo uso de la clase gvHidraList(), a la que se le pasa por parámetro el nombre del campo que le hemos dado en la tpl. Ahora ya podemos ir añadiendo las opciones que necesitamos, lo haremos con el método addOption(), nos permitirá añadir tantas opciones como se necesiten.
A continuación vemos un ejemplo para que sólo aparezcan las provincias pertenecientes a la Comunidad Valenciana:
$listaProvincias = new gvHidraList('codigoProvincia'); $listaProvincias->addOption('03','ALICANTE'); $listaProvincias->addOption('12','CASTELLON'); $listaProvincias->addOption('46','VALENCIA'); $listaProvincias->setSelected('12'); $this->addList($listaProvincias);
En este caso, el conjunto de valores posibles se obtienen a partir de una fuente de datos, ya sea de una consulta a base de datos, una clase...
Tal y como se ha indicado al principio, el segundo parámetro indica la fuente que se va a utilizar para obtener el contenido. Estas fuentes se pueden definir a nivel general de gvHIDRA (consultas o tablas comunes) o a nivel particular de cada aplicación, teniendo en cuenta que prevalecen las definidas en la aplicación sobre las generales del framework, si se han definido con el mismo nombre.
Las definiciones de las listas dinámicas deben ser cargadas al arrancar la aplicación, por ello se deben cargar en el constructor del objeto que maneja el panel principal de la aplicación, es decir, en la clase AppMainWindow.php.
Vamos a ver como incluir la fuente de datos, debemos hacer uso del objeto de configuración de gvHidra y del método apropiado según la fuente que carguemos, que pueden ser de dos tipos: fuentes de datos SQL o clases.
List_DBSource
Esta ha sido la fuente de datos habitual para las listas en gvHIDRA. Básicamente consiste en cargar directamente una query que gvHidra se encargará de parametrizar (añadir filtros a la where) para obtener el resultado esperado.
En este caso haremos uso del método setList_DBSource() donde definiremos la query correspondiente, teniendo en cuenta los siguientes puntos:
La consulta ha de seleccionar dos campos, uno se corresponderán con el valor que guardará el campo (le pondremos de alias 'valor' en la query), y el otro corresponderá con la información que visualice la opción de la lista en pantalla (este deberá tener el alias 'descripcion')
Por defecto la ordenación es por el campo 'descripcion asc', aunque podemos modificarla con la clausula ORDER BY.
class AppMainWindow extends CustomMainWindow { public function AppMainWindow() { ... $conf = ConfigFramework::getConfig(); //Tipos $conf->setList_DBSource('TIPOS',"select ctipo as \"valor\", dtipo as \"descripcion\" from tinv_tipos"); //Subtipos $conf->setList_DBSource('SUBTIPOS',"select cstipo as \"valor\", dstipo as \"descripcion\" from tinv_subtipos"); //Estados $conf->setList_DBSource('ESTADOS',"select cestado as \"valor\", destado as \"descripcion\" from tinv_estados"); ... } }
En el ejemplo anterior vemos como con el método setList_DBSource() añadimos la definición de las fuentes de datos que se gastarán en la aplicación para cargar las listas. Este método tiene dos parámetros, el primero es un identificador de la lista, este identificador debe coincidir con el identificador que se le da a la definición de la lista en la clase manejadora (gvHidraList('nombreCampo','TIPOS');); y el segundo es la definición de la consulta SQL tal y como se ha indicado antes, con los alias correspondientes.
List_ClassSource
Estas nos permiten definir como fuente de datos el resultado de un método de una clase. Esta clase, debe implementar la interfaz gvHidraList_Source para que el framework pueda interactuar con ella. Consiste en implementar el método build que será llamado por el framework para obtener el resultado de la consulta. Aquí introducimos un ejemplo sencillo:
/** * Fuente de datos ejemplo * * $Revision: 1.1.2.5 $ */ class ejemploSource implements gvHidraList_Source { public function __construct() { } public function build($dependence,$dependenceType) { $resultado = array( array('valor'=>'01','descripcion'=>'UNO'), array('valor'=>'02','descripcion'=>'DOS'), array('valor'=>'03','descripcion'=>'TRES'), ); return $resultado; } }
De este ejemplo cabe destacar:
La clase implementa la interfaz gvHidraList_Source. Si no implementa esta interfaz, no puede ser admitida como fuente de datos de las listas.
El método build, devuelve como resultado un array. Este array, puede ser array vacio o un array que contiene por cada una de sus posiciones un array con dos índices válidos (valor y descripción).
Al igual que en el caso de las fuentes de datos tipo List_DBSource(), para incluirlas debemos hacer uso del objeto de configuración de gvHidra llamando al método apropiado.En este caso, el método a utilizar es setList_ClassSource. A continuación mostramos algunos ejemplos de carga.
class AppMainWindow extends CustomMainWindow { public function AppMainWindow() { ... $conf = ConfigFramework::getConfig(); $conf->setList_ClassSource('EJEMPLO','ejemploSource'); //Subtipos $conf->setList_ClassSource('SUBTIPOS',"SubTipos"); //Estados $conf->setList_DBSource('ESTADOS',"EstadosSource"); ... } }
En el ejemplo anterior vemos como con el método setList_ClassSource() añadimos la definición de las fuentes de datos que se gastarán en la aplicación para cargar las listas. Este método tiene dos parámetros, el primero es un identificador de la lista, este identificador debe coincidir con el identificador que se le da a la definición de la lista en la clase manejadora (gvHidraList('nombreCampo','TIPOS');); y el segundo es el nombre de la clase que actuará como fuente.
Una vez conociendo como funcionan tanto las listas estáticas como las dinámicas, es muy común que se utilice una mezcla de ambas. Este uso nos será útil, por ejemplo, en el siguiente caso:
$listaProvincias = new gvHidraList('codigoProvincia','PROVINCIAS'); $listaProvincias->addOption('00','Todas'); $listaProvincias->setSelected('00'); $this->addList($listaProvincias);
En el ejemplo añadimos una opción que implica la selección de todas las opciones, hay que tener en cuenta estos valores que se añaden de forma estática, porque al interactuar con la base de datos ese valor no existirá, por lo tanto habrá que añadir un control particular en la clase manejadora.
Otro ejemplo puede ser que el campo de la base de datos admita también nulos, así que tendremos que añadir una opción de valor nulo y descripción en blanco, para darnos la posibilidad de no añadir ningún valor:
$listaProvincias->addOption('',' ');
Una vez que conocemos los dos tipos de listas que podemos tener, hay que decir que podemos tener el caso de que el contenido de la lista sea dependiente de otros campos. Para ello, en la definición de las listas hay que indicar cual es la dependencia, lo haremos mediante el método setDependence() de la clase gvHidraList.
Las definiciones de las listas dinámicas deben ser cargadas al arrancar la aplicación, por ello se deben cargar en el constructor del objeto que maneja el panel principal de la aplicación, es decir, en la clase AppMainWindow.php.
Vamos a ver como incluir la fuente de datos, debemos hacer uso del objeto de configuración de gvHidra y del método apropiado según la fuente que carguemos, que pueden ser de dos tipos: fuentes de datos SQL o clases.
List_DBSource
Esta ha sido la fuente de datos habitual para las listas en gvHIDRA. Básicamente consiste en cargar directamente una query que gvHidra se encargará de parametrizar (añadir filtros a la where) para obtener el resultado esperado.
En este caso haremos uso del método setList_DBSource() donde definiremos la query correspondiente, teniendo en cuenta los siguientes puntos:
La consulta ha de seleccionar dos campos, uno se corresponderán con el valor que guardará el campo (le pondremos de alias 'valor' en la query), y el otro corresponderá con la información que visualice la opción de la lista en pantalla (este deberá tener el alias 'descripcion')
Por defecto la ordenación es por el campo 'descripcion asc', aunque podemos modificarla con la clausula ORDER BY.
class AppMainWindow extends CustomMainWindow { public function AppMainWindow() { ... $conf = ConfigFramework::getConfig(); //Tipos $conf->setList_DBSource('TIPOS',"select ctipo as \"valor\", dtipo as \"descripcion\" from tinv_tipos"); //Subtipos $conf->setList_DBSource('SUBTIPOS',"select cstipo as \"valor\", dstipo as \"descripcion\" from tinv_subtipos"); //Estados $conf->setList_DBSource('ESTADOS',"select cestado as \"valor\", destado as \"descripcion\" from tinv_estados"); ... } }
En el ejemplo anterior vemos como con el método setList_DBSource() añadimos la definición de las fuentes de datos que se gastarán en la aplicación para cargar las listas. Este método tiene dos parámetros, el primero es un identificador de la lista, este identificador debe coincidir con el identificador que se le da a la definición de la lista en la clase manejadora (gvHidraList('nombreCampo','TIPOS');); y el segundo es la definición de la consulta SQL tal y como se ha indicado antes, con los alias correspondientes.
List_ClassSource
Estas nos permiten definir como fuente de datos el resultado de un método de una clase. Esta clase, debe implementar la interfaz gvHidraList_Source para que el framework pueda interactuar con ella. Consiste en implementar el método build que será llamado por el framework para obtener el resultado de la consulta. Aquí introducimos un ejemplo sencillo:
/** * Fuente de datos ejemplo * * $Revision: 1.1.2.5 $ */ class ejemploSource implements gvHidraList_Source { public function __construct() { } public function build($dependence,$dependenceType) { $resultado = array( array('valor'=>'01','descripcion'=>'UNO'), array('valor'=>'02','descripcion'=>'DOS'), array('valor'=>'03','descripcion'=>'TRES'), ); return $resultado; }//Metodo build }
De este ejemplo cabe destacar:
La clase implementa la interfaz gvHidraList_Source. Si no implementa esta interfaz, no puede ser admitida como fuente de datos de las listas.
El método build, devuelve como resultado un array. Este array, puede ser array vacio o un array que contiene por cada una de sus posiciones un array con dos índices válidos (valor y descripción).
Al igual que en el caso de las fuentes de datos tipo List_DBSource(), para incluirlas debemos hacer uso del objeto de configuración de gvHidra llamando al método apropiado.En este caso, el método a utilizar es setList_ClassSource. A continuación mostramos algunos ejemplos de carga.
class AppMainWindow extends CustomMainWindow { public function AppMainWindow() { ... $conf = ConfigFramework::getConfig(); $conf->setList_ClassSource('EJEMPLO','ejemploSource'); //Subtipos $conf->setList_ClassSource('SUBTIPOS',"SubTipos"); //Estados $conf->setList_DBSource('ESTADOS',"EstadosSource"); ... } }
En el ejemplo anterior vemos como con el método setList_ClassSource() añadimos la definición de las fuentes de datos que se gastarán en la aplicación para cargar las listas. Este método tiene dos parámetros, el primero es un identificador de la lista, este identificador debe coincidir con el identificador que se le da a la definición de la lista en la clase manejadora (gvHidraList('nombreCampo','TIPOS');); y el segundo es el nombre de la clase que actuará como fuente.
Una vez conociendo como funcionan tanto las listas estáticas como las dinámicas, es muy común que se utilice una mezcla de ambas. Este uso nos será útil, por ejemplo, en el siguiente caso:
$listaProvincias = new gvHidraList('codigoProvincia','PROVINCIAS'); $listaProvincias->addOption('00','Todas'); $listaProvincias->setSelected('00'); $this->addList($listaProvincias);
En el ejemplo añadimos una opción que implica la selección de todas las opciones, hay que tener en cuenta estos valores que se añaden de forma estática, porque al interactuar con la base de datos ese valor no existirá, por lo tanto habrá que añadir un control particular en la clase manejadora.
Otro ejemplo puede ser que el campo de la base de datos admita también nulos, así que tendremos que añadir una opción de valor nulo y descripción en blanco, para darnos la posibilidad de no añadir ningún valor:
$listaProvincias->addOption('',' ');
Las listas tienen una serie de métodos especiales que permiten su manipulación en las acciones. Para acceder a una lista desde una acción de este tipo se debe hacer uso de los siguientes métodos:
getLista:obtenemos la lista con la que queremos trabajar.
clean: limpiamos los valores dejándola vacia.
setLista: fijamos una lista.
setSelected: marcamos un valor como seleccionado.
getDescription: devuelve la descripción del valor seleccionado.
getSelected: devuelve el valor seleccionado.
toArray: obtenemos una lista en formato array.
arrayToObject: cargamos un objeto lista con un array.
A continuación mostramos un ejemplo de uso:
$lcuentaFe = $objDatos->getLista('cuenta_fe'); $lcuentaFe->clean(); $lcuentaFe->addOption('',''); if (count($datos)>0) { foreach($datos as $datos_lista) { //valor, descripcion $lcuentaFe->addOption($datos_lista['valor'],$datos_lista['descripcion']); } } $lcuentaFe->setSelected(''); $objDatos->setLista('cuenta_fe',$lcuentaFe); ...
El elemento checkbox podemos emplearlo también para una lista de valores, nos permitirá elegir más de una opción ya que no serán excluyentes. Para definir el checkbox hay que hacer uso de la clase gvHidraCheckBox y de sus metodos, que son:
setValueChecked($value): Fija el valor que se quiere tener cuando el check está marcado.
getValueChecked(): Devuelve el valor que tiene el check cuando está marcado.
setValueUnchecked($value): Fija el valor que se quiere tener cuando el check está desmarcado.
getValueUnchecked(): Devuelve el valor que tiene el check cuando está desmarcado.
setChecked($boolean): Indicar si el checkbox aparece marcado o no por defecto.
De este modo en la clase manejadora tendremos que crear el checkbox y definir las propiedades:
//Creamos checkbox y lo asociamos a la clase manejadora $filCoche = new gvHidraCheckBox('filCoche'); $filCoche->setValueChecked('t'); $filCoche->setValueUnchecked('f'); $this->addCheckBox($filCoche);
En la tpl definiremos el checkbox de la siguiente forma:
{CWCheckBox nombre="filCoche" editable="true" textoAsociado="Coche" dataType=$dataType_claseManejadora.filCoche valor=$defaultData_claseManejadora.filCoche}
Es importante añadir el parámetro dataType que es el que asociará la definición dada en la clase manejadora con el plugin.