Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

OnChange no funciona en sub popup

2013-11-25
2015-02-24
  • Oscar Kozto
    Oscar Kozto
    2013-11-25

    Hola, cordial saludo:

    Tengo un modulo PROGRAMACION, con un combo (se llama Accion) anotado con @OnChange, el cual tiene dos opciones: Alarma de estado y Alarma de alimentacion.

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="action")
    @OnChange(value=ProgramacionAlCambiarAccionAction.class)
    private ProgramacionAccion accion;
    

    Cuando cambia la opcion del combo se cambia la interfaz, como se muestra a continuacion:

    Al cambiar a Alarma de estado:

    ModuloProgramacion_AlarmaEstado

    Al cambiar a Alarma de alimentacion:

    ModuloProgramacion_AlarmaAlimentacion

    Hasta ahi todo correcto, pero cuando no entro directamente a PROGRAMACION, sino que sigo este camino:

    Entro a modulo PLAN DE ACCION, el cual tiene una Coleccion TAREAS

    ModuloPlanDeAccion_NuevaTarea

    En la coleccion doy clic en nueva TAREA, lo cual me abre un popup, cada TAREA tiene una coleccion de PROGRAMACIONES (alarmas):

    ModuloPlanDeAccion_PopupNuevaTarea

    En la coleccion doy clic en nueva PROGRAMACION (alarma), se abre un subpopup:

    Si cambio entre Alarma de alimentacion y Alarma de estado, la interfaz NO CAMBIA:

    ModuloPlanDeAccion_PopupNuevaTarea_PopupNuevaProgramacion1

    ModuloPlanDeAccion_PopupNuevaTarea_PopupNuevaProgramacion2

    Ahora si dentro de este subpopup, doy clic en nuevo USUARIO, se abre un subsubpopup, cuando lo cierro, ahora si reacciona la interfaz, y cambia de acuerdo a lo seleccionado en el combo:

    ModuloPlanDeAccion_PopupNuevaTarea_PopupNuevaProgramacion3

    ModuloPlanDeAccion_PopupNuevaTarea_PopupNuevaProgramacion4

    ModuloPlanDeAccion_PopupNuevaTarea_PopupNuevaProgramacion5

    Relacion en las entidades:

    TAREA:
    
    public class Tarea {
        .
        .
    
        @OneToMany(mappedBy="tarea", cascade = CascadeType.ALL)
        private Collection<TareaIniciativa> tareasIniciativa = new ArrayList<TareaIniciativa>();
    
        @OneToMany(mappedBy="tarea", cascade = CascadeType.ALL)
    private Collection<ProgramacionTarea> programacionesTarea = new ArrayList<ProgramacionTarea>();
    
        .
        .
    }
    
    PLAN DE ACCION (Iniciativa)
    
    public class Iniciativa {
        .
        .
    
        @OneToMany(mappedBy="iniciativa", cascade = CascadeType.ALL)
    private Collection<TareaIniciativa> tareasIniciativa = new ArrayList<TareaIniciativa>();
    
        .
        .
    }
    
    TAREA - PLAN DE ACCION (Iniciativa)
    
    public class TareaIniciativa {
    
    @Id
    @AsEmbedded    // ANOTACION ASEMBEDDED
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="task")
    private Tarea tarea;
    
        @Id
    @DescriptionsList(descriptionProperties="nombre")
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="initiative")
    private Iniciativa iniciativa;
    
        .
        .
        .
    }
    
    PROGRAMACION (alarmas)
    
    public class Programacion {
        .
        .
        @OneToMany(mappedBy="programacion", cascade = CascadeType.ALL)
    private Collection<ProgramacionTarea> programacionesTarea;
    
        .
        .
        .
    }
    
    PROGRAMACION - TAREA
    
    public class ProgramacionTarea {
        .
        .
    
        @Id
    @AsEmbedded    // ANOTACION ASEMBEDDED
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="schedule")
    private Programacion programacion;
    
        @Id
    @DescriptionsList(descriptionProperties="nombre")
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="task")
    private Tarea tarea;
    
        .
        .
        .
    }
    

    Esto es un bug de OpenXava, tienen algo que ver la anotaciones @AsEmbedded ?

    Agradezco de antemano las respuestas que me puedan dar una luz al respecto

    Oscar

     
    Last edit: Oscar Kozto 2013-11-25
  • JOSE ELIAS
    JOSE ELIAS
    2013-11-26

    Hola Oskar

    Serías tan amable de mostrarme cómo hacer para mostar una IU u otra en función de la opción seleccionada?

     
    • Oscar Kozto
      Oscar Kozto
      2013-11-27

      Hola Jose, aunque deberias crear un nuevo topico, igual te muestro como lo hice:

      Primero la entidad:

      @Entity
      //CantidadDeTiempo y AlarmaDeEstado son agrupaciones
      @View(members="nombre; accion; AlarmaDeEstado[parametro]; CantidadDeTiempo[minutos, horas; dias, meses]")
      public class Programacion {
          .
          .
          .
      @ManyToOne(fetch=FetchType.LAZY)
      @JoinColumn(name="action")
      @OnChange(value=ProgramacionAlCambiarAccionAction.class)
      private ProgramacionAccion accion;
      
          .
          .
          .
      }
      

      Ahora la accion:

      package net.ejemplo.actions;
      
      import java.util.*;
      import org.openxava.actions.*;
      import org.openxava.view.*;
      
      public class ProgramacionAlCambiarAccionAction extends ViewBaseAction implements IOnChangePropertyAction {
      
          private String collectionViewObject;
      
          @Override
          public void execute() throws Exception {
      
              String accion = (String) getView().getValue("accion.nombre");   //valor seleccionado en el combo (select)
      
              if (accion == null) {
                  accion = "feedingalarm";
              }
      
              //CantidadDeTiempo y AlarmaDeEstado son agrupaciones definidas en @View
              if (accion.equals("feedingalarm")) {
                  desocultarCampo("CantidadDeTiempo");    
                  ocultarCampo("AlarmaDeEstado");         
              }
              else if (accion.equals("statealarm")) {
                  ocultarCampo("CantidadDeTiempo");
                  desocultarCampo("AlarmaDeEstado");
              }
      
          }
      
          public void desocultarCampo(String nombreCampo) {
              if (getView().isHidden(nombreCampo)) {
                  getView().setHidden(nombreCampo, false);
              }
          }
      
          public void ocultarCampo(String nombreCampo) {
              if (!getView().isHidden(nombreCampo)) { 
                  getView().setHidden(nombreCampo, true);
              }
          }
      
          @Override
          public void setChangedProperty(String propertyName) {
              // TODO Auto-generated method stub      
          }
      
          @Override
          public void setNewValue(Object value) {
              // TODO Auto-generated method stub      
          }
      
      }
      
       
  • Javier Paniza
    Javier Paniza
    2013-11-27

    Hola Oscar,

    Esto es un bug de OpenXava, tienen algo que ver la anotaciones @AsEmbedded ?

    No lo he probado, pero si dices que abres un diálogo, lo cierras y después de eso ya funciona, no parece que tenga que ver con tu código, sino que parece un bug de OpenXava.
    ¿Qué versión de OpenXava estás usando? Si no estás usando la última, pruebalo con la última y si aun así te falla añadelo como bug con un vínculo a este hilo y lo arreglaremos.


    Ayuda a otros en este foro como yo te ayudo a ti.

     
  • Oscar Kozto
    Oscar Kozto
    2013-11-27

    Hola Javier, al inicio usaba 4.7, luego actualice a la ultima version: la 4.8.1, esperando que se solucionara el problema, pero el comportamiento es el mismo.

    Lo voy a reportar como un bug entonces.

    Muchas gracias por la respuesta.

     
  • Jefferson
    Jefferson
    2014-01-15

    Buenas Javier.

    Revisando este tema me encuentro que el error ocurre es por la diferencia del ID del componente en el Formulario, que se desea refrescar.

    Cuando el modulo se encuentra directamente solo, los ID son iguales y el proceso de refrescar funciona bien, pero cuando el procesos forma parte de un Popup, el ID del componente a refrescar no queda escrito como debe ser. Por lo cual el proceso que lo busca no encuentra el ID que debería tener asignado.

    Me explico el proceso openxava.setFocus en javascript, busca el formulario y lo encuentra, cuando procede a buscar la parte a refrescar, el trata de buscar "ox_Fenix_Tarea__programacionesTarea_programacion_minutos", pero el que se encuentra dentro del form es "ox_Fenix_Tarea_programacion_minutos".

    La diferencia como se ve, es que el programacionTarea, que es el modulo intermedio, no es asignado al ID visual, por lo que causa que el proceso busca un identificar que no fue bien definido. Me puedes ayudar, en que clase o jsp, se crean esos ID de los Div, para encontrar la solución mas prontamente.

     
  • Javier Paniza
    Javier Paniza
    2014-01-17

    Hola Jefferson,

    los ids se generan mediante la tag <xava:id/> cuyo código esta en org.openxava.web.taglib.IdTab que a su vez delega en la clase org.openxava.web.Ids. Échale un vistazo al código.


    Ayuda a otros en este foro como yo te ayudo a ti.

     
  • Jefferson
    Jefferson
    2014-01-17

    Hola Javier,

    Gracias por la respuesta y disculpa que te vuelva a molestar con este caso, me encuentro que lo que pasa con el ID, es porque cuando empieza el ciclo, el crea el ID de la vista, cuando empieza a iterar los módulos internos, es donde cambia el nombre del ID.

    Inicia con ProgramacionTarea.view.programacion
    Continua con el modulo interno Programacion.view.nombre

    Y es aquí donde se pierde la relación de la información del ID, porque empieza a crearlos como el modulo Programación, pero como te conté el enfoque se encuentra sobre la vista.

    Este incidente ocurre dentro del detail.jsp. en el ciclo de
    Iterator it = view.getMetaMembers().iterator()

    Tu me puedes ayudar, que podría incluir, para no perder la relación, porque no se como incluir al inicio el ProgramacionTarea.

    Gracias de antemano.

     
  • Javier Paniza
    Javier Paniza
    2014-01-20

    Hola Jefferson,

    pues no lo sé. Me tendría que poner a mirarlo. A veces a mi mismo me cuesta varios días resolver un bug y rara vez se de antemano lo que hay que tocar para arreglarlo.

    El mayor reto no es hacer que los ids salgan bien para tu caso, es hacer que salgan bien sin romper el resto de OpenXava. Lo primero que hago es una prueba jUnit y después ya me pongo a mirar donde puede estar el fallo. Sería un detalle si creas una prueba jUnit con sus clases del modelo y las adjuntas a la incidencia.


    Ayuda a otros en este foro como yo te ayudo a ti.

     
  • Javier Paniza
    Javier Paniza
    2015-02-24

    Hola Oscar:

    Como puedes ver en el bug:
    https://sourceforge.net/p/openxava/bugs/406/

    Al final no es un bug, sino tu forma de escribir la acción al cambiar.

    La mejora forma de hacer una acción al cambiar es heredar de OnChangePropertyBaseAction donde getView() siempre es la vista del elemento que ha cambiado. Está hecho así justo para que las acciones al cambiar funcionen desde cualquier sitio.

    Es decir, cambia:

    public class ProgramacionAlCambiarAccionAction extends ViewBaseAction implements IOnChangePropertyAction {
    

    Por:

    public class ProgramacionAlCambiarAccionAction extends OnChangePropertyBaseAction {
    

    Para que te funcione bien.


    Ayuda a otros en este foro como yo te ayudo a ti.