5 Replies Latest reply on Sep 28, 2007 3:06 AM by Alexander Belov

    Modal panel problem

    madman1 Newbie

      Sorry for my english.

      How can I do something like this.

      <h:form>
       <a4j:outputPanel ajaxRendered="true">
       <rich:modalPanel id="dialog" showWhenRendered="true" rendered="#{dialogManager.currentDialog != null}">
       <f:facet name="header">
       <h:outputText value="#{dialogManager.currentDialog.title}"/>
       </f:facet>
       <t:div>
       <h:outputText value="#{dialogManager.currentDialog.titleMessage}" styleClass="modalpanel-title"/>
       </t:div>
       <t:div>
       <h:graphicImage value="#{dialogManager.currentDialog.image}"/>
       <h:outputText value="#{dialogManager.currentDialog.message}"/>
       </t:div>
       <t:div>
       <a4j:commandButton value="#{dialogManager.currentDialog.acceptButtonText}" action="#{dialogManager.clickOnAcceptButton}" oncomplete="Richfaces.hideModalPanel('dialog')"/>
       <a4j:commandButton value="#{dialogManager.currentDialog.cancelButtonText}" rendered="#{dialogManager.currentDialog.cancelButtonText != null && dialogManager.currentDialog.cancelButtonText != ''}" action="#{dialogManager.clickOnCancelButton}" oncomplete="Richfaces.hideModalPanel('dialog')"/>
       </t:div>
       </rich:modalPanel>
       </a4j:outputPanel>
      </h:form>
      


      <managed-bean>
       <managed-bean-name>dialogManager</managed-bean-name>
       <managed-bean-class>com.cms.application.backingbeans.ModalPanelDialogManager</managed-bean-class>
       <managed-bean-scope>session</managed-bean-scope>
       </managed-bean>


      package com.cms.application.backingbeans;
      
      import com.cms.business.CommandProcessor;
      import com.cms.business.command.Command;
      import com.cms.business.command.DataAccessCommand;
      import com.cms.common.utils.Messages;
      import com.cms.common.utils.Utils;
      import java.util.concurrent.PriorityBlockingQueue;
      
      /**
       * En ocasiones es necesario mostrar un ventana de diálogo (modal panel), informando de un error, advertencia, mensaje.... o lo que corresponda.
       * Incluso puede darse el caso de que al realizar ciertas operaciones, sea necesario pedirle confirmación al usuario para realizar las mismas. Pero
       * esto no sea descubierto hasta una vez llegada la petición al servidor. Así pues es necesario un método que permita pedir la confirmación al usuario,
       * y posteriormente realizar la misma.
       *
       * Precisamente éste es el propósito de la clase. Servir de único punto para la creación de ventanas de diálogo que deberán ser mostradas al usuario.
       *
       * El modo de funcionamiento será el siguiente, en cualquier punto de la aplicación se podrá añadir una nuevo diálogo a ser mostrado. A la lista
       * de diálogos pendientes de ser mostrados. Una vez hecho esto, la presente clase se encargará de mostrar 1 a 1, las ventanas de diálogo que
       * correspondan. Según su prioridad, tipo...
       *
       * Actualmente se contemplan 2 tipos de ventanas modales, aquellas destinadas a informar, ya sea de un error, advertencia o información.
       * Estas serán las primeras en ser mostradas, según el orden anteriormente expuesto: error, advertencia, información.
       *
       * Y el segundo tipo se tratará de ventanas, que además de proporcionar una información, podrán desembocar en la ejecución de operaciones
       * (patrón command). Ejemplo, se sube un nuevo fichero a la aplicación, pero al intentar insertarlo se descubre que el fichero ya existe.
       * ¿Debemos sobreescribirlo? La solución será el preguntarle al usuario, y en caso de que acepte, el fichero será sobreescrito (ejecutada la operación).
       * Y en caso de que no se acepte, simplemente no se hará nada. Y se seguirá con el proceso normal.
       *
       *
       * @author Ricardo Fanjul Fandiño
       */
      public class ModalPanelDialogManager {
      
       /**
       * Prioridad de los diálogos usados para mostrar excepciones ocurridas en el servidor.
       */
       private static final int EXCEPTIONS_PRIORITY = 10;
      
       /**
       * Prioridad para los diálogos, que implican la ejecución de una operación "peligrosa". Por ejemplo que implica borrar un fichero.
       */
       private static final int WARNING_TO_DO_COMMAND = 5;
      
      
       private PriorityBlockingQueue<DialogContent> dialogs = new PriorityBlockingQueue<DialogContent>();
      
       private DialogContent currentDialog;
      
       /** Creates a new instance of ModalPanelDialogManager */
       public ModalPanelDialogManager() {
       }
      
       public void addWarningToDoCommand(String title, String titleMessage,String message, Command command){
       DialogContent dialog = createDialog(title, titleMessage, message, Utils.getMessage(Messages.ICON_WARNING_96), Utils.getMessage(Messages.TEXT_YES), Utils.getMessage(Messages.TEXT_NO), command, WARNING_TO_DO_COMMAND);
       dialogs.add(dialog);
       }
      
       private DialogContent createDialog(String title, String titleMessage, String message, String image, String acceptText, String cancelText, Command command, int priority){
       return new DialogContent(title, titleMessage, message, image, acceptText, cancelText, command, priority);
       }
      
       public DialogContent getCurrentDialog() {
       if(currentDialog == null){
       currentDialog = dialogs.poll();
       }
       return currentDialog;
       }
      
       /**
       * Es ejecutado como respuesta al evento desembocado por pulsar en el boton "aceptar" de la ventana de diálogo en la interfaz de usuario.
       * Con ello ejecutamos la operación asociada a este diálogo (command), si es que la huviera.
       *
       * Y establecemos el diálogo actual a <CODE>null</CODE>.
       * @return <CODE>null</CODE>, para que se genere una respuesta Ajax.
       */
       public String clickOnAcceptButton(){
       Command command = currentDialog.getCommand();
       currentDialog = null;
      
       if (command instanceof DataAccessCommand){
       CommandProcessor.processDataAccessCommand((DataAccessCommand) command);
       } else {
       //TODO en este momento todos los objetos command, también derivan a DataAccesCommand
       }
       return null;
       }
      
       /**
       * Es ejecutado como respuesta al evento desembocado por pulsar en el boton "cancelar" de la ventana de diálogo en la interfaz de usuario.
       *
       * Se pone a <CODE>null</CODE>, el diálogo actual.
       * @return <CODE>null</CODE>, para que la respuesta sea tratada como una respuesta Ajax.
       */
       public String clickOnCancelButton(){
       currentDialog = null;
       return null;
       }
      
      }
      


      package com.cms.application.backingbeans;
      
      import com.cms.business.command.Command;
      
      /**
       * Esta clase almacena los datos necesarios para crear una ventana de diálogo por parte de la clase ModalPanelDialogManager. Entre otros almacena:
       * <ul>
       * <li>El título del díalogo</li>
       * <li>La imagen a ser mostrada, ejemplo una imagen con el simbolo de un error</li>
       * <li>El texto a ser mostrado</li>
       * <li>El texto a ser mostrado en los botones "aceptar" y "cancelar", el segundo es opcional</li>
       * <li>La operación (patrón command), que será ejecutada al pulsar el botón "aceptar", si es que la huviera.</li>
       * <li>La prioridad de la ventana de diálogo, es decir si huviera varias pendientes de ser mostradas. Cual será en primer lugar.</li>
       * </ul>
       *
       *
       * "Note: this class has a natural ordering that is inconsistent with equals."
       *
       * @author Ricardo Fanjul Fandiño
       */
      public class DialogContent implements Comparable{
      
       /**
       * Título de la ventana de diálogo
       */
       private String title = "";
      
       /**
       * Título del cuerpo del mensaje.
       */
       private String titleMessage = "";
      
       /**
       * Mensaje en el cuerpo de la ventana de diálogo.
       */
       private String message = "";
      
       /**
       * Path hacia la imagen.
       */
       private String image = "";
      
       /**
       * El texto del botón "aceptar".
       */
       private String acceptButtonText = "";
      
       /**
       * El texto del botón cancelar, si su varlos es <code>null</code> o la cadena vacía. Dicho botón no será mostrado.
       */
       private String cancelButtonText = "";
      
       /**
       * Operación que será ejecutada al pulsar el botón "aceptar".
       */
       private Command command = null;
      
       /**
       * Prioridad del diálogo, los diálogos con mayor prioridad serán los primeros en ser mostrados.
       * Cuanto mayor sea el número mayor será la prioridad. Es decir
       * 0 < 5, una prioridad de 5 es mayor que una de 0.
       * -8 < 33, una prioridad de 33 es mayor que una de -8.
       */
       private int priority = 0;
      
       /** Creates a new instance of DialogContent */
       public DialogContent() {
       }
      
       public DialogContent(String title, String titleMessage, String message, String image, String accept, String cancel, Command command, int priority){
       this.title = title;
       this.titleMessage = titleMessage;
       this.message = message;
       this.image = image;
       this.acceptButtonText = accept;
       this.cancelButtonText = cancel;
       this.command = command;
       this.priority = priority;
       }
      
       public int compareTo(Object o) {
       return priority - ((DialogContent)o).priority;
       }
      
       public String getTitle() {
       return ""+System.currentTimeMillis();
       //return title;
       }
      
       public void setTitle(String title) {
       this.title = title;
       }
      
       public String getMessage() {
       return message;
       }
      
       public void setMessage(String message) {
       this.message = message;
       }
      
       public String getImage() {
       return image;
       }
      
       public void setImage(String image) {
       this.image = image;
       }
      
       public String getAcceptButtonText() {
       return acceptButtonText;
       }
      
       public void setAcceptButtonText(String acceptButtonText) {
       this.acceptButtonText = acceptButtonText;
       }
      
       public String getCancelButtonText() {
       return cancelButtonText;
       }
      
       public void setCancelButtonText(String cancelButtonText) {
       this.cancelButtonText = cancelButtonText;
       }
      
       public Command getCommand() {
       return command;
       }
      
       public void setCommand(Command command) {
       this.command = command;
       }
      
       public int getPriority() {
       return priority;
       }
      
       public void setPriority(int priority) {
       this.priority = priority;
       }
      
       public String getTitleMessage() {
       return titleMessage;
       }
      
       public void setTitleMessage(String titleMessage) {
       this.titleMessage = titleMessage;
       }
      
      }
      



        • 1. Re: Modal panel problem
          madman1 Newbie

          Now I will explain the code.


          In my application, when I want to show a modal panel with info about a error, warning or anything.

          I put in the ModalPanelDialogManager class, the info about the modal panel that I want to show. This class contains a list of modal panel, that are waiting to be show. And after any request (ajaxRendered="true"), if there are any modal panel
          to show. I show it.

          But the problem, it doesn't work.

          I read de forum, and I think that it's a bug. I read that this don't work.

          <a4j:outputPanel ajaxRendered="true">
           <rich:modalPanel id="dialog" showWhenRendered="true" rendered="#{dialogManager.currentDialog != null}">
           ............................
           </rich:modalPanel>
           </a4j:outputPanel>


          And that the solution, it's reRender only the content of the modal panel.

           <rich:modalPanel id="dialog" showWhenRendered="true" rendered="#{dialogManager.currentDialog != null}">
          <a4j:outputPanel ajaxRendered="true">
           ............................
          </a4j:outputPanel>
           </rich:modalPanel>
          


          But I don't want it that. I need to rereender all the modal panel.

          Are there other way to do it?

          Thanks

          • 2. Re: Modal panel problem
            Alexander Belov Novice

            I have the same problem. See the following:

            http://jira.jboss.com/jira/browse/RF-932

            To tell the truth, release of RichFaces 3.1.0 have too many bugs to use it. Latest snapshoots doen't work good, too. There are many problems with IE.
            I have to use RichFaces 3.1.0 rc2 now. It lets update model panel. There are no many features of 3.1.0 release, but it is more stable.

            • 3. Re: Modal panel problem
              Ilya Shaikovsky Master

              do not wrap modalPanel to ajax rendered a4j:outputPanel..

              In this case - the MP and its JS objects will be replaced during request before oncomplete and man problem rise.

              • 4. Re: Modal panel problem
                madman1 Newbie

                 

                "ilya_shaikovsky" wrote:
                do not wrap modalPanel to ajax rendered a4j:outputPanel..

                In this case - the MP and its JS objects will be replaced during request before oncomplete and man problem rise.


                So, How can I do it in other way? Are there some "hack", to do it?

                I need show the modal panel, only sometimes.
                rendered="#{dialogManager.currentDialog != null}"


                Only if there are a modal panel waiting. Also I need that the modal panel, showWhenRendered="true", and that the content of the modal panel will be update. Because I use it, to show differents messages ("are you sure to overwrite the file", "there are an error...", .....)

                Thanks.

                Is planned to fix this bug?

                • 5. Re: Modal panel problem
                  Alexander Belov Novice

                  You can use data attribute of ajax components to show modalPanel sometimes. And it is not a hack :-).

                  For example:
                  data="#{!empty dialogManager.currentDialog}"
                  oncomplete="if(data){Richfaces.showModalPanel(...);}"

                  To update content of modalPanel, place h:panelGroup into inner form of modalPanel and update it's content.

                  Main problem is updating of facets of modalPanel. For example, changing title or controls. There is no way to do it. And it is a bug, because it worked early.