0

I have a form where I have a rich:select whether they choose option A or option B an h:inputText is rendered. Initially the h:inputText corresponding to option A is rendered and if I leave it blank the requiredMessage appears and everything is OK. Now when I select the second option of the rich:select the h:inputText for option B is rendered but if I leave it blank the requiredMessage doesn't appear.

What am I missing?

My xhtml code is as follows:

                <h:panelGrid columns="3">
                    <h:outputLabel for="tipoPersona">Tipo de persona</h:outputLabel>
                    <rich:select id="tipoPersona"
                                 required="true" value="#{userInformationController.tipoPersona}"
                                 requiredMessage="Seleccione el tipo de persona"
                                 defaultLabel="Seleccione una opción">
                        <f:selectItems value="#{userInformationController.tipoPersonaOpciones}"/>
                        <f:ajax event="blur" render="tipoPersonaMessage"/>
                        <f:ajax event="selectitem"
                                render="outputLabelCURP inputTextCURP messageCURP outputLabelRFC inputTextRFC messageRFC"
                                listener="#{userInformationController.doRenderCURP}"/>
                    </rich:select>
                    <rich:message id="tipoPersonaMessage" ajaxRendered="true"
                                  for="tipoPersona"/>


                    <a4j:outputPanel id="outputLabelCURP">
                        <h:outputLabel for="CURP" value="CURP"
                                       rendered="#{userInformationController.curpRendered}"/>
                    </a4j:outputPanel>                        
                    <a4j:outputPanel id="inputTextCURP">
                        <h:inputText id="CURP" required="true"
                                     requiredMessage="Introduzca el CURP"
                                     rendered="#{userInformationController.curpRendered}">
                            <f:ajax event="blur" render="curpMessage"/>
                        </h:inputText>
                    </a4j:outputPanel>
                    <a4j:outputPanel id="messageCURP">
                        <rich:message id="curpMessage" ajaxRendered="true"
                                      for="CURP"
                                      rendered="#{userInformationController.curpRendered}"/>
                    </a4j:outputPanel>


                    <a4j:outputPanel id="outputLabelRFC">
                        <h:outputLabel for="RFC" value="RFC"
                                       rendered="#{not userInformationController.curpRendered}"/>
                    </a4j:outputPanel>
                    <a4j:outputPanel id="inputTextRFC">
                        <h:inputText id="RFC" required="true"
                                     requiredMessage="Introduzca el RFC"
                                     rendered="#{not userInformationController.curpRendered}">
                            <f:ajax event="blur" render="rfcMessage"/>
                        </h:inputText>
                    </a4j:outputPanel>
                    <a4j:outputPanel id="messageRFC">
                        <rich:message id="rfcMessage" ajaxRendered="true"
                                      for="RFC"
                                      rendered="#{not userInformationController.curpRendered}"/>
                    </a4j:outputPanel>
                </h:panelGrid>

UPDATE

I have made some changes on the UI and now I have this

            <fieldset>
                <legend>Datos SURI</legend>
                <h:panelGrid columns="3">
                    <h:outputLabel for="tipoPersona">Tipo de persona</h:outputLabel>
                    <rich:select id="tipoPersona"
                                 required="true" value="#{userInformationController.tipoPersona}"
                                 requiredMessage="Seleccione el tipo de persona"
                                 defaultLabel="Seleccione una opción">
                        <f:selectItems value="#{userInformationController.tipoPersonaOpciones}"/>
                        <f:ajax event="blur" render="tipoPersonaMessage"/>
                        <f:ajax event="selectitem"
                                render="outputLabelCURP inputTextCURP messageCURP 
                                        outputLabelRFC inputTextRFC messageRFC
                                        datosPersonaFisica datosPersonaMoral"
                                listener="#{userInformationController.doRenderTipoPersona}"/>
                    </rich:select>
                    <rich:message id="tipoPersonaMessage" ajaxRendered="true"
                                  for="tipoPersona"/>


                    <a4j:outputPanel id="outputLabelCURP">
                        <h:outputLabel for="CURP" value="CURP"
                                       rendered="#{userInformationController.personaFisicaRendered}"/>
                    </a4j:outputPanel>                        
                    <a4j:outputPanel id="inputTextCURP">
                        <h:inputText id="CURP" required="true"
                                     requiredMessage="Introduzca el CURP"
                                     value="#{userInformationController.curp}"
                                     rendered="#{userInformationController.personaFisicaRendered}">
                            <f:ajax event="blur" render="curpMessage identificadorSURI"
                                    listener="#{userInformationController.doSearchIdSURI}"/>
                        </h:inputText>
                    </a4j:outputPanel>
                    <a4j:outputPanel id="messageCURP">
                        <rich:message id="curpMessage" ajaxRendered="true" for="CURP"
                                      rendered="#{userInformationController.personaFisicaRendered}"/>
                    </a4j:outputPanel>


                    <a4j:outputPanel id="outputLabelRFC">
                        <h:outputLabel for="RFC" value="RFC"
                                       rendered="#{userInformationController.personaMoralRendered}"/>
                    </a4j:outputPanel>
                    <a4j:outputPanel id="inputTextRFC">
                        <h:inputText id="RFC" required="true"
                                     requiredMessage="Introduzca el RFC"
                                     value="#{userInformationController.rfc}"
                                     rendered="#{userInformationController.personaMoralRendered}">
                            <f:ajax event="blur" render="rfcMessage identificadorSURI"
                                    listener="#{userInformationController.doSearchIdSURI}"/>
                        </h:inputText>
                    </a4j:outputPanel>
                    <a4j:outputPanel id="messageRFC">
                        <rich:message id="rfcMessage" ajaxRendered="true" for="RFC"
                                      rendered="#{userInformationController.personaMoralRendered}"/>
                    </a4j:outputPanel>

                    <h:outputLabel for="identificadorSURI">Identificador SURI</h:outputLabel>
                    <h:inputText id="identificadorSURI" disabled="true"
                                 value="#{userInformationController.identificadorSuri}"/>

                </h:panelGrid>
            </fieldset>

