Me encontré este interesante artÃculo de Dan McGhan en el que trata el tema que a continuación se trata de definir:
Supongamos que se tienen dos listas de valores, digamos DEPARTAMENTOS y EMPLEADOS, ambas con un valor por defecto definido a “Todos”, puesto que EMPLEADOS depende de DEPARTAMENTOS, en el momento en que se cambie el valor de DEPARTAMENTOS, EMPLEADOS es reseteado. Lo que debería suceder es que EMPLEADOS sea re-evaluado, como en el siguiente ejemplo: Digamos que DEPARTAMENTOS está seleccionado a “Todos” y EMPLEADOS a “García”. Si luego cambiamos DEPARTAMENTOS a “Contabilidad” y “García” pertenece al departamento de contabilidad, entonces EMPLEADOS debería mantener la selección de “García”, pues es un valor válido para EMPLEADOS.
Entonces, la pregunta sería: ¿es posible mantener el valor seleccionado de un campo si ese mismo valor existe en la lista de valores después de refrescarse? Gracias a los nuevos eventos en APEX y a las Acciones Dinámicas, la solución es mucho más sencilla de lo que era en el pasado.
Existen tres eventos principales de los cuales se debe preocupar cuando se trata de selecciones en cascada:
- change
- apexbeforerefresh
- apexafterrefresh
El evento change es una parte estándar de JavaScript y de DOM. Este evento se dispara cuando el usuario manualmente cambia el valor de la lista de selección, pero puede ser disparado también de manera programática vía JavaScript. Los eventos apexbeforerefresh y apexafterrefresh son eventos personalizados en Apex. Ellos se disparan antes y justamente después de que solicitudes AJAX refrescan algo dentro de una página. Los eventos trabajan con muchos campos y regiones que utilizan esta tecnología.
En el ejemplo que estamos tratando, tenemos dos listas de selección: una padre y la otra hija. SI se cambia el valor de la lista hija, el evento change se dispara y eso es todo. SI en cambio se modifica el valor de la lista padre, suceden un muchas cosas más a la selección hija. A continuación algunas de las cosas que suceden:
- Los valores actuales de la lista son limpiados
- Se dispara el evento apexbeforerefresh
- Una solicitud AJAX obtiene los nuevos valores, lo cual sucede solo si:
- optimize refresh está definido como FALSE
- optimize refresh está definido como TRUE y todos los campos padres no son nulos
- El evento apexafterrefresh es disparado
- El evento change es disparado
Conociendo todo lo anterior, ¿Cómo podemos utilizar la secuencia de eventos para resolver el problema original de mantener los valores seleccionados? La respuesta está en crear dos acciones dinámicas.
La primer acción dinámica lo que hará es almacenar el valor actual de la lista de selección, de manera que podamos accesarlo posteriormente. Esto típicamente sucederá cuando se dispara el evento change, pero también sucede cuando la página se carga por primera vez. Siga el siguiente procedimiento para crear la primera Acción Dinámica:
- Estando en Vista de Árbol, haga clic con el botón derecho sobre la lista de selección hija y seleccione Crear Acción Dinámica
- Seleccione Avanzado
- Haga clic en el botón “Siguiente >”
- Ingrese un nombre para la primera acción dinámica, por ejemplo “Guarda Empleado Seleccionado”
- Haga clic en el botón “Siguiente >”
- Seleccione “Cambiar” en la lista Evento
- Haga clic en el botón “Siguiente >”
- En en campo Acción seleccione la opción “Ejecutar Código JavaScript”
- En el campo Código ingrese:
$(this.triggeringElement).attr(‘data-last-value’, $(this.triggeringElement).val());
- Haga clic en el botón “Siguiente >”
- Haga clic en el botón “Crear”
La segunda Acción Dinámica toma ventaja del evento apexafterrefresh y accesa el valor previamente almacenado, valor que será utilizado para buscar en las nuevas opciones si una coincidencia existe para entonces seleccionarla. Para esto aplicamos en siguiente procedimiento:
- Haga clic derecho nuevamente en la lista hija y seleccione Crear Acción Dinámica
- Seleccione Avanzada
- Haga clic en el botón “Siguiente >”
- Ingrese un nombre para la siguiente acción dinámica
- Haga clic en el botón “Siguiente >”
- Seleccione “After Refresh” en el campo Evento
- Haga clic en el botón “Siguiente >”
- En el campo Acción seleccione la opción “Ejecutar Código JavaScript”
- En el campo Código, ingrese lo siguiente:
$(this.triggeringElement).children(‘option[value=”‘ + $(this.triggeringElement).attr(‘data-last-value’) + ‘”]’).attr(‘selected’,’selected’);
- Haga clic en el botón “Siguiente >”
- Por último haga clic en el botón “Crear”
Y eso es todo, solo tiene que probarlo.
Puede encontrar un ejemplo funcional aquí