This question already has answers here:
How to dynamically add JSF components
(3 answers)
Closed 7 years ago.
I want to add dynamically input fields. Like
Is there a good component in PF on how to add such a component?
Pls give me a hint on how you would develop it, cause I have no clue at the moment.
I really appreciate your answer.
My technology stack:
Hibernate: 4.0.1.Final
Spring: 3.1.1.RELEASE
Primefaces: 3.5
jsf-version: 2.2.0-m08
PrimefacesMobile-version: 0.9.3
Apache Tomcat/7.0.12
Maybe the following piece of code can help you out, I'm afraid there's not a component for this (at least to my knowledge):
HTML
<h:form>
<ui:repeat value=#{bean.values}
var="value">
<h:inputText value="#{value}" />
<br />
</ui:repeat>
<h:commandButton value="Extend">
<f:ajax listener="#{bean.extend}"
process="#form"
render="#form" />
</h:commandButton>
<h:commandButton action="#{bean.submit}"
value="Save" />
</h:form>
BEAN
#ManagedBean
#ViewScoped
public class Bean {
private List<String> values;
#PostConstruct
public void init() {
values = new ArrayList();
values.add("");
}
public void submit() {
// save values in database
}
public void extend() {
values.add("");
}
public void setValues(List<String> values) {
this.values = values;
}
public List<String> getValues() {
return values;
}
}
Related
This question already has answers here:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
(12 answers)
How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?
(2 answers)
Closed 2 years ago.
I'm working with JSF and want to save a choose from a dropdown, but it doesn't save it, what can I do?
xhtml:
<h:form>
<h:selectOneMenu value="#{spielController.ausgewaehlteKategorie}" >
<f:selectItems value="#{spielController.alleKategorien}"/>
</h:selectOneMenu>
</h:form>
<br/>
<h:form>
<h:commandButton action="#{spielController.ladeFrage()}" value="Spielen"/>
</h:form>
BackingBean:
#Named(value = "spielController")
#SessionScoped
public class SpielController implements Serializable {
private String ausgewaehlteKategorie;
private ArrayList<String> alleKategorien = new ArrayList<>();
public SpielController() throws SQLException {
for (String kategorie : kdao.getKategorien()) {
alleKategorien.add(kategorie);
}
}
public String getAusgewaehlteKategorie() {
return ausgewaehlteKategorie;
}
public void setAusgewaehlteKategorie(String ausgewaehlteKategorie) {
this.ausgewaehlteKategorie = ausgewaehlteKategorie;
}
public ArrayList<String> getAlleKategorien() {
return alleKategorien;
}
public void setAlleKategorien(ArrayList<String> alleKategorien) {
this.alleKategorien = alleKategorien;
}
}
I get the things from a DAO-class and it works, but when I press the button, it doesn't work because the choose I made above wasn't saved
Move
<h:commandButton action="#{spielController.ladeFrage()}" value="Spielen"/>
to h:form
<h:form>
<h:selectOneMenu value="#{spielController.ausgewaehlteKategorie}" >
<f:selectItems value="#{spielController.alleKategorien}"/>
</h:selectOneMenu>
<br/>
<h:commandButton action="#{spielController.ladeFrage()}" value="Spielen"/>
</h:form>
This is the reason why your setter not invoked.
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.
This question already has answers here:
How to ajax-refresh dynamic include content by navigation menu? (JSF SPA)
(3 answers)
Closed 6 years ago.
I try to update component panelgroup after clicking on commandLink, but it doesn't succeed. I have already tryed many ways but nothing helps. Please, say me, what should I do that to update panelgroup?
<h:panelGroup layout="block" id="content">
<h:panelGroup layout="block" id="nav">
<h:form id="itemsMenu">
<h:commandLink value="View" update="workplace" actionListener="#{main.determineAction}">
<f:param name="link" value="Viewing telephone book"/>
</h:commandLink>
</h:form>
</h:panelGroup>
<h:panelGroup id="workplace">
<h:panelGroup layout="block" rendered="#{main.responseRendered}">
<ui:include src="#{main.linkPage}"/>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
Bean code:
#ManagedBean(name = "main")
#ViewScoped public class MainBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> listItemsMenu;
private String linkPage;
private boolean responseRendered = false;
public boolean isResponseRendered() {
return responseRendered;
}
public void setResponseRendered(final boolean responseRendered) {
this.responseRendered = responseRendered;
}
public String getLinkPage() {
return linkPage;
}
public void setLinkPage(final String linkPage) {
this.linkPage = linkPage;
}
public void determineAction(final ActionEvent event) {
final Locale currentLocale = SessionBean.getCurrentLocale();
final MessageManager messageManager = new MessageManager(currentLocale);
final Map<String, String> mapParameters = FacesContext.getCurrentInstance()
.getExternalContext().getRequestParameterMap();
final String linkType = mapParameters.get(Constants.ATTRIBUTE_LINK_TYPE);
if (linkType.equals(messageManager.getProperty(Constants.MESSAGE_MENU_VIEWING))) {
linkPage = Constants.PAGE_VIEW;
}
...
responseRendered = true;
}
}
Ok well command link doesn't have an attribute update, so that should have thrown an error here:
<h:commandLink value="View" update="workplace">
I'm assuming you want an ajax solution it would be:
<h:commandLink value="View">
<f:param name="link" value="Viewing telephone book"/>
<f:ajax render="workplace" listener="#{main.determineAction}" />
</h:commandLink>
I want to implement a filtering facility in a JSF web application as follows: The users can add as many filters as they want. They can also delete them. So I am having a dataTable of filters. Each row consists of one h:selectOneMenu which has an ajax “change” event in order to make a second h:selectOneMenu visible in the same row. The options of the second h:selectOneMenu are calculated dynamically according to the selected option of the first.
The problem is that the value of second h:selectOneMenu is never set to the back-end object even if I added an ajax event. However the value of the first h:selectOneMenu is set.
I have the following fragment of code in an .xhtml page:
<h:form id="filterForm">
<h:dataTable id="filterTable" value="#{filterManager.filters}" var="filter">
<h:column>
<h:outputLabel value="#{msgs.filterBy}:" for="availableFilters" />
<h:selectOneMenu id="availableFilters" value="#{filter.filter}">
<f:selectItems value="#{filterManager.getProperties(typeSelector.typeSelected)}" />
<f:ajax event="change" render=":filterForm" />
</h:selectOneMenu>
</h:column>
<h:column>
<h:panelGroup id="filterValuesPanel" >
<h:outputLabel value="#{msgs.value}:" for="filterValues" rendered="#{!filter.filterEmpty}" />
<h:selectOneMenu value="#{filter.value}" id="filterValues" rendered="#{!filter.filterEmpty}" >
<f:selectItems value="#{filterManager.getPossibleAnswers(filter)}" />
<f:ajax event="change" render=":filterForm" />
</h:selectOneMenu>
</h:panelGroup>
</h:column>
<h:column>
<h:commandButton value="#{msgs.delete}" title="#{msgs.deleteFilter}">
<f:ajax event="click" listener="#{filterManager.removeFilter(filter)}" render=":filterForm" />
</h:commandButton>
</h:column>
</h:dataTable>
<h:commandButton value="#{msgs.addNewFilter}">
<f:ajax event="click" listener="#{filterManager.addNewFilter}" render=":filterForm" />
</h:commandButton>
</h:form>
I have a bean called “FilterManager” which has a ViewScoped. Important parts are shown below:
#ManagedBean
#ViewScoped
public class FilterManager implements Serializable {
private List<Filter> filters; // it has a getter
private int currentFilterId;
public void addNewFilter(AjaxBehaviorEvent event) {
this.currentFilterId++;
this.filters.add(Filter.getEmptyFilter(this.currentFilterId));
}
public void removeFilter(Filter filter) {
this.filters.remove(filter);
}
...
}
The Filter class is a normal class (not a bean) and is shown below:
public class Filter implements Serializable {
private int id;
private String filter;
private String value;
public String getFilter() {
return filter;
}
public void setFilter(String theFilter) {
if (theFilter != null && !theFilter.isEmpty())
this.filter = theFilter;
}
public String getValue() {
return value;
}
public void setValue(String theValue) {
this.value = theValue;
}
public boolean isFilterEmpty() {
return this.filter == null || this.filter.isEmpty();
}
...
}
Notice that TypeSelector is a SessionScoped bean which has a typeSelected property along with getter and setter.
The problem is: filter.filter is set correctly whereas filter.value is never set. I can't find the problem so I need your help please. Apologies for all this code but I needed to provide you with all the necessary details.
Thanks in advance!
Okay guys that was my fault. I had a bug in FilterManager.getPossibleAnswers(Filter filter) method. Basically, at the end of the method, I was setting filter.value to the first element of List unconditionally. Eg instead of writing
if (filter.getValue() == null || filter.getValue().isEmpty()) {
SelectItem first = answers.get(0);
filter.setValue((String) first.getValue());
}
I just wrote:
SelectItem first = answers.get(0);
filter.setValue((String) first.getValue());
Although filter.value was updating as normal, the value was changing back to default (first element in list) during re-rendering of dataTable component.
I am failing to render data which is surely in a database. All my DAO methods working and tested. Perhaps it is not important but anyway: I am using Primefaces, Java ee 6, glassfish 3.1.
Here is error: /edit.xhtml #59,45 value="#{b.orderNum}": The class 'com.boatmanagement.domain.BoatOrder' does not have the property 'orderNum'.
My domain class.
#Entity
#Table(name="BOAT_ORDR_TB")
public class BoatOrder implements Serializable
{
#Id
#GeneratedValue
#Column(name="ORDER_PK")
private int orderId;
#Column(name="ORDER_NUM")
private String orderNum;
#Temporal(TemporalType.DATE)
#Column(name="ORDER_DATE")
private Date orderDate;
public int getBoatOrderId() {
return orderId;
}
public void setBoatOrderId(int orderId) {
this.orderId = orderId;
}
public String getBoatOrderNum() {
return orderNum;
}
public void setBoatOrderNum(String orderNum) {
this.orderNum = orderNum;
}
public Date getBoatOrderDate() {
return orderDate;
}
public void setBoatOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
}
Here is part of my JSF page.
<h:form class="displayTable">
<p:dataTable id="boatTable" autoUpdate="true"
var="b" value="#{filterbean.btOrderlist}">
<p:column headerText="res. num" width="50">
<h:outputText value="#{b.orderNum}" />
</p:column>
<p:column headerText="Date" width="50">
<h:outputText value="#{b.orderDate}" />
</p:column>
<p:column headerText="Yacht name" width="100">
<h:outputText value="" />
</p:column>
</p:dataTable>
</h:form>
</ui:define>
The presence of the property is basically determined by the presence of the public getter method which is named according the Javabeans specification. So the property of orderNum basically requires a public getter with the name getOrderNum() (and for input components also a public setter with the name of setOrderNum()).
You don't have them. You gave them different names. Fix the method names in the class, or the property name in EL.
As an aside, knowing this is 8 years old, I found an issue when dealing with Boolean/boolean values.
Assuming I have an object member "active", Eclipse creates a getter as isActive(), not getActive(). JBOSS/Tomcat seem to not recognize this getter. I have not tried this in Glassfish, but I'm posting it in case someone else finds this issue...