Page 1 of 2

selectOneMenu - How should I dynamically render components?

Posted: 11 Apr 2012, 15:30
by march_in

Code: Select all

<h:panelGrid columns="2" id="rejestracjaFormPanel">

<p:column />
                        <p:message id="srdSrdIdMessage" for="srdSrdId" />
                        <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_srdSrdId}" for="srdSrdId" />
                        <p:selectOneMenu id="srdSrdId"
                                         value="#{rejestracjaController.selected.srdSrdId}"
                                         title="#{msgs.CreateRejestracjaFormTitle_srdSrdId}"
                                         required="true"
                                         requiredMessage="#{msgs.msgs.CreateRejestracjaForm_srdSrdIdRequired}"
                                         >
                            <f:selectItems value="#{sloRodzajDzialalnosciController.itemsAvailableSelectMany}" />
                            <p:ajax update="rejestracjaFormPanel" />
                        </p:selectOneMenu>

                        <p:column 
                            rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}" />
                        <p:message id="kodPromocjiMessage" for="kodPromocji"
                                   rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}" />
                        <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_kodPromocji}"
                                       for="kodPromocji"
                                       rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}"/>
                        <p:inputText id="kodPromocji" value="#{rejestracjaController.selected.kodPromocji}" title="#{msgs.CreateRejestracjaFormTitle_kodPromocji}"
                                     rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}">
                            <f:validateLength maximum="20" />
                        </p:inputText>
</h:panelGrid>

how should i render some inputs depends on select? When validation fails input is not rendered even if selected value is 1.

Re: selectOneMenu - How should I dynamically render componen

Posted: 11 Apr 2012, 15:51
by Hamsterbau
More information what you want to do with your construct would really help. I guess you want first select one entry in selectOneMenu and after that input some additional informations, right?

If yes, you can wrap your input tags into a p:outputPanel (f. e. with id="hoooray"). If you change your selectOneMenu only update this panel instead of the whole form. If you want to skip validation you should read more about immediate="true".

Re: selectOneMenu - How should I dynamically render componen

Posted: 11 Apr 2012, 16:51
by smithh032772
See code I shared at following URL.

http://lmgtfy.com/?q=site%3Aforum.prime ... ectonemenu

Re: selectOneMenu - How should I dynamically render componen

Posted: 12 Apr 2012, 10:44
by march_in
tnx. i will try with p:outputPanel and read your post smithh032772.
What i need is show/hide some inputs based on selection from selectOneMenu. Lets assume that i want to select type of business and then show some input fields for that kind of business. Some fields are required for particular kinds of business others not. So i don't need to show them and post them. I'm not pretty sure that i need to use:

Code: Select all

<p:ajax update="rejestracjaFormPanel" />
because i don't need to post values, i only need to hide some fields. Do I need to hide them via javascript and onchange?
I'm new in primefaces and jsf.

Hamsterbau is this your solution:

