Skip to content Skip to sidebar Skip to footer

How Link To And Target/open A P:tab Within An P:accordionPanel Within A P:tab Within A P:tabview

Primefaces 6.0 (community edition); Mojarra: 2.2.8-18; Glassfish: 4.1; Java version: 1.8.0_102; jQuery [EDIT: 2016-10-05 An answer using pure Primefaces+JSF for the following gener

Solution 1:

A working solution using pure Primefaces+JSF via activeIndex (without any JavaScript pseudo-clicking tricks) has now been found, see below. The rest of the descriptions above concerning failed attempts at synchronising JavaScript clicking of an outer p:tab then an inner p:tab are now considered academic (and are now low priority for me), but any feedback on why they failed is still welcome.


The following using activeIndex in an outer p:tabView then the inner p:accordionPanel works fine with dynamic non-cached.

One of the reasons I was persisting with (but have for now abandoned) attempts to imitate clicks on outer then inner tabs using id or widgetVar was so that I could avoid hard-coded activeIndex numbers (so that the solution would be robust against inserting new tabs, because each target id or widgetVar is stable); it turns out if one uses f:viewParam parameters bound to a navigation bean throughout one does not have to hard-code any activeIndex values.

In the page tabs_accordions.xhtml with the p:tabView/p:tab/p:accordionPanel/p:tab nesting:

<f:view>
  <f:metadata>                
   <f:viewParam name="tabViewActiveIndex" value="#{navBean.tabViewActiveIndex}" required="false"/>
   <f:viewParam name="accordionActiveIndex" value="#{navBean.accordionActiveIndex}" required="false"/>
...                                
 </f:metadata>
</f:view>

<p:tabView 
 id='tabview' 
 dynamic="true" 
 cache="false" 
 widgetVar="widgetTabView"
 activeIndex="#{navBean.tabViewActiveIndex}"
>

 <p:tab title="Outer Tab1" id="tabOuter1">
   Content of Tab1
 </p:tab>

 <p:tab title="Outer Tab2" id="tabOuter2" >

  <p:accordionPanel 
    id="accordion"
    dynamic="true" 
    cache="false" 
    widgetVar="widgetAccordion"
    activeIndex="#{navBean.accordionActiveIndex}" 
    >

     <p:tab title="Inner Tab1" id="tabInner1">
       <h:link 
         outcome="dummy_edit_viewParam" 
         value="Link1: Go to pretend edit page then return to this 1st inner tab">
          <f:param name="stem" value="tabs_accordions"/>
          <f:param name="tabViewActiveIndex" value="#{navBean.tabViewActiveIndex}"/>
          <f:param name="accordionActiveIndex" value="#{navBean.accordionActiveIndex}"/>
         </h:link>                            
      </p:tab>

     <p:tab title="Inner Tab2 " id="tabInner2">
         <h:link 
            outcome="dummy_edit_viewParam"
            value="Link2: Go to pretend edit page then return to this 2nd inner tab">
            <f:param name="stem" value="tabs_accordions"/>
            <f:param name="tabViewActiveIndex" value="#{navBean.tabViewActiveIndex}"/>
            <f:param name="accordionActiveIndex" value="#{navBean.accordionActiveIndex}"/>
          </h:link>                                                        
      </p:tab>

   </p:accordionPanel>
 </p:tab>
</p:tabView>

The links (from either inner tab) go to dummy_edit_viewParam.xhtml, which has:

<f:view>
 <f:metadata>
   <f:viewParam name="stem" value="#{navBean.stem}" required="true"/>
   <f:viewParam name="tabViewActiveIndex" value="#{navBean.tabViewActiveIndex}" required="true"/>
   <f:viewParam name="accordionActiveIndex" value="#{navBean.accordionActiveIndex}" required="true"/>
  </f:metadata>
</f:view>

Then on (for example) saving after some edits, one can return to whatever inner tab one came from.

The interesting bit is that in p:tabView and p:accordionPanel this not only opens a desired tab, it also sets the corresponding value in the navigation bean when a tab is clicked (i.e. opening a tab other than the tab targeted by the initial parameters):

activeIndex="#{navBean.tabViewActiveIndex}" 

activeIndex="#{navBean.accordionActiveIndex}" 

For example, if you enter the view cycle with this it opens the 1st inner tab of the 2nd outer tab:

/faces/tabs_accordions.xhtml?tabViewActiveIndex=1&accordionActiveIndex=0

If you then click on the 2nd inner tab of the 2nd outer tab it will set #{navBean.accordionActiveIndex} to 1 corresponding to that tab !

So when one follows this link (from within the 2nd inner tab of the 2nd outer tab) this will send info to target the correct tab:

<p:tab title="Inner Tab2 " id="tabInner2">
  <h:link 
    outcome="dummy_edit_viewParam"
    value="Link2: Go to pretend edit page then return to this 2nd inner tab">
    <f:param name="stem" value="tabs_accordions"/>
    <f:param name="tabViewActiveIndex" value="#{navBean.tabViewActiveIndex}"/>
    <f:param name="accordionActiveIndex" value="#{navBean.accordionActiveIndex}"/>
  </h:link>                                                        
</p:tab>

When these params are used to eventually return to the original tabView/accordionPanel (such as after editing values in another page and returning on save) it will now target that 2nd inner tab automatically:

/faces/tabs_accordions.xhtml?tabViewActiveIndex=1&accordionActiveIndex=1

For example, the action of a save button for a page to return from might be:

public String saveReturnToTabViewAccordionUseParams() {    
  return "tabs_accordions?faces-redirect=true&includeViewParams=true";
}    

And all of this then works without any hard-coding of each target activeIndex.


Post a Comment for "How Link To And Target/open A P:tab Within An P:accordionPanel Within A P:tab Within A P:tabview"