Hi I would like to iterate over a list of person-object and show the data in a tab per person. I tried:
<p:tabView>
<ui:repeat ...>
<p:tab title="#{expression}>
</ui:repeat>
</p:tabView>
This is not working. Any help appreciated
Marcel
Hi I would like to iterate over a list of person-object and show the data in a tab per person. I tried:
<p:tabView>
<ui:repeat ...>
<p:tab title="#{expression}>
</ui:repeat>
</p:tabView>
This is not working. Any help appreciated
Marcel
PrimeFaces 3.x's tabView now supports a dynamic number of tabs with the addition of its own iteration feature:
<p:tabView value="#{myBean.tabList}" var="tabItem">
<p:tab title="#{tabItem.tabTitle}">
<h:outputText value="#{tabItem.valueA}"/>
... etc.
</p:tab>
</p:tabView>
Unfortunately, it's still not possible to include both fixed and dynamic tabs in the same tabView (as I wanted to do), or even dynamically add a tab without rebuilding the view. Fortunately, doing the latter isn't a big deal when using a SessionScoped or CDI ConversationScoped bean (or perhaps a JSF ViewScoped bean as well).
I would binding the tabView to server back bean
<p:tabView binding="#{homeController.tabView}">
</p:tabView>
public class HomeController {
private TabView tabView;
public TabView getTabView(){
return tabView;
}
public void setTabView(TabView tabView){
this.tabView = tabView;
}
public HomeController(){
//generate tabs by code
tabView = new TabView();
Tab tab1 = new Tab();
tab1.setTitle("Business Partner");
Tab tab2 = new Tab();
tab2.setTitle("Manage Favorites");
tabView.getChildren().add(tab1);
tabView.getChildren().add(tab2);
}
}
Hope it helps, but now I'm still looking how to define the Tab Content by code.
The p:tabView
has to know about all of its tabs. So you really need to create tabs during view build time, not during view render time. So use c:forEach
instead of ui:repeat
. It's already included in Facelets and its default XML namespace is xmlns:c="http://java.sun.com/jsp/jstl/core"
.
Update as per your new problem with this: that's indeed a disadvantage of c:forEach
. You've basically got to specify the input ID's/names yourself and gather them yourself. Another alternative is to build the tabs programmatically in managed bean code, or to post a feature request at PrimeFaces to add a <p:tabs>
component which takes a collection or array.
I got dynamic tabs and even content with one exception. I can't get the inputText.setLabel() to work. .setValue() works but not .setLabel()
Here is the redacted and essential code. I used
XTML
...
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:csxc="http://java.sun.com/jsf/composite/csxcomponent"
xmlns:p="http://primefaces.prime.com.tr/ui"
...
<p:tabView rendered="true" style="width:500px;float:left;margin-top:10px;margin-left:5px;" binding="#{scenarioInputs.tabView }">
</p:tabView>
Java Bean
@ManagedBean(name = "scenarioInputs")
@RequestScoped
...
public TabView getTabView() {
FacesContext fc = FacesContext.getCurrentInstance();
tabView = (TabView) fc.getApplication().createComponent(
"org.primefaces.component.TabView");
String[] value = fc.getExternalContext().getRequestParameterValuesMap()
.get("cat");
int val = 0;
// error check the value to insure compatibility
if (value.length < 1 || value.length > 1) {
val = 0;
} else {
try {
val = Integer.parseInt(value[0]);
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
val = 0;
}
}
// get the sub category title
String[] temp = this.getSubCategories(val);
// dynamically create the tabs needed for this category
for (String sub : temp) {
Tab tab = new Tab();
tab.setTitle(sub);
Random randomGenerator = new Random();
int total = Math.max(1, randomGenerator.nextInt(6));
for (int i = 0; i < total; i++) {
InputText inputtext = new InputText();
// this method does not work, or if it does, it doesn't do what
// I think it should do.
inputtext.setLabel("LabelYo");
// set the value of the text box
inputtext.setValue("value");
tab.getChildren().add(inputtext);
}
tabView.getChildren().add(tab);
}
return tabView;
}
Never mind, setLabel doesn't do what I think it does. I thought it would auto generate a label for me. But I guess I have to add a label some other way. Any suggestions?
I found it!!!!
HtmlOutputLabel hol = new HtmlOutputLabel();
hol.setValue("label");
hol.setStyleClass("label");
tab.getChildren().add(hol);
Once again the whole reason for doing this in a bean is because the dynamic nature of the form and the rendering lifecycle of the different JSF tags. If you bind a tab view to a backing bean then you are stuck in the backing bean for the duration of the tabView. If you put ANYTHING else in the tabview JSF declaration it will not render. Unless I missed something? I couldn't get the ui:repeat tag to work with the p:tab and I am not allowed to use c:foreach tags.
Also i couldn't reuse a single instantiation of the primeface components. I had to create a new instance everytime I wanted to add a component to another component.
In Primefaces 5.X You should use this to generate many tabs inside tabview
<p:tabView id="tabdinamico2" value="#{proyectoMb.beanList}" var="item" orientation="left" effect="fade" effectDuration="fast">
<p:ajax event="tabChange" listener="#{proyectoMb.loadCampoEquipo}" update="frmProyecto:tabProyecto:tabdinamico2"/>
<p:tab title="#{item.nombre}">
<h:outputText value= "#{item.id}"/>
<h:outputText value= "#{item.nombre}"/>
</p:tab>
</p:tabView>
and , In your java controller you get the Item selected in the changetab with "event.getData()" :
public void loadCampoEquipo(TabChangeEvent event) {
System.out.println("loadCampoEquipo");
System.out.println("tab1:" + event.getTab().getId());
System.out.println("tab2: " + event.getData());
System.out.println("tab3:" + event.getSource().toString());
System.out.println("tab4: " + event.getTab().getTitle());
System.out.println("tab5: " + event.getTab().getTitletip());
}
the code
//generate tabs by code
tabView = new TabView();
will produce error in browser: property not found; instead of using new keyword, you must use:
FacesContext fc = FacesContext.getCurrentInstance();
ContentTabView = (TabView)
fc.getApplication().createComponent("org.primefaces.component.TabView");
the HomeController class must also be in @RequestScoped