Code: Select all

  <h:form id="rejestracjaForm" prependId="false">
    <h:panelGrid columns="2" id="rejestracjaFormPanel">
                        <p:column />
                        <p:message id="srdSrdIdMessage" for="srdSrdId" />
                        <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_srdSrdId}" for="srdSrdId" />
                        <p:selectOneMenu id="srdSrdId"
                                         value="#{rejestracjaController.selected.srdSrdId}"
                                         title="#{msgs.CreateRejestracjaFormTitle_srdSrdId}"
                                         required="true"
                                         requiredMessage="#{msgs.msgs.CreateRejestracjaForm_srdSrdIdRequired}"
                                         >
                            <f:selectItems value="#{sloRodzajDzialalnosciController.itemsAvailableSelectMany}" />
                            <p:ajax update="rejestracjaFormPanel" />
                        </p:selectOneMenu>

                        <p:outputPanel rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}">
                            <p:column />
                            <p:message id="nazwaMessage" for="nazwa" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_nazwa}" for="nazwa" id="nazwas" />
                            <p:inputText id="nazwa" value="#{rejestracjaController.selected.nazwa}" title="#{msgs.CreateRejestracjaFormTitle_nazwa}">                            
                                <f:validateLength maximum="150" />
                            </p:inputText>

                            <p:column />
                            <p:message id="nazwiskoMessage" for="nazwisko" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_nazwisko}" for="nazwisko" />
                            <p:inputText id="nazwisko" value="#{rejestracjaController.selected.nazwisko}" title="#{msgs.CreateRejestracjaFormTitle_nazwisko}">
                                <f:validateLength maximum="100" />
                            </p:inputText>

                            <p:column />
                            <p:message id="imieMessage" for="imie" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_imie}" for="imie" />
                            <p:inputText id="imie" value="#{rejestracjaController.selected.imie}" title="#{msgs.CreateRejestracjaFormTitle_imie}">
                                <f:validateLength maximum="50" />
                            </p:inputText>

                            <p:column />
                            <p:message id="ulicaMessage" for="ulica" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_ulica}" for="ulica" />
                            <p:inputText id="ulica" value="#{rejestracjaController.selected.ulica}" title="#{msgs.CreateRejestracjaFormTitle_ulica}" required="true" requiredMessage="#{msgs.CreateRejestracjaFormRequiredMessage_ulica}">
                                <f:validateLength maximum="70" />
                            </p:inputText>

                            <p:column />
                            <p:message id="nrDomMessage" for="nrDom" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_nrDom}" for="nrDom" />
                            <p:inputText id="nrDom" value="#{rejestracjaController.selected.nrDom}" title="#{msgs.CreateRejestracjaFormTitle_nrDom}" required="true" requiredMessage="#{msgs.CreateRejestracjaFormRequiredMessage_nrDom}">
                                <f:validateLength maximum="20" />
                            </p:inputText>

                            <p:column />
                            <p:message id="nrLokalMessage" for="nrLokal" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_nrLokal}" for="nrLokal" />
                            <p:inputText id="nrLokal" value="#{rejestracjaController.selected.nrLokal}" title="#{msgs.CreateRejestracjaFormTitle_nrLokal}">
                                <f:validateLength maximum="10" />
                            </p:inputText>
                        </p:outputPanel>
                        <p:outputPanel rendered="#{rejestracjaController.selected.srdSrdId.srdId == 2}">

                            <p:column />
                            <p:message id="nazwiskoMessage" for="nazwisko" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_nazwisko}" for="nazwisko" />
                            <p:inputText id="nazwisko" value="#{rejestracjaController.selected.nazwisko}" title="#{msgs.CreateRejestracjaFormTitle_nazwisko}">
                                <f:validateLength maximum="100" />
                            </p:inputText>


                            <p:column />
                            <p:message id="ulicaMessage" for="ulica" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_ulica}" for="ulica" />
                            <p:inputText id="ulica" value="#{rejestracjaController.selected.ulica}" title="#{msgs.CreateRejestracjaFormTitle_ulica}" required="true" requiredMessage="#{msgs.CreateRejestracjaFormRequiredMessage_ulica}">
                                <f:validateLength maximum="70" />
                            </p:inputText>

                            <p:column />
                            <p:message id="nrDomMessage" for="nrDom" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_nrDom}" for="nrDom" />
                            <p:inputText id="nrDom" value="#{rejestracjaController.selected.nrDom}" title="#{msgs.CreateRejestracjaFormTitle_nrDom}" required="true" requiredMessage="#{msgs.CreateRejestracjaFormRequiredMessage_nrDom}">
                                <f:validateLength maximum="20" />
                            </p:inputText>

                        </p:outputPanel>

    </h:panelGrid>

    <h:commandLink action="#{rejestracjaController.create}" value="#{msgs.CreateRejestracjaFormSaveLink}" />
  
  </h:form>

Re: selectOneMenu - How should I dynamically render componen

Posted: 12 Apr 2012, 15:36
by march_in
Solution 1 - use javascript

Code: Select all

                    <h:panelGrid columns="2" id="rejestracjaFormPanel">
                        <p:column />
                        <p:message id="srdSrdIdMessage" for="srdSrdId" />
                        <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_srdSrdId}" for="srdSrdId" />
                        <p:selectOneMenu id="srdSrdId"
                                         value="#{rejestracjaController.selected.srdSrdId}"
                                         title="#{msgs.CreateRejestracjaFormTitle_srdSrdId}"
                                         required="true"
                                         requiredMessage="#{msgs.msgs.CreateRejestracjaForm_srdSrdIdRequired}"
                                         onchange="changeBusinessType();">
                            <f:selectItems value="#{sloRodzajDzialalnosciController.itemsAvailableSelectMany}" />
                        </p:selectOneMenu>
                    </h:panelGrid>

                    <h:panelGroup id="panelKodPromocji">
                        <h:panelGrid columns="2">
                            <h:column />
                            <p:message id="kodPromocjiMessage" for="kodPromocji" />
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_kodPromocji}"
                                           for="kodPromocji" />
                            <p:inputText id="kodPromocji" value="#{rejestracjaController.selected.kodPromocji}" title="#{msgs.CreateRejestracjaFormTitle_kodPromocji}">
                                <f:validateLength maximum="20" />
                            </p:inputText>
                        </h:panelGrid>
                    </h:panelGroup>

