Get the value for multiple <p:rating> [duplicate] - jsf

I have a bean with a List<T>:
#Named
#ViewScoped
public class Bean {
private List<Item> items;
private String value;
#Inject
private ItemService itemService;
#PostConstruct
public void init() {
items = itemService.list();
}
public void submit() {
System.out.println("Submitted value: " + value);
}
public List<Item> getItems() {
return items;
}
}
And I'd like to edit the value property of every item:
<h:form>
<ui:repeat value="#{bean.items}" var="item">
<h:inputText value="#{bean.value}" />
</ui:repeat>
<h:commandButton action="#{bean.submit}" />
</h:form>
With this code the value doesn't contain all the submitted values, only the latest submitted value. I also tried <c:forEach> and <h:dataTable>, but it didn't made any difference.
What should I do for collecting all the submitted values?

Your problem is caused because you're basically collecting all submitted values into one and same bean property. You need to move the value property into the bean behind var="item".
<h:form>
<ui:repeat value="#{bean.items}" var="item">
<h:inputText value="#{item.value}" /> <!-- instead of #{bean.value} -->
</ui:repeat>
<h:commandButton action="#{bean.submit}" />
</h:form>
In the bean action method, simply iterate over items in order to get all submitted values via item.getValue().
public void submit() {
for (Item item : items) {
System.out.println("Submitted value: " + item.getValue());
}
}

Related

selectBooleanCheckbox is not set after remoteCommand

I have a remmoteCommand that updates a List, after the items are loaded a repeat render selectBooleanCheckbox. However, the values are not correctly set at the checkbox, all of them are unchecked beside there are some items with selected property (which is Boolean) set to true.
If I just set an Item in the backing bean after the list is loaded it works only for that Item. What could be the problem?
index.xhtml
<h:form>
<h:panelGroup id="itemsHolder">
<h:panelGrid rendered="#{backingBean.items != null}">
<h:selectBooleanCheckbox value="#{backingBean.item.selected}" disabled="#{backingBean.rendered}" /> #{backingBean.item.name}
<ui:repeat value="#{backingBean.items.toArray()}" var="option" >
<h:selectBooleanCheckbox value="#{option.selected}" disabled="#{backingBean.rendered}" />
#{option.name}
<br />
</ui:repeat>
</h:panelGrid>
</h:panelGroup>
<p:remoteCommand rendered="#{backingBean.rendered}"
name="initItems"
actionListener="#{backingBean.initItems()}"
process="#this"
update="itemsHolder"/>
</h:form>
<ui:fragment rendered="#{backingBean.rendered}">
<script>
$(document).ready(function () {
setTimeout(function () {
initItems();
}, 3000);
});
</script>
</ui:fragment>
BackingBean.java
#Component
#ManagedBean
#Scope("view")
public class BackingBean {
private boolean rendered = true;
private Set<Item> items;
private Item item;
public void initItems() {
items = new LinkedHashSet<>();
items.add(new Item("item 1", true, "1"));
items.add(new Item("item 2", false, "2"));
items.add(new Item("item 3", true, "3"));
item = new Item("lonely item", true, "4");
}
//Getters and setters
}
UPDATE:
I created a copy of the real code in a SandBox, I am still not able to reproduce, I think I will have to add more dependencies from real code.
I've recreated your case and it is working just fine with following simple managed bean
#ManagedBean(name = "bean")
#ViewScoped
public class YourBean implements Serializable {
List<YourItem> items=new ArrayList<>();
YourItem anItem=new YourItem();
#PostConstruct
public void init() {
System.out.println("Bean is created");
//initialize items
anItem.setSelected(false);
//add 5 items to list
for (int i=0;i<5;i++){
YourItem item=new YourItem();
item.setSelected(false);
items.add(item);
}
}
public void onUpdateItems(){
System.out.println("Items will be updated...");
anItem.setSelected(true);
//modify 1st and 3rd item
items.get(0).setSelected(true);
items.get(2).setSelected(true);
//remove 4th item
items.remove(3);
}
public List<YourItem> getItems() {
return items;
}
public void setItems(List<YourItem> items) {
this.items = items;
}
public YourItem getAnItem() {
return anItem;
}
public void setAnItem(YourItem anItem) {
this.anItem = anItem;
}
}
p:command should be implemented on following way
<h:form id="form">
<h:panelGroup id="itemHolder">
<h:panelGrid rendered="#{bean.items != null}">
<h:selectBooleanCheckbox value="#{bean.anItem.selected}" />
<ui:repeat value="#{bean.items}" var="item">
<h:selectBooleanCheckbox value="#{item.selected}" />
#{item.selected}
<br />
</ui:repeat>
</h:panelGrid>
</h:panelGroup>
<p:remoteCommand name="startUpdate"
actionListener="#{bean.onUpdateItems()}"
update=":form:itemHolder"/>
<p:commandButton value="Update items" onclick="startUpdate();"/>
</h:form>
Compare your code with this example. Very probably there is problem in your managed bean method for updating items List or with the way how you are updating h:panelGroup.

