13 Replies Latest reply on Sep 18, 2007 5:11 PM by hgf

    HowTo: rich:tab disabled by ajax4jsf II

    hgf

      Hi,

      I'm using SUN-JSF 1.2, faclets 1.1.12, richFaces 3.0.1, ajax4jsf 1.1.1 and tomahawk 1.1.6 (only panelLayout yet).

      I want to disable panel one by a select of a of a h:selectOneMenu component on an other panel, which includes a a4j:support component. I could implement this basically with a litle awkward feature (see previous topic). But a real problem is now that the content of that disabled panel is still rendered after I've made any inputs (which are send to the server for validation by ajax) on that panel to be disabled previously. That content comes out on the next or a previous page. I've tried to supress this by adding a rendererd attribute to the surrounding h:panelGrid tag of that panel. The result is, that the content is, as expected, not rendered but the border of the panel still is rendererd.

      I'm using faclets ui:include and ui:composition for each richt:tab to seperate the sources of the different panels. Perhaps this causes the rendering of the border.

      The current workaround I use is to use the rendered attribute of rich:tab instead of disabled. But that leeds to a flickering ui what I don't like.

      Is there any solution to disable a panel and the complete content of that panel is not rendered?

      Thanks for any idea.

        • 1. Re: HowTo: rich:tab disabled by ajax4jsf II
          ilya_shaikovsky

          Unfortunatelly I've lost your point... Please explain using code snippets and step by step explanation of your problem. Thanks!

          • 2. Re: HowTo: rich:tab disabled by ajax4jsf II
            hgf

            OK! I'l try it again.

            Important is not only to disable the tab of a rich:tab, but also do not render the content of that tab in any other page. The situation I have is that the tab is disabled but the content is still rendered on a neighbour tab. That problem occurs if

            <a4j:support event="onblur" reRender="outputError"ajaxSingle="true" limitToList="true" />

            for h.inputText id="lineID" is executed.


            Here is to much of code, I fear:

            Here is the richt:tabPanel. As you can see the content of the particular tabs is included with faclets, to avoid flooding one only page:

            ==================================================

            <ui:define name="pageBody">
            <h:form id="wizardForm" styleClass="pageBody">
            <h:panelGrid columns="1" width="100%">
            <a4j:outputPanel ajaxRendered="true" id="DLG_CONFIG_TBN_ALL">
            <h:panelGrid columns="1" width="100%">
            <rich:tabPanel switchType="client" style="height: 400px; width=100%">
            <rich:tab label="#{msg.DLG_CONFIG_TPN_BASIC}">
            <ui:include src="/pages/basicInformation.xhtml" />
            </rich:tab>
            <rich:tab id="DLG_CONFIG_TBN_ADRESS"
            label="#{msg.DLG_CONFIG_TBN_ADRESS}">
            <ui:include src="/pages/adress.xhtml" />
            </rich:tab>
            <rich:tab label="#{msg.DLG_CONFIG_TBN_CPE}">
            <ui:include src="/pages/cpeInformation.xhtml" />
            </rich:tab>
            <rich:tab id="DLG_CONFIG_TBN_LOLO"
            label="#{msg.DLG_CONFIG_TBN_LOLO}"
            disabled="#{configurationHandler.disableLocalLoops}">
            <ui:include src="/pages/localLoops.xhtml" />
            </rich:tab>
            <rich:tab id="DLG_CONFIG_TBN_DSL"
            label="#{msg.DLG_CONFIG_TBN_DSL}"
            disabled="#{configurationHandler.disableDSL}">
            <ui:include src="/pages/dsl.xhtml" />
            </rich:tab>
            <rich:tab id="DLG_CONFIG_TBN_ISDN"
            label="#{msg.DLG_CONFIG_TBN_ISDN}"
            disabled="#{configurationHandler.disableISDN}">
            ISDN
            </rich:tab>
            </rich:tabPanel>
            </h:panelGrid>
            <h:panelGrid id="panelError" styleClass="error_footer">
            <h:panelGrid columns="5" style="text-align: left;">
            <h:messages />
            </h:panelGrid>
            </h:panelGrid>
            <h:panelGrid columns="1" width="100%"
            style="text-align: left; border: 1px solid #E20074; background-color: #D5D5D5">
            <h:panelGrid columns="5" style="text-align: left;">
            <h:commandButton action="#{configurationHandler.createROTConfig}"
            value="Create ROT Config" />
            <h:commandButton
            action="#{configurationHandler.createVPNDConfig}"
            value="Create VPND Config" />
            <h:commandButton
            action="#{configurationHandler.newConfigAndInit}" value="reset"
            immediate="true" />
            </h:panelGrid>
            </h:panelGrid>
            </a4j:outputPanel>
            </h:panelGrid>
            </h:form>
            </ui:define>
            ================================================

            And here is the page which should be not rendererd:

            ================================================

            <ui:composition>
            <h:panelGrid columns="1"
            rendered="#{!configurationHandler.disableLocalLoops}">
            <h:panelGrid columns="2" style="horizontal-align: center">
            <h:panelGrid columns="2">
            <h:panelGroup />
            <h:message styleClass="error"
            id="DLG_CONFIG_TBN_LOLO_IT_PE_NAME_ERROR"
            for="DLG_CONFIG_TBN_LOLO_IT_PE_NAME" />
            <h:outputText value="PE Name:" />
            <h:inputText id="DLG_CONFIG_TBN_LOLO_IT_PE_NAME" label="PE Name"
            value="#{configurationHandler.config.FRAMERELAY.PE_NAME}"
            converter="spims.PeNameConverter" required="true" />
            </h:panelGrid>

            <h:panelGrid columns="2">
            <h:panelGroup />
            <h:message styleClass="error" id="accessSpeedError"
            for="accessSpeed" />
            <h:outputText value="Access speed:" />
            <h:selectOneMenu id="accessSpeed" label="Access speed"
            value="#{configurationHandler.config.FRAMERELAY.CIRCUIT_ACCESS_SPEED_CUSTOMER}"
            converter="spims.CircuitAccessSpeedConverter">
            <f:selectItems value="#{selectItemProvider.circuitAccessSpeedList}" />
            </h:selectOneMenu>
            </h:panelGrid>
            </h:panelGrid>

            <h:panelGrid columns="1">
            <rich:spacer width="1" height="15" />
            <rich:spacer width="550" height="0"
            style="border:1px solid #{a4jSkin.panelBorderColor}" />
            <rich:spacer width="1" height="15" />
            </h:panelGrid>

            <rich:dataTable id="localLoopList" rowKeyVar="rowKey"
            onRowMouseOver="this.style.backgroundColor='#F1F1F1'"
            onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"
            cellpadding="0" cellspacing="0" border="0" var="localLoop"
            value="#{configurationHandler.localLoopsHandler.resultModel}">

            <f:facet name="header">
            <rich:columnGroup>
            <rich:column rowspan="2">
            <h:outputText value="Del." />
            </rich:column>
            <rich:column rowspan="2">
            <h:outputText value="Nr." />
            </rich:column>
            <rich:column rowspan="2">
            <h:outputText value="Line-ID" />
            </rich:column>
            <rich:column colspan="4">
            <h:outputText value="PE" />
            </rich:column>
            <rich:column breakBefore="true">
            <h:outputText value="Slot" />
            </rich:column>
            <rich:column>
            <h:outputText value="Bay" />
            </rich:column>
            <rich:column>
            <h:outputText value="Port" />
            </rich:column>
            <rich:column>
            <h:outputText value="Timeslots" />
            </rich:column>
            </rich:columnGroup>
            </f:facet>

            <rich:column>
            <h:commandButton value="X" immediate="true"
            action="#{configurationHandler.localLoopsHandler.deleteLokalLoop}"
            disabled="#{!configurationHandler.localLoopsHandler.localLoopsDeletePossibile}">
            <a4j:support event="onclick" reRender="localLoopList"
            ajaxSingle="true" limitToList="false" />

            </h:commandButton>
            </rich:column>
            <rich:column>
            <h:outputText value="#{rowKey + 1}" />
            </rich:column>
            <rich:column>
            <h:inputText id="lineId" label="Line-ID"
            value="#{localLoop.LINE_ID}" converter="spims.LineIdConverter"
            required="true" size="25">
            <a4j:support event="onblur" reRender="outputError"
            ajaxSingle="true" limitToList="true" />
            </h:inputText>
            </rich:column>
            <rich:column>
            <h:inputText value="#{localLoop.SLOT}" size="3" />
            </rich:column>
            <rich:column>
            <h:inputText value="#{localLoop.BAY}" size="3" />
            </rich:column>
            <rich:column>
            <h:inputText value="#{localLoop.PORT}" size="3" />
            </rich:column>
            <rich:column>
            <h:inputText id="timeslotId" value="#{localLoop.TIME_SLOT}"
            converter="spims.TimeslotConverter">
            </h:inputText>
            </rich:column>

            <f:facet name="footer">
            <rich:columnGroup>
            <rich:column colspan="1">
            <a4j:commandButton value="add" immediate="true"
            disabled="#{configurationHandler.localLoopsHandler.maxLocalLoopsCountReached}"
            action="#{configurationHandler.localLoopsHandler.addLokalLoop}"
            reRender="panelError" ajaxSingle="true" limitToList="true" />
            </rich:column>
            <rich:column colspan="1">
            </rich:column>
            <rich:column colspan="5">
            <a4j:outputPanel id="outputError">
            <h:message styleClass="error" id="lineIdError" for="lineId" />
            </a4j:outputPanel>
            </rich:column>
            </rich:columnGroup>
            </f:facet>

            </rich:dataTable>

            </h:panelGrid>
            </ui:composition>

            • 3. Re: HowTo: rich:tab disabled by ajax4jsf II
              ilya_shaikovsky

              what the reason to use aj4:support inside the command button? both components are action components and shouldn't be used in a such way.

              • 4. Re: HowTo: rich:tab disabled by ajax4jsf II
                hgf

                OK! Your wright. I dont't know what that construct is good for. Must be a mental derangement.

                I see now that I've marked the wrong elements. The right once are a few lines below:

                <h:inputText id="lineId" label="Line-ID"
                value="#{localLoop.LINE_ID}" converter="spims.LineIdConverter"
                required="true" size="25">
                <a4j:support event="onblur" reRender="outputError"
                ajaxSingle="true" limitToList="true" />
                </h:inputText>

                • 5. Re: HowTo: rich:tab disabled by ajax4jsf II
                  ilya_shaikovsky

                  B.t.w. If you choose client side switched Tab panel and put it in the one form - all tabs will be processed on submit. disable - just means that you will not able to switch. So turn it to ajax and you will submit only one tab.

                  • 6. Re: HowTo: rich:tab disabled by ajax4jsf II
                    hgf

                    I'll check this.

                    I want to remind of the original question: how to prevent that the content of my disabled panel is rendererd. Curious is that this only happens if the a4j:support has fired before.

                    • 7. Re: HowTo: rich:tab disabled by ajax4jsf II
                      ilya_shaikovsky

                      To make the tab content to be rendered only if the tab is active - just switch switchtype ti server or ajax.

                      • 8. Re: HowTo: rich:tab disabled by ajax4jsf II
                        hgf

                        I can not switch to ajax. Doing this means that I have to fill out each panel before I can leave it. I think it's the better choice to let the user click here and there, and then send all data with one submit to the server.

                        • 9. Re: HowTo: rich:tab disabled by ajax4jsf II
                          ilya_shaikovsky

                          ok.. let me show you my example:

                           <h:form>
                           <rich:tabPanel switchType="client" id="tab">
                           <rich:tab label="test 1">
                           <h:inputText value="#{person.prop1}" ></h:inputText>
                           </rich:tab>
                           <rich:tab label="Sample 2" disabled="#{bean.check}" >
                           <h:inputText value="#{person.prop2}" required="true"></h:inputText>
                           </rich:tab>
                           </rich:tabPanel>
                           <rich:messages/>
                           <h:selectBooleanCheckbox value="#{bean.check}">
                           <a4j:support event="onclick" reRender="tab" ajaxSingle="true"></a4j:support>
                           </h:selectBooleanCheckbox>
                           <h:commandButton value="submit"></h:commandButton>
                           </h:form>


                          There you can see next cases:

                          1) I have optionally disabled tab disablement/enablement works as expected on checkbox click.

                          2) On submit button click - if the tab is enbled - message thrown in other case - no.

                          Did you need anything else?

                          • 10. Re: HowTo: rich:tab disabled by ajax4jsf II
                            hgf

                            Thank you for the example and having patience.

                            The first unpleasent thing in your example is, that the whole tabPanel is reRendererd. Select an item and the contend of test 1 inputText is lost. I know that you need a component which is always available. Because of that you have to take tabPanel for rerender. But what about disabled tabs? My trials showed that it is not

                            Because of that I use a workaround sending the content of each field back to the server using a4j:ssupport and onblur event. But that results in (I assume) that when the tab itself is disabled or not rendered the content of that tab is still renderered. The content appears on the next or the previous tab.

                            regards

                            • 11. Re: HowTo: rich:tab disabled by ajax4jsf II
                              hgf

                              sorry! I was distracted. Please add the following to the second section...

                              ... My trials showed that it is not possible to reRender a single tab.

                              • 12. Re: HowTo: rich:tab disabled by ajax4jsf II
                                ilya_shaikovsky

                                reRendering of the tab - isn't available. A tab on the client - is just control for switching but not a container for the content.

                                In case of server and ajax mode - reRendering the whole tabPanel - is reRendering the only active tab. And in client case - you need to reRender the whole panel.

                                Not sure that understand you about disabled again.. Did you see that in my example - disablement is realy dinamical and the content didn't rendered if the tab is disabled?

                                • 13. Re: HowTo: rich:tab disabled by ajax4jsf II
                                  hgf

                                  It is a pity that rendering a single panel is not available. But this definte information is although very important because of now I'm sure that I have to look for an other way using tab and panels.

                                  I have changed a previuos layout with next-previous buttons for each content to panel layout because with this layout the user is able to see everything he wants with just one click instead of klicking backward or forward buttons through available or not available content. We think that enabling or disabling tabs immediate after a change is more resonable for the users.

                                  I've not tested your example because I'm very shure that this will work as expected. Because of rerendering the whole tab and all panels, I've started to send each value change of any input component to the server. This prevents that after a rerendering the whole tab the previous entered content is been lost. These changes are sent with:



                                  <a4j:support event="onblur" reRender="panelError"
                                   ajaxSingle="true" limitToList="true" />
                                  


                                  I see rigth now that limitToList is nonsensically.

                                  After making some changes and sending these to the server and because of any other changes the panel is set disbaled the content still appears. I'm not sure but I belief that not the whole content is rendererd but just the rich:dataTable. I'll check this again. But setting the rendering of the whole content to false still ends in rendering a border of the disabled tab. Perhaps I will find the time to create and post a reduced example of this use case. But I fear that this can take some time because we have to deliver a first version of our application in just three weeks. Time is rare. Same procedure as last year Miss Sophie?

                                  I am very thankfull for your help!

                                  Regards