Code: Select all

                <script type="text/javascript">
                    /* <![CDATA[ */
                    function changeBusinessType(){
                        if($("#srdSrdId_input").val()==2){
                            $("#panelKodPromocji").hide();
                        }else{
                            $("#panelKodPromocji").show();
                        }
                    }
                    function onLoadPage(){
                        changeBusinessType();
                    }
                    $(document).ready(function() {
                        onLoadPage();
                    });
                    /* ]]> */
                </script>
problem is that value of hidden panel is also posted with form.

Re: selectOneMenu - How should I dynamically render componen

Posted: 12 Apr 2012, 16:51
by march_in
anyone can help? any ideas how to do this? some links to examples?

Re: selectOneMenu - How should I dynamically render componen

Posted: 12 Apr 2012, 21:08
by Hamsterbau
No, you should not use rendered attribute for your outputPanel. Outputpanel should always be rendered, so you are able to update this component (with all underlying components in tree). So what i have ment is something like this:

Code: Select all

<h:form id="rejestracjaForm" prependId="false">
    <h:panelGrid columns="2" id="rejestracjaFormPanel">
                        <p:column />
                        <p:message id="srdSrdIdMessage" for="srdSrdId" />
                        <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_srdSrdId}" for="srdSrdId" />
                        <p:selectOneMenu id="srdSrdId"
                                         value="#{rejestracjaController.selected.srdSrdId}"
                                         title="#{msgs.CreateRejestracjaFormTitle_srdSrdId}"
                                         required="true"
                                         requiredMessage="#{msgs.msgs.CreateRejestracjaForm_srdSrdIdRequired}">
                            <f:selectItems value="#{sloRodzajDzialalnosciController.itemsAvailableSelectMany}" />
                            <p:ajax update="changeablePanel" />
                        </p:selectOneMenu>

                        <p:outputPanel [b]id="changeablePanel"[/b]>
                            <p:column />
                            <p:message id="nazwaMessage" for="nazwa" [b]rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}"[/b]/>
                            <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_nazwa}" for="nazwa" id="nazwas" rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}"/>
                            <p:inputText id="nazwa" value="#{rejestracjaController.selected.nazwa}" title="#{msgs.CreateRejestracjaFormTitle_nazwa}" rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}">                           
                                <f:validateLength maximum="150" />
                            </p:inputText>
... 
Or in short, you cannot update an outputpanel with AJAX if it is not rendered at this time.

Hope this helps,

Daniel

Re: selectOneMenu - How should I dynamically render componen

Posted: 13 Apr 2012, 11:49
by march_in
Hamsterbau problem is that if i select option, the value of the field in changeablePanel, will be lost.

I can use:

Code: Select all

                        <p:selectOneMenu id="srdSrdId"
                                         value="#{rejestracjaController.selected.srdSrdId}"
                                         title="#{msgs.CreateRejestracjaFormTitle_srdSrdId}"
                                         required="true"
                                         requiredMessage="#{msgs.msgs.CreateRejestracjaForm_srdSrdIdRequired}">
                            <f:selectItems value="#{sloRodzajDzialalnosciController.itemsAvailableSelectMany}" />

                            <p:ajax update="rejestracjaFormPanelImie" />
                            <ui:remove>
                                <p:ajax update="rejestracjaFormPanelImie" process="@all" immediate="true" />
                            </ui:remove>

                            <ui:remove>
                                <f:ajax event="change" execute="@all" immediate="true" />
                            </ui:remove>
                        </p:selectOneMenu>


                    <h:panelGrid columns="2" id="rejestracjaFormPanelImie">
                        <p:column
                            rendered="#{rejestracjaController.selected.srdSrdId.srdId==3 || rejestracjaController.selected.srdSrdId.srdId==4}" />
                        <p:message id="imieMessage" for="imie"
                                   rendered="#{rejestracjaController.selected.srdSrdId.srdId==3 || rejestracjaController.selected.srdSrdId.srdId==4}" />
                        <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_imie}" for="imie"
                                       rendered="#{rejestracjaController.selected.srdSrdId.srdId==3 || rejestracjaController.selected.srdSrdId.srdId==4}" />
                        <p:inputText id="imie" value="#{rejestracjaController.selected.imie}"
                                     title="#{msgs.CreateRejestracjaFormTitle_imie}"
                                     rendered="#{rejestracjaController.selected.srdSrdId.srdId==3 || rejestracjaController.selected.srdSrdId.srdId==4}"
                                     required="#{rejestracjaController.selected.srdSrdId.srdId==3 || rejestracjaController.selected.srdSrdId.srdId==4}"
                                     requiredMessage="Wymagane wymagane">
                            <f:validateLength maximum="50" />
                        </p:inputText>
                    </h:panelGrid>

