Java 使用 PrimeFaces 动态生成标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4052581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:01:29  来源:igfitidea点击:

Dynamically Generate Tabs with PrimeFaces

javajsfprimefaces

提问by Marcel Menz

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

马塞尔

回答by BalusC

The p:tabViewhas 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:forEachinstead of ui:repeat. It's already included in Facelets and its default XML namespace is xmlns:c="http://java.sun.com/jsp/jstl/core".

p:tabView有权知道其所有选项卡。因此,您确实需要在视图构建期间创建选项卡,而不是在视图渲染期间。所以使用c:forEach代替ui:repeat. 它已经包含在 Facelets 中,它的默认 XML 命名空间是xmlns:c="http://java.sun.com/jsp/jstl/core".



Updateas 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.

根据您的新问题进行更新:这确实是c:forEach. 您基本上必须自己指定输入 ID/名称并自己收集它们。另一种替代方法是在托管 bean 代码中以编程方式构建选项卡,或在 PrimeFaces 上发布功能请求以添加<p:tabs>采用集合或数组的组件。

回答by Wen

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.

希望它有所帮助,但现在我仍在寻找如何通过代码定义选项卡内容。

回答by Harun

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

ContentTabView = (TabView)

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

FacesContext fc = FacesContext.getCurrentInstance();

ContentTabView = (TabView)

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

the HomeController class must also be in @RequestScoped

HomeController 类也必须在 @RequestScoped 中

回答by Justus

I got dynamic tabs and even content with one exception. I can't get the inputText.setLabel() to work. .setValue() works but not .setLabel()

我得到了动态标签,甚至有一个例外。我无法让 inputText.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. I thought it would auto generate a label for me. But I guess I have to add a label some other way. Any suggestions?

没关系, setLabel 不会做我认为它会做的事情。我以为它会自动为我生成一个标签。但我想我必须以其他方式添加标签。有什么建议?

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.

再次在 bean 中执行此操作的全部原因是因为表单的动态特性和不同 JSF 标记的呈现生命周期。如果您将选项卡视图绑定到支持 bean,那么您将在 tabView 的持续时间内卡在支持 bean 中。如果您在 tabview JSF 声明中放置任何其他内容,它将不会呈现。除非我错过了什么?我无法让 ui:repeat 标签与 p:tab 一起使用,而且我不允许使用 c:foreach 标签。

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.

此外,我无法重用primeface 组件的单个实例化。每次我想将一个组件添加到另一个组件时,我都必须创建一个新实例。

回答by Kevin Rahe

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. 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).

不幸的是,仍然无法在同一个 tabView 中同时包含固定和动态选项卡(正如我想要的那样),甚至无法在不重建视图的情况下动态添加选项卡。幸运的是,在使用 SessionScoped 或 CDI ConversationScoped bean(或者也可能是 JSF ViewScoped bean)时,执行后者并不是什么大问题。

回答by diego matos - keke

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()”在更改选项卡中选择项目:

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

    }