tags:

views:

935

answers:

3

In my application the component has to change dynamically. I am having a Datatable in that i am having two column, first is a <h:selectoneMenu> in the menu i am having two data(the data are 1 and 2) if 1 is selected then a <h:inputText> should appear and if 2 is selected <h:selectoneMenu> should appear. Need help to do this?

My JSF

   <h:selectOneMenu id="menu" value="#{sample.data}" rendered="true" valueChangeListener="#{sample.change}">
    <f:selectItem itemLabel="Data" itemValue=""/>
    <f:selectItems value="#{sample.list1}"/>
            <a4j:support event="onchange" reRender="text" />
</h:selectOneMenu>
<h:inputText id="text" value="#{sample.input}" rendered="#{sample.status}" />

My Manged Bean Class

public class Sample {
private Boolean status;          //Getter & Setter
private List<SelectItem> list1;  //Setter
private String input;            //Getter & Setter
private String data;             //Getter & Setter

public void change(ValueChangeEvent event){
System.out.println((String)event.getNewValue());
if(((String)event.getNewValue()).equals("value1")){
    status=true;
}
else if(((String)event.getNewValue()).equals("value2")){
    status=false;
}
}
public Boolean getStatus(){
if(status==null){
    status=true;
}
return status;
}
public List<SelectItem> getList1() {
if(list1==null) {
list1 = new ArrayList<SelectItem>();
list1.add(new SelectItem("value1", "label1"));
list1.add(new SelectItem("value2", "label2"));
}
return list1;
}
}
+5  A: 

My advice would be: do not add/remove component dynamically. Solve your problem another way:

  • Toggle visibility of components
  • Rebind the data belonging to a component

Adding/removing component dynamically is always a source of trouble and chances are that you can do it another way much simpler.

In your case, playing with the visibility using rendered attribute should be enough.

ewernli
then how to change the visibility according to the data provided...
Hari
can we change the visibility in the managed bean?
Hari
As ewernli said you have to render again the component you want to be changed. You can do this by reloading the full page or by reloading the component you want using AJAX. We should have more info of what component library are you using for giving you a more detailed answer.
Averroes
i am using jsf2.0 and richfaces for ajax support
Hari
+2  A: 

Let's say you have something like this

<h:selectoneMenu id="selectOne" rendered="#{myBean.selectOneRendered}">
<h:inputText id="input" rendered="#{!myBean.selectOneRendered}">

You have both the components in your jsp page. Once you reload the jsp the rendered prorpertie will be checked.

in your myBean you must to have something like this

public boolean isSelectOneRendered(){
 boolean rendered;
 //Do something here
 return rendered;
}

if the result is true then the selectOne will be rendered and the input will not and the other way round.

Averroes
+2  A: 

Easiest (and least user-friendly due to flash of content) way would roughly be the following, using onchange="submit()" to submit the dropdown on every change, in combination with the rendered attribute on the input elements which depends on the selected value (to learn more about how to use the rendered attribute, check this answer):

<h:column>
    <h:selectOneMenu value="#{row.item}" onchange="submit()">
        <f:selectItem itemValue="1" itemLabel="one" />
        <f:selectItem itemValue="2" itemLabel="two" />
    </h:selectOneMenu>
</h:column>

<h:column>
    <h:inputText value="#{row.input1}" rendered="#{row.item == 1}" />
    <h:inputText value="#{row.input2}" rendered="#{row.item == 2}" />
</h:column>

To add a bit more user-friendliness, grab JS/Ajax. If you're already on JSF 2.0, use f:ajax, else grab a component library like RichFaces Ajax4jsf.

A better way would be to move this logic to the bean's action method so that you can just stick to one input element:

public void submit() {
    for (Row row : rows) {
        switch (row.getItem()) {
            case 1:
                // Handle row.getInput() specifically for selected item 1.
                break;
            case 2:
                // Handle row.getInput() specifically for selected item 2.
                break;
        }
    }
}
BalusC
thanks BalusC before seeing ur answer i had done mostly the same. but i am not getting the output. i have added my code,Kindly help
Hari
You've basically designed your code as if it is for a session scoped bean. Is it also in the session scope? It will not work if you put bean in request scope.
BalusC
its in the Session scope only..
Hari
when do the vice-versa like according to the input from the inputtext and rerendering the selectoneMenu it working fine.
Hari
for the present code the inputtext box is not rerendering, i dont know the reason for it.
Hari