简体   繁体   English

使用PrimeFaces动态生成制表符

[英]Dynamically Generate Tabs with PrimeFaces

Hi I would like to iterate over a list of person-object and show the data in a tab per person. 嗨,我想迭代一个person-object列表,并在每个人的标签中显示数据。 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: PrimeFaces 3.x的tabView现在支持动态数量的选项卡,并增加了自己的迭代功能:

<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. 不幸的是,仍然无法在同一个tabView中包含固定和动态标签(我想做),甚至无需重建视图即可动态添加标签。 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). 幸运的是,使用SessionScoped或CDI ConversationScoped bean(或者也许是JSF ViewScoped bean)时,做后者并不是什么大问题。

I would binding the tabView to server back bean 我将tabView绑定到服务器后端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. 希望它有所帮助,但现在我仍然在寻找如何通过代码定义Tab内容。

The p:tabView has to know about all of its tabs. p:tabView必须知道它的所有选项卡。 So you really need to create tabs during view build time, not during view render time. 因此,您确实需要在视图构建时创建选项卡,而不是在视图渲染时创建选项卡。 So use c:forEach instead of ui:repeat . 所以使用c:forEach而不是ui:repeat It's already included in Facelets and its default XML namespace is xmlns:c="http://java.sun.com/jsp/jstl/core" . 它已经包含在Facelets中,其默认的XML命名空间是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 . 根据你的新问题 更新 :这确实是c:forEach的缺点。 You've basically got to specify the input ID's/names yourself and gather them yourself. 您基本上必须自己指定输入ID /名称并自己收集它们。 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. 另一种方法是以编程方式在托管bean代码中构建选项卡,或者在PrimeFaces上发布功能请求以添加带有集合或数组的<p:tabs>组件。

In Primefaces 5.X You should use this to generate many tabs inside tabview 在Primefaces 5.X中您应该使用它在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()" : 并且,在您的java控制器中,您可以使用“event.getData()”在changetab中选择Item:

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());

    }

I got dynamic tabs and even content with one exception. 我有一个动态标签甚至内容有一个例外。 I can't get the inputText.setLabel() to work. 我无法使inputText.setLabel()工作。 .setValue() works but not .setLabel() .setValue()有效但不是.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. 没关系,setLabel没有做我认为它做的事情。 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. 在bean中执行此操作的全部原因再次是因为表单的动态特性和不同JSF标记的呈现生命周期。 If you bind a tab view to a backing bean then you are stuck in the backing bean for the duration of the tabView. 如果将选项卡视图绑定到辅助bean,那么在tabView的持续时间内,您将被卡在辅助bean中。 If you put ANYTHING else in the tabview JSF declaration it will not render. 如果你在tabview JSF声明中放入其他任何东西,它将不会呈现。 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. 我无法使用ui:repeat标签与p:tab一起使用,我不能使用c:foreach标签。

Also i couldn't reuse a single instantiation of the primeface components. 此外,我无法重用primeface组件的单个实例。 I had to create a new instance everytime I wanted to add a component to another component. 我每次想要将组件添加到另一个组件时都必须创建一个新实例。

the code 代码

//generate tabs by code //按代码生成标签

tabView = new TabView(); tabView = new TabView();

will produce error in browser: property not found; 将在浏览器中产生错误:找不到属性; instead of using new keyword, you must use: 而不是使用new关键字,您必须使用:

FacesContext fc = FacesContext.getCurrentInstance(); FacesContext fc = FacesContext.getCurrentInstance();

ContentTabView = (TabView) ContentTabView =(TabView)

fc.getApplication().createComponent("org.primefaces.component.TabView"); fc.getApplication()createComponent( “org.primefaces.component.TabView”);

the HomeController class must also be in @RequestScoped HomeController类也必须在@RequestScoped中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM