Hace un tiempo estuve leyendo el tutorial de la antes SUN sobre JSF y estos días estoy leyendo sobre jQuery. Por aquello de jugar un poco con ambas cosas me dije: voy a hacer un proyectito. Una lista de tareas web con base de datos y JSF, pero que se puedan ordenar arrastrándolas con el ratón usando sortable de jQuery. Por supuesto, cada vez que se arrastra una fila de la lista y se coloca en otra posición, debería almacenarse su nueva posición en base de datos.
Pues nada, me pongo a ello. Con JSF me hago toda la parte de base de datos, lista de tarear y botones para editar, borrar y crear.
Ahora me pongo con la parte de jQuery. Lo de hacer la tabla "sortable" y arrastrar las filas de un lado para otro sin ningún problema. Toca hacer la persistencia…. y ahí es donde han empezado mis problemas.
Con jQuery puedo enterarme cuándo se arrastra una fila y hacer una pequeña llamada jQuery.ajax() para indicarle al servidor el nuevo orden y que lo guarde en base de datos. La primera "pega"es que no hay forma fácil de llamar desde jQuery a un managed bean de JSF.La solución pasa por hacerse un JSP normalito o Servlet para recoger esas llamadas jQuery.ajax(). Ese JSP sí puede intentar conseguir el ManagedBean de JSF y hacer la llamada correspondiente.
La segunda pega de momento es más insalvable de una forma sencilla. Con jQuery y sortable() puedo obtener el orden de los elementos por su id del tag html. Es decir, si uso un <table> y quiero ordenar los <tr>, cada <tr> debe tener un id <tr id="algo">….</tr>. En la llamada a jQuery.ajax() se pasaría como parámetro esa lista de id de los <tr> en el orden en que están en pantalla. Y este id debería ser el id de la Tarea en esa fila, de esta forma cuando esa lista de id llegue al servidor, este sabrá el orden de las tareas.
Pero JSF, con su tag DataTable usa columnas y no pone ningún id a los <tr>. Y no hay forma de ponérselo de ninguna forma fácil. Tampoco con javascript/jQuery se puede poner a posteriori, porque jQuery no puede acceder al ManagedBean que ha generado la fila y por tanto a su id. Posiblemente se puede poner una columna oculta con los id de tarea y así jQuery podría poner el id al <tr> según el valor de la columna oculta… pero se me hace un poco "artificioso".
Y ahí me he atascado. JSF no pone id a los <tr> ni forma fácil de hacerlo. JQuery no puede acceder a los ManagedBean para poner ese id a posteriori.
Resumiendo, me hace la impresión de que cada tecnología sirve para lo que sirve y no siempre es fácil usar varias de ellas a la vez.
Hola, desde javascript si que se puede llamar a una managedBean de forma facil, utilizando la etiqueta
Con esto, declaras en el jspx o xhtml la función js que la puedes invocar desde cualquier fichero .js. Ademas, a esa funciones le puedes asignar eventos de jsf como cualquier otro componente.
En cuanto a lo que quieres hacer con la tabla, podrías pasarle a la función que declares con a4j:jsFunction el numero de fila y columna y en el bean, a través del binding obtener el elemento deseado, no es muy complicado.
JSF es muy potente, aunque tiene un ciclo de vida demasiado sobre-dimensionado para mi gusto.
Hola:
Gracias por los comentarios, tengo que seguir probando a ver.
De todas formas, si con jQuery cambio los elementos de la tabla en el navegador…. ¿se va a enterar el managed bean con el binding de ese cambio o va seguir pensando que tiene lo último que él ha pintado?
Gracias de nuevo.
Si, para eso es el binding, en el ciclo de vida de JSF, hay una etapa que actualiza los valores del bean con lo que esta en el html
Por que utilizar JQuery? complicas lo facil! Con Rich Faces tengo solucionado ese tema….
Bueno, como casi siempre, mi objetivo no es la aplicación en sí, sino aprender. Si lo que no quisiera es complicarme la vida, me bajaría cualquiera de los gestores de tareas que hay por internet, gratis y más «molones» que el que yo me haga 😉
Se bueno.
Por la forma de trabajar que tiene JSF, no es sencillo integrar algo como el Ajax de jQuery con JSF así nada más. Se puede, pero es complicado.
Como dijeron, A4J (Ajax4Java) que hace un tiempo pasó a formar parte de RichFaces, lo resuelve. Incluso, internamente usa jQuery y Protopype. Y agrega algunos componentes JSF para facilitar la integración de jQuery con JSF en caso de usarlo directamente.
Seam2, que por defecto usa RichFaces como implementación de JSF, viene muy bien integrado con Ajax a su vez, y agrega un par de bondades más. Por ejemplo, tenemos Seam Remoting: que permite hacer invocaciones al backend desde JavaScript, serializando objetos java/javascript de forma transparente para nosotros. También viene integrado con RestEasy, que nos permite publicar servicios RestFull desde Seam, que pueden ser usados fácilmente desde jQuery vía ajax() y/o loadJSON().
Cada alternativa tiene sus ventajas y desventajas, hay que ver qué alternativa nos conviene en cada caso.
Con JSF/Ajax de RichFaces/A4J + Seam, es muy rápido (muchísimo) desarrollar, pero se paga con un consumo alto en recursos si nos descuidamos. Con jQuery + REST + JSON + Seam podemos hacer un sitio muy liviano y con ínfimo consumo de recursos, a costa de mayor desarrollo por nuestra parte (aunque haciendo las cosas bien, aplicando patrones, reutilizando componentes, se compensa).
A veces conviene tener el control absoluto y fino. Otras conviene una solución rápida.
Hola Chuidiang, tan solo decirte que si lo consigues avísame si puedes, ya que ando liado con lo mismo, y no hay manera.
Gracias!!!
Hola gorlok, es interesante el comentario que haces sobre la integración de RichFaces/A4J + Seam, tendran algun link, documentación o tutorial donde pueda ver esta ingración en acción, cual App Server me recomiendan para esta ingración, GlassFish, Jboss, Tomcat ???. Gracias por sus comentarios.