7

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?

AjMeen
  • 734
  • 2
  • 13
  • 26
  • 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 Jan 17 '13 at 16:18
  • @Mindwin it seems that it's not being called at all. Can't see any JS errors too. – AjMeen Jan 17 '13 at 16:41

2 Answers2

22

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.

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
kolossus
  • 19,953
  • 3
  • 45
  • 94
  • Thanks for your answer! I did what you have told me to do, but now I'm getting this error: `/user/editSkills.xhtml @39,121 itemValue="#{skill.id}": The class 'java.lang.String' does not have the property 'id'.` What is strange I think it's connected with picklist and it's weird, cause picklist works fine. What should I do? – AjMeen Jan 18 '13 at 16:51
  • @AjMeen, that's a different issue altogether,probably caused by the fact that `#{skill.id}` and `#{skillslevel.level}` are not the same datatype(one of them is a string, the other is something else). But now your commandButton is definitely firing. – kolossus Jan 18 '13 at 17:26
  • `#{skillslevel.level}` has nothing to do with this error, cause even if I remove `skilsslevel` part the error still shows up. I just probably need a converter. Anyway thanks for help! – AjMeen Jan 18 '13 at 18:08
  • @AjMeen, You're welcome. You should only need a converter if `itemValue` is a POJO/complex type. Look at [this answer](http://stackoverflow.com/a/13710569/1530938). The question directly correlates to yours – kolossus Jan 18 '13 at 19:04
  • i am having the same problem, tried this but didn't work: http://stackoverflow.com/questions/31350850/pdialog-form-submission-doesnt-invoke-action-method?lq=1 – amphibient Jul 10 '15 at 22:32
4
<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".

  • you shouldn't need immediate="true" or process="@this". However your answer had the quick bit of information I needed. Thanks! – Eric Dec 06 '16 at 21:24