but the value will be lost onchange. If i add process attribute the validation will be proccessed and i cannot change the value of select even with immediate option.
Other problems is that this field in changable panel can be required fore some options and not for the others.

I tried:

Code: Select all

<p:ajax update="rejestracjaFormPanelImie" process="@this,imie" />
<p:ajax update="rejestracjaFormPanelImie" process="@this,imie" immediate="true" />
<p:ajax update="rejestracjaFormPanelImie" process="@all" />
with different combination of update attribute. I'm not preety sure that is good idea.

any solutions? Should i use my "Solution 1" with javascript and jquery scripts triggered onchange event?

Re: selectOneMenu - How should I dynamically render componen

Posted: 16 Apr 2012, 16:54
by march_in
should i skip all f:validateLength tags, all required properties and use:

Code: Select all

<f:event listener="#{rejestracjaController.validateRejestracja}" type="postValidate" />                    
and then "manually" validate all fields?
and use:

Code: Select all

                            <p:ajax event="change"
                                    update="rejestracjaFormPanelImie"
                                    listener="#{rejestracjaController.changeTypeOfBusiness}"
                                    process="@all" />

Re: selectOneMenu - How should I dynamically render componen

Posted: 16 Apr 2012, 18:14
by smithh032772
Did you click the URL i provided earlier and review the code I shared?

I just looked at your code below (that you shared when you initiated this forum topic).

Code: Select all

<h:panelGrid columns="2" id="rejestracjaFormPanel">

<p:column />
                        <p:message id="srdSrdIdMessage" for="srdSrdId" />
                        <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_srdSrdId}" for="srdSrdId" />
                        <p:selectOneMenu id="srdSrdId"
                                         value="#{rejestracjaController.selected.srdSrdId}"
                                         title="#{msgs.CreateRejestracjaFormTitle_srdSrdId}"
                                         required="true"
                                         requiredMessage="#{msgs.msgs.CreateRejestracjaForm_srdSrdIdRequired}"
                                         >
                            <f:selectItems value="#{sloRodzajDzialalnosciController.itemsAvailableSelectMany}" />
                            <p:ajax update="rejestracjaFormPanel" />
                        </p:selectOneMenu>

                        <p:column 
                            rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}" />
                        <p:message id="kodPromocjiMessage" for="kodPromocji"
                                   rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}" />
                        <h:outputLabel value="#{msgs.CreateRejestracjaFormLabel_kodPromocji}"
                                       for="kodPromocji"
                                       rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}"/>
                        <p:inputText id="kodPromocji" value="#{rejestracjaController.selected.kodPromocji}" title="#{msgs.CreateRejestracjaFormTitle_kodPromocji}"
                                     rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}">
                            <f:validateLength maximum="20" />
                        </p:inputText>
</h:panelGrid>
1. I don't see how your xhtml works with <p:column ... /> and then embedding your selectOneMenu and other components 'outside' of the <p:column .../>.
2. Your xhtml includes the following:

Code: Select all

rendered="#{rejestracjaController.selected.srdSrdId.srdId == 1}"
3. Can you reply with your entire xhtml, especially the p:dataTable ... ?
4. I hope srdSrdId.srdId == 1 is not first row in your datatable.
5. In the code that I provided, p:column rendered="..." is working as designed depending on what enduser selects in selectOneMenu via AJAX and when page is loaded initially (not using javascript at all).