Dynamically adding fields to JSF form on button click [duplicate] - jsf

Can I add JSF components dynamically? I need to have a form with a button which should add one <h:inputText> to the form. Is this possible?
I know this should be possible in JavaScript somehow. Do anybody know how to do this in JSF? I think the major problem is how do I get or set values of new inputs via #{value}.

Use an iterating component like <h:dataTable> or <ui:repeat> to display a dynamically sized List of entities. Make the bean #ViewScoped to ensure that the list is remembered across postbacks on the same view instead of recreated over and over.
Kickoff example with <h:dataTable> (when using <ui:repeat> simply replace <h:dataTable> by <ui:repeat>, and <h:column> by e.g. <li> or <div>):
<h:form>
<h:dataTable value="#{bean.items}" var="item">
<h:column><h:inputText value="#{item.value}" /></h:column>
<h:column><h:commandButton value="remove" action="#{bean.remove(item)}" /></h:column>
</h:dataTable>
<h:commandButton value="add" action="#{bean.add}" />
<h:commandButton value="save" action="#{bean.save}" />
</h:form>
Managed bean:
#Named
#ViewScoped
public class Bean {
private List<Item> items;
#PostConstruct
public void init() {
items = new ArrayList<>();
}
public void add() {
items.add(new Item());
}
public void remove(Item item) {
items.remove(item);
}
public void save() {
System.out.println("items: " + items);
}
public List<Item> getItems() {
return items;
}
}
Model:
public class Item {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String toString() {
return String.format("Item[value=%s]", value);
}
}
See also:
Recommended JSF 2.0 CRUD frameworks
How to create dynamic JSF form fields
How to implement a dynamic list with a JSF 2.0 Composite Component?
How to choose the right bean scope?

It's should be like that
Bind a form tag to the bean property
<form binding="#{myBean.myform}">...</form>
#ManagedBean("myBean")
public class Bean{
property HtmlForm myform;
}
on event, create a new instance of the input component
HtmlInputText input=new HtmlInputText();
and attach to the your form
myform.getChildren().add(input);

Use h:dataTable to add elements dynamically... Have a list of any type you want to provide values for dataTable...
In h:dataTable... you can include the element tag to create inside <h:column>
It will be used to generate elements you want to create dynamically.

Related

JSF processing a non-JSF form? [duplicate]

Can I add JSF components dynamically? I need to have a form with a button which should add one <h:inputText> to the form. Is this possible?
I know this should be possible in JavaScript somehow. Do anybody know how to do this in JSF? I think the major problem is how do I get or set values of new inputs via #{value}.
Use an iterating component like <h:dataTable> or <ui:repeat> to display a dynamically sized List of entities. Make the bean #ViewScoped to ensure that the list is remembered across postbacks on the same view instead of recreated over and over.
Kickoff example with <h:dataTable> (when using <ui:repeat> simply replace <h:dataTable> by <ui:repeat>, and <h:column> by e.g. <li> or <div>):
<h:form>
<h:dataTable value="#{bean.items}" var="item">
<h:column><h:inputText value="#{item.value}" /></h:column>
<h:column><h:commandButton value="remove" action="#{bean.remove(item)}" /></h:column>
</h:dataTable>
<h:commandButton value="add" action="#{bean.add}" />
<h:commandButton value="save" action="#{bean.save}" />
</h:form>
Managed bean:
#Named
#ViewScoped
public class Bean {
private List<Item> items;
#PostConstruct
public void init() {
items = new ArrayList<>();
}
public void add() {
items.add(new Item());
}
public void remove(Item item) {
items.remove(item);
}
public void save() {
System.out.println("items: " + items);
}
public List<Item> getItems() {
return items;
}
}
Model:
public class Item {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String toString() {
return String.format("Item[value=%s]", value);
}
}
See also:
Recommended JSF 2.0 CRUD frameworks
How to create dynamic JSF form fields
How to implement a dynamic list with a JSF 2.0 Composite Component?
How to choose the right bean scope?
It's should be like that
Bind a form tag to the bean property
<form binding="#{myBean.myform}">...</form>
#ManagedBean("myBean")
public class Bean{
property HtmlForm myform;
}
on event, create a new instance of the input component
HtmlInputText input=new HtmlInputText();
and attach to the your form
myform.getChildren().add(input);
Use h:dataTable to add elements dynamically... Have a list of any type you want to provide values for dataTable...
In h:dataTable... you can include the element tag to create inside <h:column>
It will be used to generate elements you want to create dynamically.

