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 !!!!

La ética en la empresa

miércoles, 4 de junio de 2008
Una empresa está constituida y existe para crear bienes y/o servicios útiles para la sociedad, y a partir de esta creación o desarrollo (etc.) obtener beneficios de manera tal que la empresa obtenga un lugar en el mercado y surja dentro de éste, haciéndose de un buen nombre que sea reconocido en la mayor cantidad de lugares posibles.

Y basados en la definición principal de empresa, qué significa útil para la sociedad ??. Muchas veces he escuchado frases como "una empresa existe para ganar dinero" o "una empresa debe centrarse en el desarrollo interno, el bien comercial", etc., pero y qué pasa con el cliente ??

Útil para la sociedad significa proveer productos y/o servicios que satisfagan las necesidades de los consumidores (clientes y usuarios) sin desmedro de éstos ni otros directa o indirectamente.

Existe un problema, que muchos conocen, y es que muchas empresas solo se concentran en el beneficio propio y olvidan lo fundamental que es el cliente. Así surgen sitios como www.reclamos.cl en donde pueden ver la inmensa cantidad de reclamos, denuncias y demandas que los usuarios hacen en contra de distintas empresas de diversos mercados, qué esta pasando ??

Centrémonos en el caso de las empresas IT, como los proveedores de servicios de acceso a Internet (ISP).

Durante años, en nuestro país, hemos visto como las empresas hacen fusiones, las cuales sabemos se utilizan para reducir costos y aumentar beneficios. Pero para quién son las mejoras ??, para el cliente definitivamente no.

Estas fusiones, como la de la antigua Metrópolis y VTR solo han ocasionado problemas a sus clientes.

Caso personal:
Yo era cliente de Metrópolis y después por fuerza bruta de VTR. El servicio fue pésimo, el trato indigno, y llegué al extremo de perder mi línea telefónica por los problemas que me ocasionaron y los tuve que demandar al sernac

Estas fusiones ocurren sin el conocimiento ni menos la participación del cliente, a cuantos clientes se les consultó sobre si estaban de acuerdo con la fusión de las dos empresas ? a cuantos siquiera se les notificó las repercusiones que éstos hechos tendría ?

Algunos dirán: Bueno, esas son decisiones de empresa, el cliente no trabaja ahí no tiene nada que ver. Y yo les digo: Lean la definición de empresa y entiendan que una empresa existe por y para el cliente.

El tema que surge aquí es la toma de decisiones por parte de la empresa sin consultar ni notificar al cliente. No involucran al cliente en ninguna etapa mas que en el cobro de la cuenta.

Todos sabemos que una toma de decisiones afecta a todos los niveles de una empresa en mayor o menor medida, pero muy pocas veces se habla de las repercusiones al cliente, simplemente se toman y el cliente debe acatar ... por qué ? si como cliente soy el que pago las cuentas ? y si yo soy el que pago por que otros deben tomar las decisiones que me corresponden ? y mi derecho como ciudadano y cliente ?

Actualmente tengo contrato de acceso a Internet con Telefónica Chile, en el contrato está especificado que no hay un bloqueo de puertos para uso de software p2p que al parecer se respeta (personalmente no he tenido problemas con las descargas), pero si tengo un problema con permitir el acceso a otras personas hacia mi equipo. Telefónica se niega a darme la clave del router Zyxel P-660HW-T1 v2 y no puedo configurar los puertos correspondientes a mi equipo.

La respuesta ante este problema fue:

Debe llamar a atención comercial para solicitar desbloqueo de puertos y re direccionamiento remoto de los mismos. Usted no puede hacer eso desde el router, nosotros lo hacemos de forma remota. Es por su seguridad.


A raíz de lo anterior surgen algunas preguntas básicas:
  • y quién les pidió que se preocupen por mi seguridad ?
  • y no se supone que no bloquean puertos ? (está en el contrato)
  • y por qué tengo que solicitar que me abran los puertos de forma remota ?
  • por qué no lo puedo hacer yo desde el router ?
  • debo llamar y solicitar permiso cada vez que quiera abrir o cerrar un puerto en mi equipo ?
  • debo pedirles permiso por utilizar mi equipo ?

Otro problema típico con empresas como Telefónica Chile es no atender al cliente si éste no utiliza un sistema operativo Windows. En una ocasión tuve problemas con mi conexión y llamé a soporte técnico, le expliqué que había un problema de planta y empezó con el típico: vaya inicio, cmd ... etc. Le dije que no usaba Windows y me dijo que no me podía dar soporte y me cortó la llamada.

Como ven algunas empresas toman decisiones por nosotros que nos afectan directamente, haciéndonos perder el tiempo y en algunos casos dinero y recursos (todas las anteriores en mi caso).

Donde está la ética en la empresa moderna ?? se preocupan de reducir costos, aumentar beneficios, mejorar procesos internos, aplicar ingeniería de vanguardia en la cadena de producción, pero y por qué se toman las atribuciones para tomar una decisión tan personal como la configuración de puertos de mi equipo ?? por qué debo pedir permiso al ISP para dar acceso a mis amigos a mi equipo ??

Como mencioné al principio, las empresas están olvidando para quién trabajan, están mordiendo la mano de quien les da de comer y si siguen así se van a ir llenando de demandas (ya demandé a VTR y gané, tal vez sea el turno de Telefónica Chile).

Nosotros como profesionales IT tenemos el deber de velar por la seguridad de nuestros usuarios y clientes, pero jamás tomarnos las atribuciones de tomar una decisión personal de ellos y por ellos.

La ética no le corresponde solo a los médicos y a los abogados (por ejemplo el caso de la confidencialidad de información), nos corresponde a todos y si trabajamos con y para personas no debemos olvidar darles el lugar que les corresponde.

Está mal que las empresas se tomen atribuciones personales de los clientes y si usted lector tiene su propia empresa mas vale que tome este tema en cuenta, ya que la relación que tenga con sus clientes marcará la diferencia entre si obtiene beneficios o se va a pérdida por demandas o por que sus clientes lo abandonan.

Y ustedes estimados lectores, qué opinan sobre la toma de decisiones por ustedes ?? existe la ética en la empresa moderna ?? están de acuerdo en pedir permiso a una empresa para utilizar sus equipos como les plazca ??

saludos !!!