ComboBox en JMaki con NetBeans 6.1, publish and suscribe

jueves, 5 de junio de 2008
Ayer un amigo lector de éste blog me envió un correo preguntando como lo podía hacer para obtener el valor de un Widget JMaki ComboBox, ya que él había probado el método que expliqué en ésta entrada pero no servía. En efecto, el método explicado ahí solo retorna el nombre de la etiqueta y no el valor que se requiere.

El método corresponde al siguiente:


var fecha = jmaki.getWidget('fecha').getValue();


pero este retorna el label del combobox y no el value.

Me explico, cuando uno usa un ComboBox, generalmente muestra un nombre al usuario y por debajo quiere manejar un código, entonces el usuario al seleccionar un nombre específico de la lista quiere obtener el código que le corresponde y hacer algo con éste.

El nombre corresponde al label o etiqueta y el código corresponde al value o valor.

Entonces me dispuse a leer varios sitios y en el el sitio oficial de jmaki encontré la respuesta (era lo mas lógico verdad ??).

Es bastante simple la verdad. Debemos crear nuestra página jsp como queramos y agregamos un widget combobox de la biblioteca dojo, hasta aquí es bastante simple ya que solo arrastramos el widget desde el panel de la derecha a la página jsp.

Lo nuevo que haremos será crear un Bean que utilizaremos para cargar los datos en el widget en vez de hacerlo directamente en el jsp. Esto es mas elegante, útil y seguro. Lo mas probable es que los datos provengan de una base de datos, de seguro que ninguno querrá obtener los datos de la base de datos directamente desde el jsp.

El Bean (ComboBoxBean) es bastante sencillo para éste ejemplo, simplemente contendrá un arreglo de Strings con un par de países y un arreglo de Strings con códigos de los países.


protected String[] paises= new String[] { "Chile", "Argentina", "España", "Estados Unidos"};


protected String[] codigoPaises = new String[] { "CL", "AR", "ES", "US" };


Lo que tenemos que tener en cuenta es que para retornar los datos no basta con hacer un simple método get y retornar el arreglo String, debemos transformar los datos a un form JSON. Esto lo hacemos de la siguiente forma:


public String getPaises() throws JSONException {

JSONArray datosPaises = new JSONArray();

JSONObject datosPais = new JSONObject();

for (int loop = 0; loop < paises.length; loop++) {

datosPais.put("label", paises[loop]);

datosPais.put("value", codigoPaises[loop]);

datosPaises.put(datosPais);

datosPais = new JSONObject();

}

return jsonArrayToString(datosPaises, new StringBuffer());

}


pero debemos definir el método jsonArrayToString


public String jsonArrayToString(JSONArray ja, StringBuffer buff) throws JSONException {

if (buff == null)

buff = new StringBuffer("[");

else

buff.append("[");



for (int key=0; (ja != null) && key < ja.length(); key++) {

String value = null;

if (ja.optJSONObject(key) != null){

jsonToObjectLibertal(ja.optJSONObject(key), buff);

} else if (ja.optJSONArray(key) != null) {

jsonArrayToString(ja.optJSONArray(key), buff);

} else if (ja.optLong(key, -1) != -1) {

value = ja.get(key) + "";

buff.append(value);

} else if (ja.optDouble(key, -1) != -1) {

value = ja.get(key) + "";

buff.append(value);

} else if (ja.optBoolean(key)) {

value = ja.getBoolean(key) + "";

buff.append(value);

} else if (ja.opt(key) != null) {

Object obj = ja.opt(key);

if (obj instanceof Boolean) {

value = ja.getBoolean(key) + "";

} else {

value = "'" + ja.get(key) + "'";

}

buff.append(value);

}

if (key < ja.length() -1) buff.append(",");

}

buff.append("]");



return buff.toString();

}



y necesitamos el método jsonToObjectLibertal


public String jsonToObjectLibertal(JSONObject jo, StringBuffer buff) throws JSONException {

if (buff == null)

buff = new StringBuffer("{");

else

buff.append("{");



JSONArray names = jo.names();

for (int l=0; (names != null) && l < names.length(); l++) {

String key = names.getString(l);

String value = null;

if (jo.optJSONObject(key) != null){

value = key + ":";

buff.append(value);

jsonToObjectLibertal(jo.optJSONObject(key), buff);

}else if (jo.optJSONArray(key) != null) {

value = key + ":";

buff.append(value);

jsonArrayToString(jo.optJSONArray(key), buff);

} else if (jo.optLong(key, -1) != -1) {

value = key + ":" + jo.get(key) + "";

buff.append(value);

} else if (jo.optDouble(key, -1) != -1) {

value = key + ":" + jo.get(key) + "";

buff.append(value);

} else if (jo.opt(key) != null) {

Object obj = jo.opt(key);

if (obj instanceof Boolean) {

value = key + ":" + jo.getBoolean(key) + "";

} else {

value = key + ":" + "'" + jo.get(key) + "'";

}

buff.append(value);

}

if (l < names.length() -1) buff.append(",");

}

buff.append("}");



return buff.toString();

}