JSF inputtext + Converter

First, I show my code:
XHTML page:
<h:body>
<h:form id="ffffffffff">
<p:inputText value="#{prueba.dato}" >
<p:ajax event="keyup" process="#this" />
</p:inputText>
</h:form>
</h:body>
Bean:
#ManagedBean
#ViewScoped
public class Prueba implements Serializable {
private String dato = "ASSSS";
public String getDato() {
return dato;
}
public void setDato(String dato) {
this.dato = dato;
System.out.println("DAAAAAA: " + dato);
}
public void listener() {
System.out.println("LISTENEEEEEEEEEEEEEEEEEEEEEEEEEE");
}
}
Converter
#FacesConverter
public class SnaCarreraConverter extends SelectItemsConverter {
//CODE
}
My problem, setDato is always getting a null value. But when I modify the converter to this:
#FacesConverter(forClass=SnaCarrera.class)
adding forClass resolve my problem, I don't know why this happens. Is The inputText trying to find a Converter without add the converter property?
First of all, the SelectItemsConverter is for <f:selectItems>. The <p:inputText> is not a <f:selectItems>. So the SelectItemsConverter is useless for the <p:inputText>. See also its documentation and showcase.
Second, it's normal to give the Converter implementation an ID or a "for-class" in order to use it. Otherwise you can't refer it in the <x:inputSomething converter> attribute, or in the <f:converter> tag, or you can't auto-associate it with a certain class. This requirement is totally unrelated to the SelectItemsConverter. It's just required by standard JSF spec.

JSF h:selectBooleanCheckbox inside ui:repeat - varStatus.index works, var doesn't

Can someone please explain this phenomenon?
I am using Mojarra 2.1.6 - Glassfish 3.1.2.
I have a checkbox inside a ui:repeat. The ui:repeat is looping over a list of booleans from my managed bean. Each individual checkbox is bound to an element of that list. For example:
<ui:repeat var="checkbox" value="#{checkboxTestBean.list}" varStatus="status">
<h:selectBooleanCheckbox value="#{checkbox}"/>
</ui:repeat>
The problem is the values aren't getting applied to the managed bean. When I submit and re-render the form, the values don't stick.
However, if I index into the managed bean element explicitly, by changing value=#{checkbox} above to value="#{checkboxTestBean.list[status.index]}", everything works.
Any ideas why that might be the case?
XHTML:
<h:form>
<div>
Using value="#\{var\}"
<ui:repeat var="checkbox" value="#{checkboxTestBean.list}" varStatus="status">
<h:selectBooleanCheckbox value="#{checkbox}"/>
</ui:repeat>
</div>
<div>
Using value="#\{varStatus.index\}"
<ui:repeat var="checkbox" value="#{checkboxTestBean.list}" varStatus="status">
<h:selectBooleanCheckbox value="#{checkboxTestBean.list[status.index]}"/>
</ui:repeat>
</div>
<h:commandLink actionListener="#{checkboxTestBean.actionListener}">
PROCESS FORM
<f:ajax execute="#form" render="#form"/>
</h:commandLink>
</h:form>
Java:
#ManagedBean
#ViewScoped
public class CheckboxTestBean {
public List<Boolean> list = new ArrayList<Boolean>();
public CheckboxTestBean() {
for (int i = 0; i < 5; i++) {
list.add(Boolean.FALSE);
}
}
public void actionListener(ActionEvent evt) {
System.out.println("*** dumping whole form");
System.out.println("*** list = " + list);
}
public List<Boolean> getList() {
return list;
}
public void setList(List<Boolean> list) {
this.list = list;
}
}
That's because the Boolean as being an immutable class doesn't have a setter method for the value. When referencing it as a list item by index instead, EL will be able to set the new value on the List by index like so list.add(status.index, newValue). An alternative is to make it a property of a mutable model class and have a collection of it instead like so List<Item> which you reference by <h:selectBooleanCheckbox value="#{item.checkbox}"/>.
This is not specifically related to Boolean, you would have exactly the same problem when using for example List<String> in an <ui:repeat><h:inputText>.
See also:
Using <ui:repeat><h:inputText> on a List<String> doesn't update model values

