Primefaces dialog is rendering twice

14,137

Solution 1

In my case I cannot user oncompleteI) method to hide the dialog because it has to be closed to some business logic.

I my case I have use primefaces tabs on UI. Every time I navigate the tabs and then click on button on which dialog appears then my dialogs number are increasing proportionality So I have used simple jquery script to remove all the duplication dialog from the UI e UI.

function removeDuplicateDialogs(dialogId) {

    \\ generally all our components have : character we have to 
    \\ replace ':' with '\\:'(applying escape character)
    dialogId = dialogId.replace(/\:/g, '\\:');

    var dialogs = jQuery("div[id=" + dialogId + "]");
    var numOfDialogs = dialogs.length;
    numOfDialogs = numOfDialogs - 1;
    for (var i = 0; i < numOfDialogs; i++) {
        jQuery(dialogs[i]).remove();
    }
}

Solution 2

I've posted the same question in primefaces forum (like Tommy Chan told), and someone answered this:

You are probably placing your dialog in the form you are updating which is a nono. Never update the dialog only the stuff in the dialog

I've tried to do this until I saw all my dialogs have "rendered" attribute coming from server (just see the first xml), I have a lot of dialogs in this application and some of them have relation with others (on server), these last are on the same form.

I did something different, I only created this javascript code:

function removerDialogo(id) {
   setTimeout(function() {
       removerDialogoAposIntervalo(id);
   }, 100);  
}

function removerDialogoAposIntervalo(id) { 
   id = id.replace(':', '\\:');
   jQuery('div.ui-dialog')
       .find('#' + id)
       .parent().eq(1)
       .remove(); 
}

and called this on dialog "onShow" attribute:

<p:dialog widgetVar="#{idPopup}" id="#{idPopup}" modal="#{popup.modal}"
    draggable="#{popup.modal}" rendered="#{popup.visivel}"
    visible="#{popup.visivel}" closeOnEscape="false" closable="false"
    header="#{titulo}" resizable="false" styleClass="autoWidthDialog"
    showEffect="fade" hideEffect="fade" onShow="removerDialogo(this.id)">

I don't like to do things like this, but I can't find a better way to solve this... If someone give me a better solution, I will be grateful

Solution 3

As i said on the primefaces forum, you are updating your forms with the dialog in it... you need to place your dialogs out of your form and update them seperatly. If you need to use a form in your dialog then place it in you dialog:

   <p:dialog><p:form> </p:form> </p:dialog>

Solution 4

I had the same problem with a dialog, the solution was place in the update of the commandButton that show the dialog component the specific id of the Dialog Component not the form id, the solution looks like this:

    <p:dialog id="dialogId">
        <p:commandButton value="OK" style="float:right"
             update="@form dialogId"
             action="#{controladorPopup.submit}"
             process="@form"/>
    </p:dialog>
Share:
14,137

Related videos on Youtube

brevleq
Author by

brevleq

@brevleq

Updated on June 04, 2022