Estos 3 métodos no los hize yo, solo modifiqué una ínfima parte para adaptarlos al ejemplo, el código lo saqué de uno de los tutoriales de JMaki (apenas lo encuentre pongo la URL).

Ya con eso tenemos listo el Bean que llenará el widget combobox de datos de forma elegante, limpia y sencilla.

Ahora toca ir al jsp en donde tenemos el widget combobox. El tag debería lucir así:


<a:widget name="dojo.combobox" value="${ComboBoxBean.paises}" publish="/micombobox"/>


y al inicio del jsp agregar las siguientes lineas:


<jsp:useBean id="ComboBoxBean" scope="session" class="org.ComboBoxBean"/>

<%@ taglib prefix="a" uri="http://jmaki/v1.0/jsp" %>


en donde deben cambiar el nombre del Bean al que corresponda.

Antes de continuar explicaré de que se trata el publish y el subscribe en JMaki.

El publish se utiliza para definir un nombre específico a un widget específico (com un ID), con el cual se diferenciará de otros al momento de registrar eventos. El publish se define como un argumento en el widget.

El registro de eventos se hace utilizando el subscribe y se define en el archivo glue.js.

Utilizando publish y subscribe se manejan de forma limpia los eventos asociados a widgets. Cada widget puede tener varios eventos asociados y cada evento se le puede asociar a muchos widgets, una relación de muchos a muchos, en donde cada widget define lo que hace independientemente de los demás, a través de la configuración del subscribe correspondiente en el archivo glue.js.

Dicho y explicado lo anterior, agregamos al jsp un div en donde colocaremos el código del país seleccionado de forma dinámica.


<div id="valorSeleccionado"></div>


Una vez listo abrimos el archivo glue.js y agregamos al final lo siguiente:


jmaki.subscribe("/micombobox/onSelect", function(args){

var value = args.value;

var targetDiv = document.getElementById("valorSeleccionado");

if(targetDiv)

targetDiv.innerHTML = "El codigo de este pais es: " + value;

});


Si se fijan, el subscribe es específico para el widget de publish "micombobox" y el evento "onSelect", pudiendo subscribir el mismo evento a otros widgets u otros eventos al mismo widget (muchos a muchos), donde para cada widget se define un evento de forma personalizada.

Con el código anterior obtenemos el código del país seleccionado y lo agregamos al div correspondiente.

En esta parte podemos hacer lo que queramos con el dato seleccionado, podríamos enviarlo a un servlet utilizando la función jmaki.doAjax y almacenarlo en una sesión o hacer otra cosa.

A continuación pueden ver algunas screenshots mostrando la funcionalidad descrita en esta entrada:



Como ven, utilizando Beans y los métodos publish y subscribe el llenado de datos y obtención de los mismos mediante un ComboBox de JMaki es realmente simple.

Espero les sea de utilidad.

ya saben, si quieren el código me lo piden y se los envío por correo.

saludos !!!


EDITADO!!!

Subí el código a un servidor para que puedan hacer la descarga sin necesidad de enviarme sus correos (así no tienen que esperar a que yo lea el correo para rebotarlo a ustedes), si tienen problemas para la descarga seguimos con el método tradicional del correo electrónico.

Descarga

saludos !!!!

5 comentarios:

Unknown dijo...

Excelente !!!

Muchas Gracias!!!

Anónimo dijo...

Que bien!!

Por fa, si puede enviarme el codigo a fulgore11@hotmail.com Gracias :)

santiago dijo...

Felicidades por el blog. Está exelente. va directo a mis Feeds!

Daniel Dario Morales Salas dijo...

Se agradecen sus comentarios. Seguiré publicando articulos y guias de distintas cosas útiles.

saludos !!!

Anónimo dijo...

http://metalklesk.blogspot.com/2007/10/web-service-y-web-service-client-en.html?showComment=1331929254296#c6016518849438985271

Publicar un comentario