primefaces accordion panel within single form - va

2019-07-07 09:07发布

I have checked around but I didn't found a clear example on how to submit the accordion using a single form. The problem I find is when I want to process (validate) only fields of the opened tab.

The structure of my page is as follows:

<h:form>
    <p:accordionPanel activeIndex="#{bean.selectedTab}">
        <p:ajax event="tabChange" listener="#{bean.tabChangeListener}"/>

        <p:tab title="Tab1" id="t1">
            <p:inputText id="reqField1" required="true"/>
        </p:tab>
        <p:tab title="Tab2" id="t2">
            <p:inputText id="reqField2" required="true"/>
        </p:tab>
   </p:accordionPanel>

   <p:commandButton update="list" immediate="true" actionListener="#{bean.addRecord}"/>                     
</h:form>

method:

@SessionScoped
public class Bean{
    public void tabChangeListener(AjaxBehaviorEvent evt){
        AccordionPanel panel = (AccordionPanel) evt.getComponent();
        // getLoadedTabs() returns an empty list
        String currentlyLoadedTabId = panel.getLoadedTabs().get(this.selectedTab).getClientId(); 

    }
}

Is there anyway to specify the id of the currently opened tab as part of the process attribute in p:commandButton tag?

UPDATE When Tab1 is open, on submit, I want to be validated only reqField1 and not reqField2. Viceversa, when Tab2 is open, I want to be validated only reqField2 and not reqField1.

1条回答
再贱就再见
2楼-- · 2019-07-07 09:49

Try this.

  1. Bind the activeIndex of the accordionPanel to a backing bean int attribute

    activeIndex="#{myBean.selectedTab}"
    
  2. Get the id of the currently selected tab using the bound activeIndex. To do this in your actionListener, get a handle on the accordion panel

    EDIT: Since your actionListener has been set to immediate, the activeIndex and selectedTab will need to be updated via ajax. Add the following <p:ajax/> to your accordionPanel

    <p:ajax event="tabChange" listener="#{bean.tabChangeListener}" />
    

    In your backing bean, you'll now have

    public void (AjaxBehaviorEvent evt){
     AccordionPanel panel = (AccordionPanel) evt.getComponent();
     String currentlyLoadedTabId = panel.getLoadedTabs().get(this.selectedTab).getClientId(); 
    
    }
    
  3. Using the the id you got from 2 above, you can include that in the JSF list of things to be rerendered using ajax on the server side. In the same action listener method:

     FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(currentlyLoadedTabId);
    

Alternatively, you might just consider placing a command button in each of those tabs and having a form in each tab as well. This way, each command button processes only it's own parent form

查看更多
登录 后发表回答