Simple setting from form input to object attribute - jsf

<h:inputText value="#{myController.myString}" id="stg" />
<h:inputText value="#{myController.document.title}" id="title" />
<h:inputTextarea value="#{myController.document.subtitle}" id="subtitle" />
I can recover myString correctly, but document is always null. It has a default constructor. If I do a Document document = new Document() in myController then it is not null but title and subtitle are. Am I missing something?
EDIT
I thought my problem might not need additional information, but here it is:
.xhtml
<h:form id="ExampleForm" styleClass="myClass">
<h:inputText value="#{myController.myString}" id="stg" />
<h:inputText value="#{myController.document.title}" id="title" />
<h:inputTextarea value="#{myController.document.subtitle}" id="subtitle" />
<h:commandButton action="#{myController.readData()}" type="submit" value="Read"/>
</h:form>
Then I complete all the inputs in the form and click the button...
Controller
#Named(value = "myController")
#ViewScoped
public class MyController implements Serializable {
private String myString;
private Document document;
// getters and setters
public void readData() {
System.out.println("String: " + myString); // prints well
System.out.println("Doc: " + document); // prints null
// System.out.println("Doc title: " + document.getTitle()); // prints null when I declare private Document document = new Document();
}
}
Document is a Serializable simple bean with String title and subtitle and the respective getters/setters.
EDIT
The problem seems to be solved thanks to BalusC pointer.
There have been different things that mixed up and made my code work incorrectly. First, I solve the problem with:
#PostConstruct
public void init() {
document = new Document();
}
#PreDestroy
public void cleanup() {
document = null;
}
Another mistake I had while researching the issue (and that's why some other things created errors) was I didn't specify title and subtitle in the execute:
<h:commandButton action="#{myController.readData()}" type="submit" value="Read">
<f:ajax execute="#this title subtitle" />
</h:commandButton>

Related

Added String to ArrayList not shown / not updated [duplicate]

This question already has answers here:
How to send form input values and invoke a method in JSF bean
(1 answer)
Pass an input value directly as action method argument
(1 answer)
Using <ui:repeat><h:inputText> on a List<String> doesn't update model values
(1 answer)
Closed 5 years ago.
...So i've got my #ApplicationScoped Bean "Application"..:
#ManagedBean(name = "Application")
#ApplicationScoped
public class Application implements Serializable {
private boolean isRunning = false;
private ArrayList<Feed> sentNotifications = new ArrayList<>();
private ArrayList<String> emails = new ArrayList<>(
Arrays.asList("f00#b4r.com", "test#test.com")
);
private LinkedList<String> words = new LinkedList<>(
Arrays.asList("vuln","banana","pizza","bonanza")
);
private LinkedList<String> feeds = new LinkedList<>(
Arrays.asList("http://www.kb.cert.org/vulfeed",
"https://ics-cert.us-cert.gov/advisories/advisories.xml",
"https://ics-cert.us-cert.gov/alerts/alerts.xml")
);
...and want to add a String to ArrayList<String> emails using the method:
public String addEmail(String email) {
emails.add(email);
return null;
}
The Facelet goes as follows:
<!-- EMAILS -->
<h3>Configured Emails</h3>
<h:form>
<h:inputText value="Email" var="email"/>
<h:commandButton value="Add Email" action="#{Application.addEmail(email)}"/>
</h:form>
<h:form>
<ui:repeat var="email" value="#{Application.emails}">
<tr>
<td>#{email}</td>
<td>
<f:facet name="header">Action</f:facet>
<h:commandLink value="Delete" action="#{Application.rmEmail(email)}"/>
</td>
</tr>
<br></br>
</ui:repeat>
</h:form>
...so when i try to add "blabla#bla.com", this is the Result:
There is a delete-button shown, but not the String itself?!
Is the String correctly added - and JSF doesnt rerender the view..?
..Or is the String not added correctly?
please help!
thanks.
I fixed it, finally!
Thanks to User #Kukeltje, who hinted me at basic things that i got wrong - and User #Wietlol who motivated me in the chat through moral support and 'believes in me' :)
The solution:
..in Application.java:
public List<Feed> sentNotifications = new ArrayList<>();
public List<String> emails = new ArrayList<>();
public List<String> words = new LinkedList<>(Arrays.asList("vuln", "banana", "pizza", "bonanza"));
public List<String> feeds = new LinkedList<>(
Arrays.asList("http://www.kb.cert.org/vulfeed",
"https://ics-cert.us-cert.gov/advisories/advisories.xml",
"https://ics-cert.us-cert.gov/alerts/alerts.xml")
);
private String currentEmail;
private String currentFeed;
private String currentWord;
[...]
public void addEmail() {
emails.add(currentEmail);
}
..and gui.xhmtl:
<!-- EMAILS -->
<h3>Configured Emails</h3>
<h:form>
<h:inputText value="#{Application.currentEmail}" var="email"/>
<h:commandButton value="Add Email" action="#{Application.addEmail}"/>
</h:form>
<h:form>
<ui:repeat var="email" value="#{Application.emails}">
<tr>
<td>#{email}</td>
<td>
<f:facet name="header">Action</f:facet>
<h:commandLink value="Delete" action="#{Application.rmEmail(email)}"/>
</td>
</tr>
<br></br>
</ui:repeat>
</h:form>
Notice how action="#{Application.addEmail}" does not make use of arguments- rather the parameter is handed to the method via value="#{Application.currentEmail}".
If you, reader, have the same problem please consider these points:
getter/setter for each Field in the bean
primitive fields!
argument-less methods to 'delegate' the primitive Fields, e.g. my addEmail method
Hope this answer is usefull to ppl having the same issue!
Greetings,
Gewure

Sending JSF textbox value to a managed bean function as a parameter [duplicate]

This question already has an answer here:
How to send form input values and invoke a method in JSF bean
(1 answer)
Closed 7 years ago.
I have two textboxes and one submit button in my login.xhtml page. I also have a bean. Here are the codes:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Welcome to Online Banking</title>
</h:head>
<h:body>
<h:outputText value="Online Banking System Login" ></h:outputText>
<h:form>
<h:panelGrid columns="2" border="1">
<h:outputText value="Username:"></h:outputText>
<h:inputText id="username" value="#{loginBean.username}"></h:inputText>
<h:outputText value="Password"></h:outputText>
<h:inputSecret id="password" value="#{loginBean.password}" > </h:inputSecret>
<h:commandButton value="Login" action="#{loginBean.loginCheck(username, password)}"></h:commandButton>
</h:panelGrid>
</h:form>
</h:body>
</html>
And the beans file:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package beans;
import javax.inject.Named;
import javax.enterprise.context.Dependent;
/**
*
* #author SUUSER
*/
#Named(value = "loginBean")
#Dependent
public class LoginBean {
/**
* Creates a new instance of LoginBean
*/
public LoginBean() {
}
private static String username="", password="";
public String getUsername(){
return username;
}
public String getPassword(){
return password;
}
public void setUsername(String Username){
username=Username;
}
public void setPassword(String Password){
password=Password;
}
public void loginCheck(String username, String password){
}
}
I will do the database check in my loginCheck function, so i need to pass the values of those two textboxes as a parameter. But i do not know how to do this. I just tried the code but it just passes empty strings as parameteres. Can anyone help me with this?
Thanks
Actually, you do not need to pass username and password parameters to a action method in your case.
A JSF page has a request life cycle. If you look inside JSF request life cycles, you will notice that values is applied to managed bean before the action.
Therefore, loginBean.username and loginBean.password values are set to managed bean username and password fields before the action. You can access them in the action method.
Your action will be
<h:commandButton value="Login" action="#{loginBean.loginCheck}"></h:commandButton>
and the action method
public String loginCheck(){
// search username and password in database.
// username, password field are set to values on page and accessible in the action method.
// Do not forget to navigate a proper page after according to login attempt.
}
For further reading
Communication in JSF 2.0 tutorial by BalusC
Basic Login Mechanism using Filters
JSF Request Life Cycle
How to pass value from textbox to Bean
1- create a .xhtml file
<h:form id="frm">
<h:inputText id="t1" value="#{user.x}" />
<h:commandButton action="#{user.check}" value="ok"/>
<h:outputText value="Value is #{user.msg}" ></h:outputText>
</h:form>
2- create a bean
ManagedBean(name="user")
RequestScoped
public class UserNumber {
int x;
String msg;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void check()
{
if(x%2==0)
{
msg= "Even";
}
else
{
msg= "Odd";
}
}
public UserNumber() {
}
}
JSF automatically binds textbox values to variables in backing bean.
So you don't need to pass values to backing bean in calling function. You can just put like this
<h:commandButton value="Login" action="#{loginBean.loginCheck}"></h:commandButton>
And in bean you can use those as regular variable. I also suggest not to use static variables to store backing bean data.
public String loginCheck(){if(username == <fromDB> && password == <fromDB>) return "loginsuccess"; else return "loginfailure"; }
Hope this helps.
Well, from what I understand, do you that check in your loginCheck function the values of those textboxes. Automatically the JSF set the values of parameters to the variables, so you can work with them by gets(). For example is the following:
<h:form>
<h:panelGrid columns="2" border="1">
<h:outputText value="Username:"></h:outputText>
<h:inputText id="username" value="#{loginBean.username}"></h:inputText>
<h:outputText value="Password"></h:outputText>
<h:inputSecret id="password" value="#{loginBean.password}" > </h:inputSecret>
<h:commandButton value="Login" action="#{loginBean.loginCheck()}"></h:commandButton>
</h:panelGrid>
</h:form>
end in his ManagedBean is the following:
#ManagedBean(name= "loginBean")
public class LoginBean {
public LoginBean() {
}
// gets and sets
public void loginCheck(){
if(getUsername() != null && getPassword() != null){
// and here you chek database parameters
}
}
}

Adding values from multiple inputs to the arraylist

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

How do I display a list of strings in JSF which also needs to be editable?

I have a backing bean which has a property called List cites where Cite has a string property called "value" .. In the init method I am fetching the values stored as a comma separated string, splitting them into individual strings constructing a list and displaying the list of cites. But I also want to give the users ability to add more cites on top of existing ones/edit existing cite content. How can I do that ? The code below is the jsf in xhtml but it doesn't work for me ..
<div style="margin-top: 10px; padding: 3px 3px;">
<fieldset>
<legend>Cites Affected</legend>
<h:dataTable value="#{dataEntry.cites}" var="citeAffected">
<h:column>
<f:facet name="header" >
<h:outputText value="Cite"/>
</f:facet>
<h:inputText value="#{citeAffected.value}"/>
</h:column>
</h:dataTable>
<h:commandButton value="Add cite" process="#this" action="#{dataEntry.addCite}"/>
</fieldset>
</div>
In the backing bean .. this is what I have
DataEntry
{
private List<CiteAffected> cites = new ArrayList<CiteAffected>();
public void addCite()
{
cites.add(new CiteAffected());
}
public void editMetadata()
{
//update the db object
}
private void init()
{
// get the value from database as a comma separated string
for(String citeAffected : Arrays.asList(sourceManualLoadProperties.getCitesAffected().split(",")))
{
CiteAffected cite = new CiteAffected();
cite.setValue(citeAffected);
this.cites.add(cite);
} }
}
The error I am getting is .. As soon as I click on the command button "add cite" all the existing values disappear when I want it to simply add another text box but display the existing values as well ..
public class CiteAffected
{
private String value;
/**
*
* #return the cite affected
*/
public String getValue()
{
return value;
}
/**
*
* #param value the cite affected
*/
public void setValue(final String value)
{
this.value = value;
}
}
Just remove the process="#this" from <h:commandButton> and have your managed bean in #ViewScoped at least.
JSF code:
<h:form>
<h:dataTable id="dtCites" value="#{dataEntry.cites}" var="citeAffected">
<!-- content... -->
</h:dataTable>
<h:commandButton value="Add cite" action="#{dataEntry.addCite}">
<f:ajax render="dtCites" />
</h:commandButton>
</h:form>
Managed bean:
#ManagedBean
#ViewScoped
public class DataEntry {
//...
}

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