0

Is it possible to create multiple selectOneMenu using JSF at run time?

my problem is that i want to create another selectOneMenu each time the user select an item in a previous selectOneMenu.

the first list is loaded when the page loads, here what i've tried:

<h:form id="form">
            <p:panel id="panel">
            <p:selectOneMenu id="selCaterogy" value="#{connaissance.category}" filter="true" filterMatchMode="startsWith">
                <f:selectItem itemLabel="Select une catégorie..." itemValue="" />
                <f:selectItems value="#{connaissanceDAO.category}"/>
                <p:ajax listener="#{connaissance.addComponent()}"/>
            </p:selectOneMenu>
            </p:panel>
        </h:form>

public void addComponent(){
        UIComponent parent = FacesContext.getCurrentInstance().getViewRoot().findComponent("form:panel");
        includeCompositeComponent(parent, "http://primefaces.org/ui", "selectOneMenu", "randomID");
        System.out.println("Added");
    }

the includeCompositeComponent is gotten from this question

public static void includeCompositeComponent(UIComponent parent, String taglibURI, String tagName, String id) {
        FacesContext context = FacesContext.getCurrentInstance();
        UIComponent composite = context.getApplication().getViewHandler()
                .getViewDeclarationLanguage(context, context.getViewRoot().getViewId())
                .createComponent(context, taglibURI, tagName, null);
        composite.setId(id);
        parent.getChildren().add(composite);
    }

but the component isnt getting added. Another thing, if adding components at runtime is possible, can i fill the select menu before i add it to the page?

Using Java EE7, tomcat 8 and primefaces 5.0.

Community
  • 1
  • 1
Ouerghi Yassine
  • 1,835
  • 7
  • 43
  • 72
  • If your quantity of `h:selectOneMenu` is predefined, you can play with `rendered` instead ? – Alexandre Lavoie Sep 03 '14 at 22:42
  • you can use datatable for that in jsf. in every row it will create drop down menu and on every button click it will add new row. isn't it you want to do. I have done same with jsf. let me know if you want to see that code – Jubin Patel Sep 04 '14 at 11:40

2 Answers2

1

If your goal is to only create multiple SelectOneMenue then just use <ui:repeat> and include your components inside it.

This way you can just items to the list binded to <ui:repeat> and set the values you want to those items and it will render to the page.

<ui:repeat value="#{bean.list}" var="item">
   <h:selectOneMenu value="#{item.value}" >
       <h:selectItem itemLabel="..." itemValue="..."></h:selectItem>
   </h:selectOneMenu>
</ui:repeat>

In your bean:

public void change(ValueChangeEvent e){
     theList.add(new SomeObject("value"))
 }
faissalb
  • 1,739
  • 1
  • 12
  • 14
  • i dont know how many selects i have to use, it is according to the data in the database. – Ouerghi Yassine Sep 04 '14 at 11:29
  • You don't have to know how much selects you will insert, just add them to the list and they will show up in the page – faissalb Sep 04 '14 at 11:31
  • I guess you did not understand my situation, they don't show up all at the same time, each time u select an item from a select menu, a new select is added. – Ouerghi Yassine Sep 04 '14 at 11:42
  • if you place a valueChangeListener on your original select then every time the value is changed you can add a new item to the list which will add a new select to the page. – faissalb Sep 04 '14 at 11:45
  • yes, but how can i do that? can you please provide me some code to work with? thank you. – Ouerghi Yassine Sep 04 '14 at 11:47
0

With the Use of Datatable you can add as many row(selectOneMenu) as you want on page.
Out side the table add one button which can add/remove row.

<p:dataTable resizableColumns="true" 
             var="sampleDesc" id="SampleDescTable" rowIndexVar="rowIndex"
                     value="#{sampleBean.sampleDescList.list}" 
                     rendered="#{not empty sampleBean.sampleDescList.list}">
            <p:column>
                    <h:outputLabel value="#{sampleDesc.sampleDescText}"/>
                </p:column>
        <p:column>
            <h:selectOneMenu required="#{not empty sampleBean.sampleDescList.list}" converter="#{sampleDescValueConverter}" 
                                                         id="SampleDescValue" value="#{sampleBean.selectedSampleDescList[rowIndex]}">                                                         
                <f:selectItem itemLabel="Select One" itemValue="#{null}"/>
                            <f:selectItems value="#{sampleDesc.sampleDescValues}" var="sdv" 
                                       itemLabel="#{sdv.sampleDescValuesText}" itemValue="#{sdv}" />

                        </h:selectOneMenu>
                </p:column>    
        </p:dataTable>

related Link on SO

Community
  • 1
  • 1
Jubin Patel
  • 1,959
  • 19
  • 38
  • if the dataTable has a rendered clause itself, it cannot be displayed again once it's rendered value returns false. – tt_emrah Sep 04 '14 at 11:58
  • for that you can remove rendered condition or by default have to generate one selectmenu on first call. – Jubin Patel Sep 04 '14 at 12:02