Adding values from multiple inputs to the arraylist - jsf

I' have a simple problem with adding values from inputs to the ArrayList.
I have a POJO like this:
public class Person {
private String firstName;
private String lastName;
private List<String> friends=new ArrayList<>();
//getters and setters
then Backing bean:
public class backingBean{
Person p=new Person();
public void addPerson(){
for(String friend:p.getFriends)
System.out.println(friend);
}
}
and the view
<h:form>
<fieldset>
<h:panelGrid columns="2">
<h:outputText value="Name" />
<h:inputText value="{backingBean.person.firstName}"/>
<h:outputText value="LastName" />
<h:inputText value="#{backingBean.person.lastName}"/>
<h:outputText value="Friends" />
<h:inputText value="#{backingBean.person.friends}" />
<h:inputText value="#{backingBean.person.friends}" />
</h:panelGrid>
<h:commandButton value="Add"
action="#{backingBean.addPerson}" />
</fieldset>
</h:form>
When I try to addPerson I get this error:
summary=(Conversion Error setting value...
I don't understand why convert String to String?

You can't bind value of h:inputText to ArrayList (without converter). When you submit form (by clicking button) JSF tries to call setFriends(String) and this is where this Exception occurs. Try to figure out what you are trying to achieve with these two h:inputText elements.

if you want to add 2 friends, just create only 2 different variables in backing bean as :
private String friend1;
private String friend2;
and then add them in addPerson like this:
List<String> friends=new ArrayList<String>();
friends.add(friend1);
friends.add(friend2);
p.setFriends(friends);
Not tested can be some bugs.
EDIT:
And if this not satisfies you, you can look at this #BalusC ANSWER

Related

Submitting ID of object-populated h:selectOneMenu still causes conversion error

I populated my selectOneMenu with objects and trying to send the id (in itemValue) back to my bean from the selected item, I tried it using the below functionality but I keep getting error about a null converter (Which I'm trying to avoid by sending the id to my bean).
xhtml:
<h:form>
<h:selectOneMenu value="#{bean.id}">
<f:selectItems value="#{bean.objectList}" var="f" itemValue="#{f.id}" itemLabel="#{f.name}" />
</h:selectOneMenu>
<h:commandButton action="#{bean.function}" value="OK"/>
</h:form>
bean:
private Collection<Object> objectList; //Object is an example, It is not the real class that is used
private int id;
public void function() {
// place where id is needed.
}
// id getters & setters
The collection you are using:
private Collection<Object> objectList;
Has a plain object as the class type for its elements.
You need to change it to:
private Collection<MyCustomClassElement> objectList;
Where MyCustomClassElement is the class for your collection elements used in the select.
I think the value is not updated, use ajax to update the value once you select it...
<h:form id="forms">
<h:selectOneMenu id="beanid" value="#{bean.id}">
<f:selectItems value="#{bean.objectList}" var="f" itemValue="#{f.id}" itemLabel="#{f.name}" />
<f:ajax event="change" render="forms" />
</h:selectOneMenu>
<h:commandButton action="#{bean.function}" value="OK"/>
</h:form>

values not getting passed from datatable to dialog box

<p:column>
<p:commandButton id="selectButton" update="#(form)" oncomplete="userDialog.show()" icon="ui-icon-search" title="View">
<f:setPropertyActionListener value="#{book}" target="#{CreateBookBean.selectedUser}" />
</p:commandButton>
</p:column>
</p:dataTable>
</p:outputPanel>
<p:dialog header="User Detail" modal="true" widgetVar="userDialog" width="200" height="175">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="fname" value="First Name: " />
<h:outputText id="fname" value="#{CreateBookBean.selectedUser.fname}" />
<h:outputLabel for="lname" value="Last Name: " />
<h:outputText id="lname" value="#{CreateBookBean.selectedUser.lname}" />
<h:outputLabel for="mobileno" value="mobile no: " />
<h:outputText id="mobileno" value="#{CreateBookBean.selectedUser.mobileno}" />
</h:panelGrid>
</p:dialog>
i came across this example recently.
the datatable is properly getting updated with the values i enter. but when i want to display it in the dialog box its not displaying anything.
and i actually don understand why value="#{CreateBookBean.selectedUser.fname}" is used instead of value="#{CreateBookBean.fname}".
here is my java code
public class CreateBookBean {
private Book book = new Book();
private List<Book> books = new ArrayList<Book>();
private Book selectedUser;
public String reinit() {
book = new Book();
return null;
}
setters and getters are included here
}
Lets split this question in two parts.
First:
When you want to display updated values (e.g. with a h:outputText), you need to update this element. Updating this element means, it will fetch the current value of it's backing bean.
Do it like this:
<p:commandButton ... update="idToUpdate1, idToUpdate2, ..." >
In order to get the idToUpdate check Naming Container in JSF2/PrimeFaces.
If you have many components which need an update, I would recomment grouping them into one NamingContainer (e.g. p:outputPanel). So you only have to update the NamingContainer, and not every single component.
Second:
#CreateBookBean.selectUser.fname means: "Fetch the CreateBookBean, fetch it's property selectUser and fetch the property of selectUser called fname".
In this case you would have these class layouts:
public class CreateBookBean {
private Book selectedUser;
....
public Book getSelectedUser() {
return this.selectedUser;
}
}
public class Book {
private String fname;
....
public String getFname() {
this.fname;
}
}
#CreateBookBean.fname means: "Fetch the CreateBookBean, fetch it's property fname".
In this case you would have this class layout:
public class CreateBookBean {
private String fname;
....
public String getFname() {
return this.fname;
}
}
According to this code you posted, i guess that the CreateBookBean has a property called selectedUser (the code reveals it: target="#{CreateBookBean.selectedUser}"), and the selectUser has a property fname.
Use the Update attribute in the button your using to display the dialog box, for example, <p:commandButton update="dialogBoxId" . . ./> in order to display the items from your datatable.

JSF does not convert InputText value to string variable of backing bean without custom converter

I try learn JSF and faced with problem.
I did use Servlet 2.5, JDK 1.6 and JSF 2.0.6 (com.sun.faces version from pom file).
I have a simple JSF page that has a <h:inputText/> tag for interaction with user
I expect what user fill this h:inputText then click on h:commandButton and on server side i will get backing bean with updated value.
But in my case lifecycle of JSF breaks on process validations, move to render
response and show to user "Parser error!" message
I.e. for simple h:inputText without any validator and converter i receive error message from server side about parsing of h:inputText value.
After some time i figured out what i can create my own converter which will not modify object, just pass String through himself.
I did add my realization of converter to <h:inputText/> and this work.
Question:
In all examples in books and other tutorials nobody used custom converter for <h:inputText/> if inputText is representation of String value of backing bean.
Why all of this tutorials and examples not working for me without custom converter? Where my mistake?
Source codes:
index.xhtml without converter, not worked for me:
<h:form id="UserForm">
<h:outputText value="Insert your first name:" />
<h:inputText id="userNameID" required="true" value="#{userBean.firstName}">
<f:validateLength minimum="5" maximum="25" />
</h:inputText>
<h:message showSummary="true" showDetail="false" for="userNameID" />
<h:commandButton id="submit" action="/view/validator/response?faces-redirect=true"
value="Submit" />
</h:form>
UserBean.java:
#ManagedBean(name = "userBean")
#SessionScoped
public class UserBean implements Serializable {
private String firstName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
MyConverter.java - dummy converter
#FacesConverter(value = "myConverter")
public class MyConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return value;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return value.toString();
}
}
index.xhtml with converter, worked as expected:
<h:form id="UserForm">
<h:outputText value="Insert your first name:" />
<h:inputText id="userNameID" required="true" value="#{userBean.firstName}" converter="myConverter">
<f:validateLength minimum="5" maximum="25" />
</h:inputText>
<h:message showSummary="true" showDetail="false" for="userNameID" />
<h:commandButton id="submit" action="/view/validator/response?faces-redirect=true"
value="Submit" />
</h:form>
The cause of the problem is not visible in the code posted so far, but the key symptom "it fails with a message coming from a so far unidentified converter while it succeeds with an explicit converter" suggests that you've elsewhere in the same project a #FacesConverter(forClass=String.class) which would run automatically on every single String property which doesn't have another converter explicitly specified.

how to parse the value to integer in <ui:repeat value="..." var="...">?

I have a code like this:
<ui:repeat value="#{myController.fileList}}" var="element" >
<t:inputFileUpload value="#{myController.uploadedFile[element]}" />
</ui:repeat>
but this returns an error : java.lang.NumberFormatException: For input string: "[0]}". UploadedFile is an array of Files. When i wrote code like this
...
<t:inputFileUpload value="#{myController.uploadedFile[0]}" />
...
everything is ok, but i want to have there values between 0-8, not only '0', and this has to be returned from my controller. So how to convert this 'element' to int value inside <t:inputFileUpload value="#{myController.uploadedFile[element]}" />? Thanks for help.
You can use the varStatus attribute to obtain the loop status.
<ui:repeat value="#{myController.fileList}" var="element" varStatus="loop">
<t:inputFileUpload value="#{myController.uploadedFile[loop.index]}" />
</ui:repeat>
(only available in JSF 2.x by the way, in JSF 1.x your best bet might be c:forEach)
But why don't you just use the following?
<ui:repeat value="#{myController.uploadedFile}" var="uploadedFile">
<t:inputFileUpload value="#{uploadedFile}" />
</ui:repeat>
Update: the fileList must be of type List<Integer> or Integer[] or int[] and the uploadedFile must be of type List<SomeObject> or SomeObject[] to get your initial code to work.
Update 2: here's a small reproducible test snippet:
XHTML:
<h:form>
<h:selectManyCheckbox value="#{bean.selectedIndexes}">
<f:selectItems value="#{bean.selectIndexes}" />
</h:selectManyCheckbox>
<h:commandButton value="submit" />
</h:form>
<ui:repeat value="#{bean.selectedIndexes}" var="selectedIndex">
<p><h:outputText value="#{bean.list[selectedIndex]}" /></p>
</ui:repeat>
Bean:
private List<SelectItem> selectIndexes; // +getter
private List<Integer> selectedIndexes; // +getter +setter
private List<String> list; // +getter
public Bean() {
selectIndexes = new ArrayList<SelectItem>();
selectIndexes.add(new SelectItem(0, "one"));
selectIndexes.add(new SelectItem(1, "two"));
selectIndexes.add(new SelectItem(2, "three"));
selectIndexes.add(new SelectItem(3, "four"));
selectedIndexes = new ArrayList<Integer>();
list = Arrays.asList("one", "two", "three", "four");
}
Works fine here on Mojarra 2.0.3 and Apache Tomcat 6.0.29. You only need to substitute selectedIndexes as fileList and list as uploadedFile.

h:inputText inside a4j:repeat

I have a List of strings in my object, and I was hoping to be able to edit them with an a4j:repeat.
Below is my code:
<a4j:repeat value="#{Controller.object.stringList}" var="item" >
<h:panelGrid columns="2">
<h:outputLabel value="ID:" />
<h:inputText value="#{item}" />
</h:panelGrid>
</a4j:repeat>
My problem is that the values of the items never get changed when I submit my form. I've had a look at the livedemo but even after adding the UpdateBean, it still didn't work.
Any ideas?
The objects in your repeat need to follow the bean standard if you want to write back to them. I'm guessing that they are just Strings in your example?
Try this:
public class StringBean {
private String value;
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
along with:
<h:inputText value=#{item.value} />

Resources