Issue
I have a form where a user can enter a delimited string of user names and this is then converted into entries in a selectOneListbox. I have a custom validator which checks the user names but this is only triggered for the highlighted entry. What I would like to be able to do if validate all the entries in the list whether or not they are selected. Is this possible?
Details
The view is simply
<p:inputText id="users" value="#{myBean.usersText}" />
<p:commandButton value="->" action="#{myBean.onAddUsers}" update="users,userList" process="users #this" />
<p:selectOneListbox id="userList">
<f:selectItems value="#{myBean.userList}" />
<f:validator validatorId="my.package.UserValidator" />
</p:selectOneListbox>
and the backing bean has
private String usersText;
private List<String> userList;
public void onAddusers() {
List<String usersToAdd = new ArrayList<>(Arrays.asList(usersText.split(";")));
for (String u : userToAdd) {
userList.add(u.trim());
}
users = null;
}
Related
I have a form that lets me edit a list of beans (one at a time), using buttons I can switch between the beans.
Keeping it simple :
public class MyBean {
private String text;
}
public class MyController {
private List<MyBean> availableBeans = new ArrayList<MyBean>(); // has five MyBeans with random text
private MyBean selectedBean; // initialized with first element of list
private int index = 0;
public void nextBean() { index++; }
public void previousBean() { index--; }
private void refreshBean() { selectedBean = availableBeans.get(index); }
}
For the html part I have something like
<h:form id="someForm">
<!-- stuff -->
<p:inputText value="#{myController.selectedBean.text}" />
<p:inplace editor="true" label="#{myController.selectedBean.text}" >
<p:inputText value="#{myController.selectedBean.text}" />
</p:inplace>
<!-- more stuff-->
</h:form>
If I change the text inside the inplace tag, the variable in myBean will be updated just fine, but If I only use inputText the bean will still have the old value, even if I change it on the webpage. Why is that?
Its because the p:inplace editor="true" implicitly submits the value to the server while <p:inputText does not do it implicitly,
You can solve it in several ways
1) add submit button like <p:commandButton to submit the value from p:inputText
2) use p:ajax event="keyup" or event="change",inside p:inputText
also take a look at the showcase p:ajax enables ajax features on supported components.
p.s , remove the value attribute from the p:inplace (there is no such attribute in p:inplace)
Lets give your components ids:
<h:form id="someForm">
<p:inputText id="first" value="#{myController.selectedBean.text}" />
<p:inplace id="second" editor="true" value="#{myController.selectedBean.text}">
<p:inputText id="third" value="#{myController.selectedBean.text}" />
</p:inplace>
</h:form>
According to the Primefaces Documentation 3.5 the component p:inplace has no attribute called value.
Do you submit the form someForm when changing the value of first? Otherwise the updated values from first won't be passed to MyController and MyBean. p:inplace submits the values automatically whereby you have to do it yourself it you use the standard p:inputText.
<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.
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
i have a CRUD generated create form:
<div class="create-form">
<h:form>
<h:inputText id="name" value="#{pointController.selected.name}" title="#{bundle.CreatePointTitle_name}" required="true" />
<h:inputText id="term" value="#{pointController.selected.term}" title="#{bundle.CreatePointTitle_term}" required="true" />
<p:commandButton styleClass="btn" action="#{pointController.create}" value="#{bundle.CreatePointSaveLink}" />
</h:form>
</div>
<button>add new form</button>
i have a button that if clicked it will create another form same as above using javascript. (2 inputText, name and term)
my goal is, with 2 or more forms, depending how many forms the user wants, with 1 commandButton that is clicked it will insert everything in the database.
example:
first form: name = first form test, term = first form testterm
2nd form: name = 2nd form test, term= 2nd form testterm
after clicking the command button
2 rows will be inserted in the same table in the database.
but i'm not sure what would be the structure for page for this.
You can't send data from many forms in a single request using JSF components, you should serialize all the data and send it manually. It would be better to have a List<Item> and every time you click in the button it will create a new item on the list and update an UIContainer that will display the items of the list.
This would be a start example of the above:
#ManagedBean
#ViewScoped
public class ItemBean {
private List<Item> lstItem;
public ItemBean() {
lstItem = new ArrayList<Item>();
addItem();
}
//getters and setter...
public void addItem() {
lstItem.add(new Item());
}
public void saveData() {
//you can inject the service as an EJB or however you think would be better...
ItemService itemService = new ItemService();
itemService.save(lstItem);
}
}
JSF code (<h:body> content only):
<h:form id="frmItems">
<h:panelGrid id="pnlItems">
<ui:repeat value="#{itemBean.lstItem}" var="item">
Enter item name
<h:inputText value="#{item.name}" />
<br />
Enter item description
<h:inputText value="#{item.description}" />
<br />
<br />
</ui:repeat>
</h:panelGrid>
<p:commandButton value="Add new item" action="#{itemBean.addItem}"
update="pnlItems" />
<p:commandButton value="Save data" action="#{itemBean.saveData}" />
</h:form>
I am currently running my web application in JSF 2.0, It also is using Primefaces 2.2RC2.
I know that primefaces gives you the ability to have editable rows, but for my project I would prefer if a user clicks on a commandButton within the table that a dialog is displayed prepopulated with that particular rows values and the user can edit the row that way.
The only way I have gotten this to work is to in the column that contains the commandButton, pass that rows contents as params like the example below:
<p:dataTable var="car" value="#{myBean.cars}" id="carList">
<h:column>
<h:inputText value="#{car.id}" style="width:100%"/>
</h:column>
<h:column>
<h:inputText value="#{car.name}" style="width:100%"/>
</h:column>
<h:column>
<h:commandButton actionListener=#{myBean.updateRow} onsuccess="editCardDialog.show()" >
<f:param name="carId" value=#{car.id} />
<f:param name="carName" value=#{car.name} />
</h:commandButton>
</h:column>
...
</p:dataTable>
So my Question is this, currently the only way I have gotten this to work is to in my backing bean create dummy temp global variables to set the params to so when my dialog opens it can reference the values like this
//myBean.java
private String tempCarId;
private String tempCarName;
public void setTempCarId(String tempCarId) {
this.tempCarId = carId;
}
public String getTempCarId() {
return tempCarId;
}
public void setTempCarName(String tempCarName) {
this.tempCarName = carName;
}
public String getTempCarName() {
return tempCarName;
}
public void updateRow(ActionEvent event) {
String carId = FaceContext...getParameterMap("carId");
String carName = FacesContext...getParameterMap("carName");
setTempCarId(carId);
setTempCarName(carName);
}
Then in the dialog I will just reference those temp variables
<p:dialog>
<h:inputText value=#{myBean.tempCarId} />
<h:inputText value=#{myBean.tempCarName} />
</p:dialog>
I am not sure if this is the correct way of doing it. My gut is telling me its not because it seems extremely redundant to have to create temp variables in my Bean just so I can pass them to the dialog. Does anyone know of a better more concise way of doing this so I dont have to create a million temporary variables in my backing bean?
Just replace the outputTexts in dialog below with inputTexts;
http://www.primefaces.org/showcase/ui/datatableRowSelectionByColumn.jsf
or
http://www.primefaces.org/showcase/ui/datatableRowSelectionInstant.jsf