7
votes

I'm trying to use primefaces <p:dialog> combined with <p:commandButton>. In my .xhtml page I have a picklist and commandButton which is used to show a dialog. Dialog displays datatable with target values from picklist. Dialog has two buttons: cancel and submit. My problem is that submit button is not fired. What's strange, commandButton out of dialog works.

Here's my .xhtml:

<body>
   <ui:composition template="./../resources/mainTemplate.xhtml">
        <ui:define name="content">
            <h:form>
                <p:dialog id="dlg" header="#{messages.chooseSkillLevel}" widgetVar="dlg" modal="true" dynamic="true">
                    <h:dataTable value="#{editSkills.skillsAndLevels}" var="skillslevel">
                        <h:column>
                            #{skillslevel.skill.umiejetnosc}
                        </h:column>
                        <h:column>
                            <p:selectOneMenu value="#{skillslevel.level}" >
                                <f:selectItems value="#{editSkills.levels}" var="level" itemLabel="#{level.stopien}" itemValue="#{level.id}" />
                            </p:selectOneMenu>
                        </h:column>
                    </h:dataTable>
                    <p:commandButton value="#{messages.confirm}" action="#{editSkills.showSkillsAndLevels}" oncomplete="dlg.hide();" />   THIS BUTTON IS NOT FIRED
                    <p:commandButton value="#{messages.cancel}" onclick="dlg.hide()"/>
                </p:dialog>
                <p:pickList value="#{editSkills.skills}" var="skill" effect="none"  
                itemValue="#{skill.id}" itemLabel="#{skill.umiejetnosc}"  
                showSourceFilter="true" showTargetFilter="true" filterMatchMode="contains" 
                addLabel="#{messages.add}" removeLabel="#{messages.remove}" removeAllLabel="#{messages.removeAll}" >  
                    <f:facet name="sourceCaption">#{messages.skillsList}</f:facet>  
                    <f:facet name="targetCaption">#{messages.yourSkills}</f:facet>
                    <p:ajax event="transfer" listener="#{editSkills.onTransfer}" /> 
                    <p:column style="width:100%;">  
                        #{skill.umiejetnosc}  
                    </p:column> 
                </p:pickList>
                <p:commandButton value="#{messages.confirm}" action="#{editSkills.afterSubmit}" update="dlg" oncomplete="dlg.show()" />   THIS BUTTON WORKS FINE
                <p:commandButton value="#{messages.cancel}" action="profile" immediate="true"/>
           </h:form>
        </ui:define>
    </ui:composition>
</body>

I've marked working button and not working one. What do I have to do to make it working?

2
Have you looked at the console, its not making an ajax call? or is it simply not working? Try looking in firebug if its sending data to server, or is the AJAX firing and the method #{editSkills.showSkillsAndLevels} is not being called at all? Also check if firebug is not showing any JS errors. - Mindwin
@Mindwin it seems that it's not being called at all. Can't see any JS errors too. - AjMeen

2 Answers

22
votes

You can try either of the following , I vote number one, it's a cleaner design IMO

  1. Bring the <p:dialog/> outside of the general <h:form/> and put an <h:form/> inside it instead

      <p:dialog id="dlg" header="#{messages.chooseSkillLevel}" widgetVar="dlg" modal="true" dynamic="true">
          <h:form>
                <h:dataTable value="#{editSkills.skillsAndLevels}" var="skillslevel">
                    <h:column>
                        #{skillslevel.skill.umiejetnosc}
                    </h:column>
                    <h:column>
                        <p:selectOneMenu value="#{skillslevel.level}" >
                            <f:selectItems value="#{editSkills.levels}" var="level" itemLabel="#{level.stopien}" itemValue="#{level.id}" />
                        </p:selectOneMenu>
                    </h:column>
                </h:dataTable>
                <p:commandButton value="#{messages.confirm}" action="#{editSkills.showSkillsAndLevels}" oncomplete="dlg.hide();" />   THIS BUTTON IS NOT FIRED
                <p:commandButton value="#{messages.cancel}" onclick="dlg.hide()"/>
               </h:form>
            </p:dialog>
    
  2. Add appendToBody="false" to the <p:dialog/> to ensure the dialog is rendered within the html form in the DOM instead of being auto-relocated to end of HTML body. But this may cause inconsistent rendering in various browsers.

4
votes
<p:commandButton  value="Cancel" oncomplete="PF('yourDialogWidgedVarName').hide();" process="@this"  />

Make sure to use ' when u call the widgetVar name. You can also use immediate="true" or process="@this".