Comments

  • brevleq
    brevleq almost 2 years

    I've created an ui:component to use like a popup, so I can create a lot of popups using the standard of this template. The component is just a popup with two buttons (cancel and submit) and a content that can be overriden, like you can see here:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.prime.com.tr/ui">
    <ui:component>
    <p:dialog widgetVar="#{idPopup}" id="#{idPopup}" modal="#{popup.modal}"
        draggable="#{popup.modal}"
        rendered="#{popup.visivel}" visible="#{popup.visivel}"
        closeOnEscape="false" closable="false" header="#{titulo}"
        resizable="false" styleClass="autoWidthDialog" showEffect="fade"
        hideEffect="fade">
        <h:panelGroup style="width:100%">
            <p:focus />
            <ui:insert name="conteudo">Nenhum conteúdo definido!</ui:insert>
            <h:panelGrid id="#{idPopup}PainelMensagens" style="width:100%">
                <p:messages />
            </h:panelGrid>
            <ui:insert name="barraDeBotoes">
                <h:panelGroup layout="block" style="width:100%">
                    <p:commandButton value="CANCELAR" immediate="true" update="@form"
                        style="float:right" action="#{controladorPopup.fechar}"
                        onclick="#{idPopup}.hide();" />
                    <p:commandButton value="OK" style="float:right"
                        update="@form formAlerta"
                        action="#{controladorPopup.submit}"
                        process="@form" />
                </h:panelGroup>
            </ui:insert>
        </h:panelGroup>
    </p:dialog>
    </ui:component>
    </html>
    

    The problem happen when I try to submit the form without filling the required fields. The correct behavior is just show again the popup with messages, but the dialog is rendered twice, one with the messages and one without the messages. You can see this behavior here:

    twice rendering

    this is one use of this template:

    <ui:composition template="../templates/popupSubmit.xhtml">
    <ui:param name="titulo" value="Buscar pessoa" />
    <ui:param name="popup" value="#{modeloPopupBuscaPessoa}" />
    <ui:param name="controladorPopup"
        value="#{controladorPopupBuscaPessoa}" />
    <ui:define name="conteudo">
        <h:panelGroup>
            <h:panelGrid columns="2">
                <h:outputLabel value="Tipo de cadastro:" style="float:none" />
                <h:selectOneMenu value="#{controladorSugestaoPessoa.tipoCadastro}"
                    immediate="true">
                    <f:selectItems value="#{carregadorTipoCadastro.itens}" />
                    <f:ajax event="change" immediate="true" />
                </h:selectOneMenu>
            </h:panelGrid>
            <h:outputText value="Buscar por:" />
            <h:selectOneRadio value="#{controladorSugestaoPessoa.tipoBusca}"
                immediate="true">
                <f:selectItems value="#{carregadorTipoBuscaPessoa.itens}" />
                <f:ajax event="change" immediate="true" />
            </h:selectOneRadio>
            <p:autoComplete value="#{modeloPopupBuscaPessoa.itemSelecionado}"
                forceSelection="true" maxResults="10" queryDelay="500" 
                completeMethod="#{controladorSugestaoPessoa.atualizarSugestoes}"
                var="pessoa" itemLabel="#{pessoa.label}" itemValue="#{pessoa}"
                converter="#{conversorSelectItem}" />
        </h:panelGroup>
    </ui:define>
    </ui:composition>
    

    And these are some use:

    <h:form id="cadastroPessoa">
        <ui:include
            src="resources/components/popups/modulo_cadastro/popupNovoCadastroPessoa.xhtml">
            <ui:param name="idPopup" value="popupNovoCadastroPessoa" />
        </ui:include>
        <ui:include
            src="resources/components/popups/modulo_cadastro/popupCadastroPessoa.xhtml">
            <ui:param name="idPopup" value="popupEdicaoCadastroPessoa" />
        </ui:include>
        <ui:include
            src="resources/components/popups/modulo_cadastro/popupBuscaPessoa.xhtml">
            <ui:param name="idPopup" value="popupBuscaCadastroPessoa" />
        </ui:include>
    </h:form>
    
    <h:form id="cadastroProduto">
        <ui:include
            src="resources/components/popups/modulo_cadastro/popupCadastroProduto.xhtml">
            <ui:param name="idPopup" value="popupNovoCadastroProduto" />
        </ui:include>
    </h:form>
    

    Could someone tell me why this is happening??

    • Bhesh Gurung
      Bhesh Gurung over 12 years
      Can you also post the code in the template and template-client that relates to this fragment?
    • BalusC
      BalusC over 11 years
      Not sure if it's the cause of the whole problem, but designing the dialog as an include file is somewhat strange. A tag file or a composite component is a more sensible choice. Also, the dialog should also have its own <h:form> and not be placed inside any <h:form>. You don't want to submit/process all other fields in the page outside the dialog in the same form when submitting the fields in the dialog.
  • brevleq
    brevleq over 12 years
    I've already tried this option, the dialog open twice but they are closed immediately.
  • brevleq
    brevleq over 12 years
    the id of the two dialog are the same: cadastroEmpresa:popupNovoCadastroEmpresa
  • Tommy Chan
    Tommy Chan over 12 years
    perhaps ask a question on the primefaces forum...users there are very responsive.
  • Lyrion
    Lyrion over 12 years
    Ha! That was my comment on the primefaces forum. (Lyrionus right? ;)) the reason i said that was because your updates say @form... and your dialog hasn't a form tag around it... so that means its above your dialog... which means your dialog is in the form.
  • brevleq
    brevleq over 12 years
    Hi Rafael, as I told, I tried this approach, but the application is very big and this approach can't be used with that composition in a generic way. This is because of the relation of some dialogs. To do this I need to change all application logic... But certainly I will implement in the correct way the next time :) Thanks.
  • Lyrion
    Lyrion over 12 years
    @brevleq Ahh didn't see that, have you tried instead of placing the renderers on your dialog, placing it in the panelgrid. I know it's a crappy solution but i can't think of anything better at the moment :p
  • Juan
    Juan over 12 years
    Something similar is happening to me, im using ajax to send forms content and every time i click on the button that shows me the dialog, it will render as many dialogs as submits via ajax ive made, i have seen that if i refresh the whole page, it will start again (rendering 1 dialog, 2, 3, etc)
  • Kawu
    Kawu over 11 years
    PrimeFaces widgetVar and JSF id must not be the same. I read that "golden" rule in a posting by Optimus himself somewhere in the forums. Can't find it right now.
  • hendrix
    hendrix over 10 years
    Which event are you calling the script on?
  • cabaji99
    cabaji99 over 5 years
    Fixed with this answer, in my case i was updating all the form instead of just the component. causing the dialog to appear twice.