2 Replies Latest reply on May 6, 2009 7:23 AM by shino

    ModalPanel backing bean instanciated too early -> no content

    shino

      Hi,
      I'm using a modalpanel to display and edit data, which the user selected by double-clicking on a datatable row.

      My problem is, that upon doubleClick, the modalpanels request scoped backing bean is created, before the selected data is written into the corresponding property of my session scoped managed bean. The result is, that the content of my modalpanel always lacks behind one request, on the first double-click it is empty, on the second one it shows the data that should have been shown before etc.

      Here is the relevant code of dataTable:

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:a4j="http://richfaces.org/a4j"
       xmlns:rich="http://richfaces.org/rich">
      
       <f:loadBundle basename="messages" var="msgs"/>
       <rich:panel header="#{msgs.addressOverviewTitle}" style="height : auto; width : auto;">
       <rich:spacer height="6"></rich:spacer>
       <h:form>
       <rich:dataTable value="#{addressesModel.addressesTableData}"
       sortMode="single"
       id="addressesTable"
       var="address"
       rowKeyVar="currentAddressIndex"
       columns="9"
       rows="#{preferencesModel.maxTableEntries}"
       headerClass="addressesTableHeader"
       rowClasses="oddRow,evenRow">
       <a4j:support
       id="editAddressSupport"
       event="onRowDblClick"
       action="#{addressesModel.selectCurrentAddress}"
       oncomplete="#{rich:component('editAddressMP')}.show();"
       reRender="editAddressForm"/>


      (addressesModel is a session scoped bean.. perhaps I will create a seperate controller class for things like keeping a selected address, so responsibilities are clearly seperated, but thats a bit off topic ;-))

      I don't know how to fix this without changing my logic.. though it seems "right" to me to first select the dataobject and then create the backing bean which populates the modalpanel using the data from the session bean. Can anyone point me to the right direction here?

      best regards

      Chris

      P.S.:
      One thing I also noticed is that the backing bean for the modal-panel is first instanciated when the whole page loads, in other words: before the modal-panels visibility state changes. Even though this makes sense because the ui:include command isn't executed conditionaly and is processed together with the rest of the page, it doesn't seem desirable to have the bean instanciated when it might not be needed at all. Is there something I'm missing here, or is this just the way modalpanels work?



        • 1. Re: ModalPanel backing bean instanciated too early -> no con
          ilya_shaikovsky

          http://livedemo.exadel.com/richfaces-demo/richfaces/dataTable.jsf?tab=editDataTable
          the only difference that we usign link and in your case support used.

          • 2. Re: ModalPanel backing bean instanciated too early -> no con
            shino

            thanks again :-) sometimes my thinking is too complicated.
            For those interested, here is the new Code:

            <ui:composition xmlns="http://www.w3.org/1999/xhtml"
             xmlns:ui="http://java.sun.com/jsf/facelets"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:a4j="http://richfaces.org/a4j"
             xmlns:rich="http://richfaces.org/rich">
            
             <f:loadBundle basename="messages" var="msgs"/>
             <rich:panel header="#{msgs.addressOverviewTitle}" style="height : auto; width : auto;">
             <rich:spacer height="6"></rich:spacer>
             <h:form>
             <rich:dataTable value="#{addressbookController.addressesTableData}"
             sortMode="single"
             id="addressesTable"
             var="address"
             rowKeyVar="currentAddressIndex"
             columns="9"
             rows="#{preferencesModel.maxTableEntries}"
             headerClass="addressesTableHeader"
             rowClasses="oddRow,evenRow">
             <a4j:support
             id="editAddressSupport"
             event="onRowDblClick"
             oncomplete="#{rich:component('editAddressMP')}.show();"
             reRender="editAddressForm">
             <f:setPropertyActionListener
             value="#{address}"
             target="#{addressbookController.selectedAddress}"/>
             </a4j:support>


            And the modalpanel:

            <ui:composition xmlns="http://www.w3.org/1999/xhtml"
             xmlns:ui="http://java.sun.com/jsf/facelets"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:a4j="http://richfaces.org/a4j"
             xmlns:rich="http://richfaces.org/rich">
            
             <rich:modalPanel id="editAddressMP" style="width:auto; height:auto;" autosized="true" >
            
             <script type="text/javascript">
            
             function closeEditAddressMPIfNoErrors(hasMessages){
             if (hasMessages==false){
             Richfaces.hideModalPanel('editAddressMP');
             }
             }
             </script>
            
             <f:facet name="header">
             <h:outputText value="#{msgs.editAddress}" />
             </f:facet>
             <f:facet name="controls">
             <h:graphicImage
             value="/images/modal/close.png"
             id="hideEditAddressMP" onclick="Richfaces.hideModalPanel('editAddressMP').hide()" />
             </f:facet>
            
             <a4j:form id="editAddressForm">
             <fieldset style="background:#E0E0F8;">
             <legend><h:outputText value="#{msgs.currentAddressData}" /></legend>
             <h:panelGrid
             id="editAddressPanel"
             columns="3"
             width="auto"
             columnClasses="newAddressFormColumn">
            
             <h:outputLabel for="reference" value="#{msgs.referenceLabel}*" />
             <h:inputText id="reference"
             value="#{addressbookController.selectedAddress.reference}"
             required="true" requiredMessage="#{msgs.pleaseEnterReferenceName}"/>
             <rich:message for="reference">
             <f:facet name="errorMarker">
             <h:graphicImage url="/images/validation/error.png"/>
             </f:facet>
             </rich:message>
            
             <h:outputLabel for="name" value="#{msgs.nameLabel}*" />
             <h:inputText id="name" value="#{addressbookController.selectedAddress.name}"
             required="true" requiredMessage="#{msgs.pleaseEnterAddressName}"/>
             <rich:message for="name">
             <f:facet name="errorMarker">
             <h:graphicImage url="/images/validation/error.png"/>
             </f:facet>
             </rich:message>
            
             <h:outputLabel for="nameExtension" value="#{msgs.nameExtLabel}" />
             <h:inputText id="nameExtension"
             value="#{addressbookController.selectedAddress.nameExtension}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="street" value="#{msgs.streetLabel}" />
             <h:inputText id="street"
             value="#{addressbookController.selectedAddress.street}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="houseNo" value="#{msgs.houseNoLabel}" />
             <h:inputText id="houseNo"
             value="#{addressbookController.selectedAddress.houseNo}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="postalCode" value="#{msgs.postalCodeLabel}" />
             <h:inputText id="postalCode"
             value="#{addressbookController.selectedAddress.postalCode}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="city" value="#{msgs.cityLabel}" />
             <h:inputText id="city"
             value="#{addressbookController.selectedAddress.city}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="country" value="#{msgs.countryLabel}" />
             <h:inputText id="country"
             value="#{addressbookController.selectedAddress.country}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <rich:spacer height="6"></rich:spacer>
             <rich:spacer height="6"></rich:spacer>
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="nonPublicSelect" value="#{msgs.nonPublicLabel}" />
             <h:selectBooleanCheckbox id="nonPublicSelect"
             value="#{addressbookController.selectedAddress.nonpublic}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="adSelect" value="#{msgs.adLabel}" />
             <h:selectBooleanCheckbox id="adSelect"
             value="#{addressbookController.selectedAddress.ad}" />
             <rich:spacer height="6"></rich:spacer>
            
             </h:panelGrid>
             </fieldset>
             <fieldset style="background:#E0E0F8;">
             <legend><h:outputText value="#{msgs.currentContactData}" /></legend>
             <h:panelGrid
             id="editContactPanel"
             columns="3"
             width="100%"
             columnClasses="newAddressFormColumn">
             <h:outputLabel for="contactPerson" value="#{msgs.contactPersonLabel}*" />
             <h:inputText id="contactPerson"
             value="#{addressbookController.selectedAddress.contact.contactPerson}"
             required="true"
             requiredMessage="#{msgs.pleaseEnterContactName}"/>
             <rich:message for="contactPerson">
             <f:facet name="errorMarker">
             <h:graphicImage url="/images/validation/error.png"/>
             </f:facet>
             </rich:message>
            
             <h:outputLabel for="phone" value="#{msgs.phoneLabel}" />
             <h:inputText id="phone" value="#{addressbookController.selectedAddress.contact.phone}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="mobile" value="#{msgs.mobileLabel}" />
             <h:inputText id="mobile" value="#{addressbookController.selectedAddress.contact.mobile}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="fax" value="#{msgs.faxLabel}" />
             <h:inputText id="fax" value="#{addressbookController.selectedAddress.contact.fax}" />
             <rich:spacer height="6"></rich:spacer>
            
            
             <h:outputLabel for="email" value="#{msgs.emailLabel}" />
             <h:inputText id="email" value="#{addressbookController.selectedAddress.contact.email}" >
             <f:validator validatorId="emailValidator"/>
             </h:inputText>
             <rich:message for="email" >
             <f:facet name="errorMarker">
             <h:graphicImage url="/images/validation/error.png"/>
             </f:facet>
             </rich:message>
            
             </h:panelGrid>
             </fieldset>
             <rich:spacer height="6"></rich:spacer>
             <a4j:commandButton type="submit" value="#{msgs.saveAddressChanges}"
             oncomplete="closeIfNoErrors(#{addressbookController.hasMessages});"/>
             </a4j:form>
             </rich:modalPanel>
             </ui:composition>


            This way, a backing bean is no longer needed.