However, I found that putting my Bean in RequestScope isn't firing the listener on both of the h:inputText (id='CURP' and id='RFC'), whereas if I put the bean in ViewScope the listener is getting fired and processed correctly.

What I need is to actually have the Bean in RequestScope because I need to create a whole new form whether the user changes the value of the rich:select. If I keep the scope in ViewScope all the data is kept within the Bean and I will then have to erase the fields when the user changes the value of the select.

Can someone explain to me why is this happening? I could'n figure out what's the trick !

Cheers

BRabbit27
  • 6,333
  • 17
  • 90
  • 161

3 Answers3

1

A request scoped bean is recreated on every single request, also on every single ajax request. So when you change a property by ajax to a new value other than default (e.g. the one responsible for rendered attribute), then this change won't be retained in the subsequent requests. So the rendered attribute effectively evaluates to false and the component and all its children won't be processed anymore during the submit.

The view scope is intended to solve exactly this problem. The bean will live as long as you're interacting with the same view by ajax requests, until you navigate away to a different view or recreate the view. As to the functional requirement of recreating the form on change of <rich:select>, just do that inside the doRenderTipoPersona() method.

If you really need to stick to the request scope, then you'd need to retain the bean's properties manually based on the request parameter map inside the (post)constructor.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks. That's was what I imagined (ajax creates new requests). What I did was to kept my bean in View Scope and clear all bean's fields on `` listener. – BRabbit27 Apr 10 '12 at 15:37
0

Instead of using to event function you can use the single ajax function

<rich:select id="tipoPersona"
                                 required="true" value="#{userInformationController.tipoPersona}"
                                 requiredMessage="Seleccione el tipo de persona"
                                 defaultLabel="Seleccione una opción">
                        <f:selectItems value="#{userInformationController.tipoPersonaOpciones}"/>
                       <f:ajax event="valueChange"
                                render="tipoPersonaMessage outputLabelCURP inputTextCURP messageCURP outputLabelRFC inputTextRFC messageRFC"
                                listener="#{userInformationController.doRenderCURP}"/>
                    </rich:select>
Usman Awan
  • 1,208
  • 2
  • 13
  • 30
  • Thanks for your answer. Maybe I explain myself wrong, but the problem is not in the **rich:select** the problem is in the **h:inputText** (id='CURP' and id='RFC'). When the `blur` event is fired I want the listener to get called but It doesn't. – BRabbit27 Apr 09 '12 at 22:23
  • ahan..i have another solution for this you can call a onBlur function on Inputtext where you can have a4j:jsFunction call which call your listener function on the bean. – Usman Awan Apr 12 '12 at 10:52
0

Well this is a solution.

<a4j:jsFunction name="onBlurRFC" execute="RFC" render = "rfcMessage identificadorSURI" 
    action="#{userInformationController.doSearchIdSURI}" />     

    <h:inputText id="RFC" required="true"
                                             requiredMessage="Introduzca el RFC"
                                             value="#{userInformationController.rfc}"
                                             rendered="#{userInformationController.personaMoralRendered}" onblur="onBlurRFC()">
                                </h:inputText>
Usman Awan
  • 1,208
  • 2
  • 13
  • 30
  • sorry, a4j:jsFunction was missing. a4j:jsFunction will fire a listener on a bean and render the panel. same will be done for CURP input Text. – Usman Awan Apr 13 '12 at 10:52