How to dynamically add JSF components

Can I add JSF components dynamically? I need to have a form with a button which should add one <h:inputText> to the form. Is this possible?
I know this should be possible in JavaScript somehow. Do anybody know how to do this in JSF? I think the major problem is how do I get or set values of new inputs via #{value}.
Use an iterating component like <h:dataTable> or <ui:repeat> to display a dynamically sized List of entities. Make the bean #ViewScoped to ensure that the list is remembered across postbacks on the same view instead of recreated over and over.
Kickoff example with <h:dataTable> (when using <ui:repeat> simply replace <h:dataTable> by <ui:repeat>, and <h:column> by e.g. <li> or <div>):
<h:form>
<h:dataTable value="#{bean.items}" var="item">
<h:column><h:inputText value="#{item.value}" /></h:column>
<h:column><h:commandButton value="remove" action="#{bean.remove(item)}" /></h:column>
</h:dataTable>
<h:commandButton value="add" action="#{bean.add}" />
<h:commandButton value="save" action="#{bean.save}" />
</h:form>
Managed bean:
#Named
#ViewScoped
public class Bean {
private List<Item> items;
#PostConstruct
public void init() {
items = new ArrayList<>();
}
public void add() {
items.add(new Item());
}
public void remove(Item item) {
items.remove(item);
}
public void save() {
System.out.println("items: " + items);
}
public List<Item> getItems() {
return items;
}
}
Model:
public class Item {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String toString() {
return String.format("Item[value=%s]", value);
}
}
See also:
Recommended JSF 2.0 CRUD frameworks
How to create dynamic JSF form fields
How to implement a dynamic list with a JSF 2.0 Composite Component?
How to choose the right bean scope?
It's should be like that
Bind a form tag to the bean property
<form binding="#{myBean.myform}">...</form>
#ManagedBean("myBean")
public class Bean{
property HtmlForm myform;
}
on event, create a new instance of the input component
HtmlInputText input=new HtmlInputText();
and attach to the your form
myform.getChildren().add(input);
Use h:dataTable to add elements dynamically... Have a list of any type you want to provide values for dataTable...
In h:dataTable... you can include the element tag to create inside <h:column>
It will be used to generate elements you want to create dynamically.

JSF Pass parameter to another page

In JSF how do you pass a parameter from one page to another without using managed beans?
e.g.
<h:dataTable value="#{myObjects}" var="object">
<h:column>
<h:commandButton value="View Object" action="view-object"/>
</h:column>
</h:dataTable>
I want to pass the object so an the next page I can simply do #{object.displayValue}
Thxs.
First of all, you can't do this without using a managed bean.
The best approach would be using a DataModel as the value of the h:dataTable so that you can retrieve the currently selected row object by DataModel#getRowData(). You only need to ensure that the bean preserves the same model in the subsequent request. In other words, fill the model in the constructor of the bean.
<h:form>
<h:dataTable value="#{bean.model}" var="item">
<h:column>
<h:commandButton value="View Object" action="#{bean.view}"/>
</h:column>
</h:dataTable>
</h:form>
With a request (or session) scoped bean which look like this:
public class Bean {
private DataModel model;
private Item item;
public Bean() {
List<Item> list = new ArrayList<Item>();
list.add(new Item(1, "value1"));
list.add(new Item(2, "value2"));
list.add(new Item(3, "value3"));
model = new ListDataModel(list);
}
public String view() {
item = (Item) model.getRowData();
return "view";
}
public DataModel getModel() {
return model;
}
public Item getItem() {
return item;
}
}
I assume that you're using JSF 1.x and not 2.x yet, else a #ViewScoped bean was better.
And in the next page:
<p>#{bean.item.value}</p>

Resources