1 2 Previous Next 15 Replies Latest reply on Aug 21, 2008 9:04 AM by nico.ben

    rich:tabPanel selectedTab problem

      Hi,

      I have a weird problem with the selectedTab attribute of the rich:tabPanel component. When I specify it, all the a4j actions (a4j:commandLink or a4j:commandButton) located in any of the tabs of my tabPanel do not work anymore. I debugged and I see on the server side that all the forms within each tab of my tabPanel aren't even decoded in the decode phase of the JSF request. If I simply remove the selectedTab attribute, everything works fine. Did anyone ever run into this particular problem? Here's what my template looks like:

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:h="http://java.sun.com/jsf/html"
      template="../templates/default.xhtml">
       <ui:define name="body">
       <rich:tabPanel id="myTabPanel" switchType="ajax" selectedTab="#{someBean.selectedTab}">
       <rich:tab name="tab1" label="Tab 1" action="#{someBean.prepTab1}">
       <ui:include src="tab1.xhtml"/>
       </rich:tab>
       <rich:tab name="tab2" label="Tab 2" action="#{someBean.prepTab2}">
       <ui:include src="tab2.xhtml"/>
       </rich:tab>
       <rich:tab name="tab3" label="Tab 3" action="#{someBean.prepTab3}">
       <ui:include src="tab3.xhtml"/>
       </rich:tab>
       </rich:tabPanel>
       </ui:define>
      </ui:composition>
      


      Basically, I have a tab set, each tab's body is in its own sub-template file, each sub-template includes one or many forms. When I click on a tab, an action of a backing bean is called. Sometimes, I want an action from one tab to redirect to another tab. When that is the case, I programmatically change the value of the "someBean.selectedTab" attribute and make sure that the whole tabPanel is reRendered. The proper tab is displayed but then none of the actions work anymore. I double-checked and I don't have any overlapping forms (form embedded inside another form). Like I said, I clearly see that forms located inside the sub-templates don't get decoded anymore when I do a postback to the server and I couldn't figure out why.

      Thank you for your help.

        • 1. Re: rich:tabPanel selectedTab problem
          ilya_shaikovsky

          I have

          <rich:tabPanel switchType="ajax" id="tab" selectedTab="#{bean.tabName}">
           <rich:tab label="test 1" name="tab1" action="#{bean.action}">
           <h:form>
           <ui:include src="/pages/greeting1.xhtml"/>
           <a4j:commandButton value="next" reRender="tab" action="#{bean.nextTab}"></a4j:commandButton>
           </h:form>
           </rich:tab>
           <rich:tab label="Sample 2" disabled="#{bean.check}" name="tab2" action="#{bean.action}">
           <h:form>
           <ui:include src="/pages/greeting1.xhtml"/>
           <a4j:commandButton value="prev" reRender="tab" action="#{bean.prevTab}"></a4j:commandButton>
           </h:form>
           </rich:tab>
           </rich:tabPanel>


          My buttons are changed the tab programatically. But after I use button - my actions on tabs still calling after next requests. My RF is 3.1.1 20 september build.

          • 2. Re: rich:tabPanel selectedTab problem

            I stripped down my test case to match what you have. I tried with RF 3.1.1 with a snapshot of September 24th and it still doesn't work for me. I'm deploying my application on Glassfish v2 final release using's Suns RI 1.2 if it makes any difference.

            I debugged further and here's what I can tell you. The first time I render the page or refresh it with Ctrl+F5, when I click on an action that brings me to another tab, it works, but then from this point on, all of the tab's content doesn't get decoded on the server anymore on the following postbacks. I'm not sure but it seems it has to do with the state that it saves. For some reason, the "renderedValue" attribute of the UITabPanel gets set to null when the first action is executed which them causes the UITabPanel to not decode any of its children on the following postbacks because it saves null as its value in the state. Removing the "selectedTab" attribute off of the rich:tabPanel tag fixes that problem but I obviously loose the behaviour that I want to implement.

            Do you have more ideas as to what is going on? Would there be a way for you to share a test web application in which the behaviour works as expected so I can deploy it on my server and see what happens?

            Thank you very much.

            • 3. Re: rich:tabPanel selectedTab problem

              Recently I had a similar problem when 'someBean' was a Seam in the PAGE scope. This scope is not available on restore view and selectedTab got initialized to null.. after that, no action coming from any of its tab got processed because the tabPanel component could not detect the tab as rendered... I got past it changing the scope of 'someBean'.. not ideal, but worked.

              Maybe a proper fix would be to keep checking for renderedTab if it evaluates to null..

              • 4. Re: rich:tabPanel selectedTab problem

                My bean does happen to be a Seam component (SFSB), but it has the conversion scope (default for SFSB) and the property on which I map the selectedTab attribute of the rich:tabPanel tag does keep its value. In the other words, the problem isn't the fact that when the tab panel tries to get the selected tab from my bean it returns null. Thanks for the tip though.

                • 5. Re: rich:tabPanel selectedTab problem

                  Well, I'll be damned! I just explicitly specified the scope type on my bean to be session and now it works! I think I jumped the gun there. Time to investigate what's going on with my conversation scope. Thanks.

                  • 6. Re: rich:tabPanel selectedTab problem
                    matt.drees

                    I'm having the same problem, I think. This is what I'm seeing from my debugging:

                    I have a TabPanel whose value is bound to a conversation-scope Seam component's attribute. During the "restore view" phase, conversational components aren't available, so restoreState sets restoredRenderedValue to null, which causes the processDecodes step to be skipped (in getSwitchedFacetsAndChildren()) for everything contained within the tab panel.

                    This sounds like similar behavior to what ylazzari is seeing.

                    Can we open a Jira issue?

                    • 7. Re: rich:tabPanel selectedTab problem
                      matt.drees

                      (I'm using richfaces-3.1.1-CR1, by the way, and Seam 2.0 cvs)

                      • 8. Re: rich:tabPanel selectedTab problem
                        maksimkaszynski

                        Definetly you can ::)

                        • 9. Re: rich:tabPanel selectedTab problem
                          matt.drees
                          • 10. Re: rich:tabPanel selectedTab problem
                            maksimkaszynski

                            Thanks

                            • 11. Re: rich:tabPanel selectedTab problem

                               

                              "matt.drees" wrote:
                              http://jira.jboss.com/jira/browse/RF-1047


                              Thanks. That's exactly the problem that I have. In the meantime, I resolved it by binding the selectedTab attribute to a session scoped variable and I always make sure that when I open a tab set I reset that value to the first tab. Works fine. It definitely isn't a show stopper but when it's fixed, I'll go back to a conversation scoped attribute.

                              • 12. Re: rich:tabPanel selectedTab problem
                                matt.drees

                                It was too painful for me to try to turn my component into a session component, so I came up with this workaround. Maybe others will find it useful until it's fixed.

                                //get around http://jira.jboss.com/jira/browse/RF-1047
                                //TODO: remove when issue fixed
                                @Name("tabPanelWorkaround")
                                public class TabPanelWorkaround {
                                
                                 @In Map<String, UIComponent> uiComponent;
                                
                                 @Observer("org.jboss.seam.beforePhase")
                                 public void fixTabPanel(PhaseEvent event) {
                                 if (event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES)) {
                                 UITabPanel panel = (UITabPanel) uiComponent.get("registrantTypes:registrantTypeTabPanel");
                                 if (panel != null) {
                                 setValue(panel, "restoredRenderedValue", panel.getValue());
                                 }
                                 }
                                 }
                                
                                 private void setValue(Object target, String fieldName, Object value) {
                                 Field field = Reflections.getField(target.getClass(), fieldName);
                                 field.setAccessible(true);
                                 Reflections.setAndWrap(field, target, value);
                                 }
                                
                                }
                                


                                • 13. Re: rich:tabPanel selectedTab problem

                                  Thanks for the code, it works very nice. Perhaps one thing that was not clear to me at once:

                                  "registrantTypes:registrantTypeTabPanel" should be always replaced with the actual id of the tabPanel in the view. E.g.

                                  <rich:tabPanel switchType="ajax" selectedTab="#{bean.selectedTab}" id="richFacesTabPanel">


                                  and

                                  UITabPanel panel = (UITabPanel) uiComponent.get("richFacesTabPanel");



                                  So with this workaround you are kinda forced to use the same ID for all your tabPanels (or use a different instance of this bean for each tabPanel), but I think it is OK. I normally have only one tabPanel per page. ;)

                                  • 14. Re: rich:tabPanel selectedTab problem
                                    matt.drees

                                    If you have lots of tabpanels, the best thing probably would be to search through the component tree for components of type UITabPanel instead of using uiComponent.get().

                                    1 2 Previous Next