jsf datatable with selectbooleancheckbox

I have following code:
JSF PAGE
<h:dataTablevalue="#{bean.records}" var="app">
<h:column>
<h:selectBooleanCheckbox value="#{bean.checked[app.id]}"/>
<f:facet name="footer">
<h:commandButton value="submit" action="#{bean.submitPublic}"/>
</f:facet>
</h:column>
and BEAN code:
#SessionScoped
public class bean
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
private List<Application> checkedItems = new ArrayList<Application>();
public void submit() {
for (Application app : getRecords()) {
if (checked.get(app.getId())) {
checkedItems.add(app);
}
}
checked.clear();
//here logic for selected apps
}
public Map<Long, Boolean> getChecked() {
return checked;
}
public void setChecked(Map<Long, Boolean> checked) {
this.checked = checked;
}
problem is when I click button, selected values are not submitted.
I was reading this article:
How to use <h:selectBooleanCheckbox> in <h:dataTable> to select multiple rows?
did everything the same way, but it does not work.
Update the datatable when the Checkbox is selected.
<h:selectBooleanCheckbox value="#{bean.checked[app.id]}">
<f:ajax event="valueChange" render=":YOUR_FORM_ID:YOUR_TABLE_ID"/>
</h:selectBooleanCheckbox>

JSF h:selectOneMenu is never set even when using f:ajax

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.

How to get dynamically rendered <h:inputText> value in back end in JSF

I am able to render dynamic but don't know how to get those dynamically created values in back end.
test.xhtml
<h:form>
Insert Your Desire Number : <h:inputText value="#{bean.number}">
<f:ajax listener="#{bean.submitAjax}" execute="#form" render="#form" event="keyup" />
</h:inputText>
<br></br>
<h:outputText value="#{bean.text}" />
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:inputText value="#{item.value}" />
</h:column>
</h:dataTable>
<h:commandButton value="Submit" action="#{item.submit}" />
</h:form>
If I render 3 input boxes, and when I submit the button i get the last value only, Can someone guide me how can i
Bean.java
#ManagedBean(name="bean")
#SessionScoped
public class Bean {
private int number;
private List<Item> items;
private Item item;
//getter and setter are omitted
public void submitAjax(AjaxBehaviorEvent event)
{
items = new ArrayList<Item>();
for (int i = 0; i < number; i++) {
items.add(new Item());
}
}
}
Item.java
private String value;
//getter and setter are omitted
public void submit() {
System.out.println("Form Value : "+value);
}
Your submit() method is in the wrong place. You should put it on the managed bean, not on the entity.
Thus so,
<h:commandButton value="Submit" action="#{bean.submit}" />
with
public void submit() {
for (Item item : items) {
System.out.println(item.getValue());
}
}
or more formally,
#EJB
private ItemService service;
public void submit() {
service.save(items);
}

How to collect submitted values of a List<T> in JSF?

I have a bean with a List<T>:
#Named
#ViewScoped
public class Bean {
private List<Item> items;
private String value;
#Inject
private ItemService itemService;
#PostConstruct
public void init() {
items = itemService.list();
}
public void submit() {
System.out.println("Submitted value: " + value);
}
public List<Item> getItems() {
return items;
}
}
And I'd like to edit the value property of every item:
<h:form>
<ui:repeat value="#{bean.items}" var="item">
<h:inputText value="#{bean.value}" />
</ui:repeat>
<h:commandButton action="#{bean.submit}" />
</h:form>
With this code the value doesn't contain all the submitted values, only the latest submitted value. I also tried <c:forEach> and <h:dataTable>, but it didn't made any difference.
What should I do for collecting all the submitted values?
Your problem is caused because you're basically collecting all submitted values into one and same bean property. You need to move the value property into the bean behind var="item".
<h:form>
<ui:repeat value="#{bean.items}" var="item">
<h:inputText value="#{item.value}" /> <!-- instead of #{bean.value} -->
</ui:repeat>
<h:commandButton action="#{bean.submit}" />
</h:form>
In the bean action method, simply iterate over items in order to get all submitted values via item.getValue().
public void submit() {
for (Item item : items) {
System.out.println("Submitted value: " + item.getValue());
}
}

Resources