7

I'm trying to implement the answer from BalusC in this post, but it is not working when I try to make the required condition depend on a button outside a Wizard, that I'm using to control the "back" and "next" of the wizard. How can achieve this?

<h:form id="form" enctype="multipart/form-data" acceptcharset="ISO-8859-1" >  

    <p:growl id="growl" sticky="true" showDetail="true"/>  

    <p:wizard id="wizard" flowListener="#{myBean.onFlowProcess}" showNavBar="false" widgetVar="wizardWV"> 

        <p:tab id="tab1" title="Tab 1"  >  
            <p:panel header="Panel for tab 1">  

                <p:message for="year" />
                <br /> 

                <table>
                    <tr>
                        <td>
                            <h:outputLabel value="Year: "  />
                        </td>
                        <td>
                            <p:inputMask 
                                id="year"
                                value="#{myBean.year}" 
                                required="#{not empty param[nextPanel.clientId]}"
                                requiredMessage="Year is required!"
                                style="width:70px;"  
                                mask="9999" 
                                maxlength="4" 
                            />
                        </td>
                    </tr>
                </table>
            </p:panel>
        </p:tab>

        <p:tab id="tab2" title="Tab 2"  >  
            <p:panel header="Panel for tab 2">  
            </p:panel>
        </p:tab>

    </p:wizard>

    <p:commandButton id="backPanel"  value="Back" onclick="PF('wizardWV').back();" styleClass="internalButton"  />
    <p:commandButton id="nextPanel" binding="#{nextPanel}" value="Next" onclick="PF('wizardWV').next();" styleClass="internalButton" />

</h:form> 
Cœur
  • 32,421
  • 21
  • 173
  • 232
reidestis
  • 195
  • 2
  • 14
  • 4
    Does the Wizard's back button in first place really need to perform a full postback (submit the whole form)? Looks like it can just be a `type="button"` or a `` (with `return false` in end of `onclick`). That would also instantly solve the "unnecessary validation" problem. Else just add `process="@this"` if you absolutely need to make it a postback. – BalusC Mar 11 '14 at 15:23
  • @BalusC,, thanks for the answer, but I didn't get it... making the button as with return false; at the end of onclick, or adding process="@this" for the didn't solve my problem. The next button still goes to the next panel without validating anything.. and I need that each panel to be validate only when I click in the next button.. – reidestis Mar 24 '14 at 03:25
  • I didn't said anything about the next button. – BalusC Mar 24 '14 at 07:56
  • 1
    @BalusC But what did you mean by "That would also instantly solve the unnecessary validation problem."? Because making the button without postback, makes no validation to be performed at all – reidestis Mar 24 '14 at 11:58

1 Answers1

1

why this question has not been answered? like @BalusC said, the answer is simple, just put @process="this"

<h:form>
    <p:wizard id="wizard" showNavBar="false" widgetVar="wizardWV">
        <p:tab id="tab0" title="Tab 0">
            <p:panel header="Panel for tab 0">
                blablabla
            </p:panel>
        </p:tab>

        <p:tab id="tab1" title="Tab 1">
            <p:panel header="Panel for tab 1">
                <p:message for="year" />
                <br />

                <h:panelGrid columns="2">
                    <h:outputLabel value="Year: " />
                    <p:inputMask id="year" value="#{myBean.year}" required="true"
                        requiredMessage="Year is required!" style="width:70px;" mask="9999"
                        maxlength="4" />
                </h:panelGrid>
            </p:panel>
        </p:tab>

        <p:tab id="tab2" title="Tab 2">
            <p:panel header="Panel for tab 2">
                blablabla
            </p:panel>
        </p:tab>
    </p:wizard>

    <p:commandButton value="Back" onclick="PF('wizardWV').back();" />
    <p:commandButton process="@this" value="Next" onclick="PF('wizardWV').next();" />
</h:form>

or better, to avoid duplicate ajax request

<p:commandButton type="button" value="Back" onclick="PF('wizardWV').back();" />
<p:commandButton type="button" value="Next" onclick="PF('wizardWV').next();" />

but i really don't see the point in using a custom nav bar for wizard in this case.


if you mean "skin" by mentioning "design", the right approach is to override PF CSS styles:

Wizard resides in a container element that style and styleClass attributes apply.
Following is the list of structural css classes.

Selector               Applies
.ui-wizard             Main container element.
.ui-wizard-content     Container element of content.
.ui-wizard-step-titles Container of step titles.
.ui-wizard-step-title  Each step title.
.ui-wizard-navbar      Container of navigation controls.
.ui-wizard-nav-back    Back navigation control.
.ui-wizard-nav-next    Forward navigation control.

But if you really mean "design", intended like features/functionalities, yes, you can interact with wizard by its "widget" and, like you did, define your own controls. In your specific case i don't see a "design" difference, i see a standard behavior of the wizard component, where current wizard tab is processed (and all its components validated) on next button pressed.

Validation is triggered ONLY for processed components (that are inside execution list), and you may control this list with process="..." attribute of any ajax component/event.

What you probably want is to change the default behavior of another component in that page wich processes @all or @form.

From what you say in your comment, you have at least another component in that page which has an ajax behavior, like a p:autocomplete and, probably, you are using PF < 4.0.

In this case you can add process="@this" to the p:autocomplete to prevent processing (and then validation) of other components inside the wizard tab, like your p:inputMask.


@Erick, the first thing that comes into my mind is this:

<p:wizard binding="#{wizardComponent}" ...>
    <p:tab id="tab0" ...>
        ...
    </p:tab>
    ...
</p:wizard>
<p:commandButton rendered="#{wizardComponent.step != 'tab0'}" value="Back" onclick="PF('wizardWV').back();" />
Michele Mariotti
  • 6,983
  • 4
  • 37
  • 69
  • thanks for the answer. Firstly, the point in using a custom nav bar is the ability to use your own designed buttons. Secondly, you didn't understand what I'm trying to do. The required condition cannot be true, the validation can ONLY be triggered by the next button. The way you suggested, any other element in the page that iterates with the faces bean, will trigger the validation, for instance an primefaces autocomplete. – reidestis May 20 '14 at 02:39
  • When using a custom nav var, how will I be able to display the back button only when necessary? i.e: not in the first tab – Erick Sep 08 '15 at 22:15
  • @MicheleMariotti thank you! But before I tried implementing it that way, could you take a look at this question that I posted yesterday and see if you have an answer for it? http://stackoverflow.com/questions/32468421/how-to-prevent-primeface-wizard-next-button-activate-client-validations – Erick Sep 09 '15 at 12:57