JSF2 Managed Bean variable initialization - jsf-2

I'm having some problems with bean initialization. I have an "edit" form to update
some user data. The user is previously created in the database and
I retrieve successfuly the data and put it in the form.
This is the form with id parameter 1 (/cms/admin/users/edit.jsf?id=1):
<h:panelGrid styleClass="general-form" columns="3" id="ajaxForm">
<h:outputLabel for="name" value="#{cms['users.add.name']}" />
<p:inputText required="true" id="name"
value="#{editUserController.user.name}"
label="#{cms['users.add.name']}">
<f:validateLength minimum="3" />
</p:inputText>
<p:message for="name" />
<h:outputLabel value="#{cms['users.add.lastname']}" />
<p:inputText id="lastname" label="#{cms['users.add.lastname']}"
required="true" value="#{editUserController.user.lastname}">
<f:validateLength minimum="3" />
</p:inputText>
<p:message for="lastname" />
<h:outputLabel value="#{cms['users.add.username']}" />
<p:inputText id="username" required="true"
label="#{cms['users.add.username']}"
value="#{editUserController.user.username}">
<f:validateLength minimum="3" />
</p:inputText>
<p:message for="username" />
<h:outputLabel value="#{cms['users.add.password']}" />
<p:password id="password" required="true"
value="#{editUserController.user.password}"
promptLabel="#{cms['users.error.enterPassword']}"
weakLabel="#{cms['users.error.weakPassword']}"
goodLabel="#{cms['users.error.goodPassword']}"
strongLabel="#{cms['users.error.strongPassword']}"
binding="#{password}" label="#{cms['users.add.password']}">
<f:validateLength minimum="6" />
</p:password>
<p:message for="password" />
<h:outputLabel value="#{cms['users.add.confirmPassword']}" />
<p:password id="passwordConfirm" required="true"
value="#{editUserController.confirmPassword}"
promptLabel="#{cms['users.error.enterPassword']}"
weakLabel="#{cms['users.error.weakPassword']}"
goodLabel="#{cms['users.error.goodPassword']}"
strongLabel="#{cms['users.error.strongPassword']}"
label="#{cms['users.add.confirmPassword']}">
<f:validateLength minimum="6" />
<f:validator validatorId="passwordValidator" />
<f:attribute name="password" value="#{password.value}" />
</p:password>
<p:message for="passwordConfirm" />
<h:outputLabel value="#{cms['users.add.active']}" />
<h:selectOneMenu value="#{editUserController.user.active}">
<f:selectItem itemValue="true" itemLabel="Sí" />
<f:selectItem itemValue="false" itemLabel="No" />
</h:selectOneMenu>
<h:outputText value="" />
<h:outputLabel value="#{cms['users.add.role']}" />
<h:selectOneMenu value="#{editUserController.securityRole}">
<f:selectItems value="#{editUserController.securityRoles}" />
</h:selectOneMenu>
<h:outputText value="" />
<h:outputText value="" />
<p:commandButton action="#{editUserController.saveUser}"
style="margin-top:20px;" ajax="false"
value="#{cms['general.save']}"></p:commandButton>
This is the Managed Bean (EditUserController.java):
public class EditUserController extends GeneralController implements
Serializable {
private static final long serialVersionUID = 1L;
#ManagedProperty("#{param.id}")
private Integer id;
private UserService userService;
private SecurityRoleService securityRoleService;
private User user;
private String confirmPassword;
private Map<String, SecurityRole> securityRoles;
private String securityRole;
#PostConstruct
public String checkUser() {
try {
FacesContext facesContext = FacesContext.getCurrentInstance();
this.id = Integer.parseInt(facesContext.getExternalContext().getRequestParameterMap().get("id"));
setUser(userService.findById(id));
Map<String, SecurityRole> secRoles = new ListUtils<String>().toMap(
securityRoleService.findAll(0, 30, "", ""), "name");
setSecurityRoles(secRoles);
setSecurityRole(user.getSecurityRole().getId().toString());
return "edit";
} catch (EntityNotFoundException e) {
return FATAL;
} catch (NoSuchMethodException e) {
return FATAL;
} catch (InvocationTargetException e) {
return FATAL;
} catch (IllegalAccessException e) {
return FATAL;
}
}
public String saveUser() {
try {
System.out.println("User saved!!");
return SUCCESS;
} catch (Exception e) {
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(MessageProvider.getMessageProvider()
.getValue("cms", "general.error")));
return ERROR;
}
}
//getters and setters ...
With the #Postconstruct method I initialize the user variable according to the id param.
Then the form is displayed correctly with all data prefilled. But when I click in the
commandButton I get an exception:
Error creating bean with name 'editUserController': Invocation of init method failed; nested exception is java.lang.NumberFormatException: null
I understand where is the error. In the #Postconstruct method the variable id has not
been "initialized" because there is not any id parameter in the request. I know I can solve this
scoping the bean to session or application, but it does not make any sense to have the bean there
just to perform this simple action.
How can I do this simple form? I just want to get an id parameter, show a form with prefilled data
then give the posibility to change the data an finally submit the form to save the new values
into the DB
Thank you all

If putting the bean in the view scope and using <f:viewParam> is not an option, then you'd need to pass the parameter back to the next request by including it as <f:param> in the UICommand component:
<p:commandButton action="#{editUserController.saveUser}"
style="margin-top:20px;" ajax="false"
value="#{cms['general.save']}">
<f:param name="id" value="#{editUserController.id}" />
</p:commandButton>
See also:
ViewParam vs #ManagedProperty(value = "#{param.id}")
Communication in JSF 2.0 - Processing GET request parameters

Related

Primefaces command button does not update datatable

I have primefaces command button multiple update problem. Command button is inside a form and datatable is not.
I have tried:
update=":datalist1,form1"
update=":datalist1 form1"
update="datalist1 form1"
update=":#{p:component('datalist1')},form1"
form1 updates every time but still dattable does not update
Version info:
primefaces: 5.3
jsf: org.glassfish 2.3.0-m04
spring: 4.2.3
and I use cdi for controller beans
Page:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<body>
<h:form id="form1" >
<h:panelGrid columns="3">
<h:outputLabel value="Name: " for="name" />
<p:inputText id="name" value="#{personelController.personel.adi}" required="true" requiredMessage="Name can not be null" />
<p:message id="nameMsg" for="name" />
<h:outputLabel value="Surname: " for="surname" />
<p:inputText id="surname" value="#{personelController.personel.soyadi}" required="true" requiredMessage="Surname can not be null" />
<p:message id="surnameMsg" for="surname" />
<h:outputLabel value="Age: " for="age" />
<p:inputText id="age" value="#{personelController.personel.yasi}" required="true" requiredMessage="Age can not be null" />
<p:message id="ageMsg" for="age" />
<h:outputLabel value="Job: " for="job" />
<p:inputText id="job" value="#{personelController.personel.meslek}" required="true" requiredMessage="Job can not be null" />
<p:message id="jobMsg" for="job" />
<h:outputLabel value="City" for="city" />
<p:inputText id="city" value="#{personelController.personel.sehir}" required="true" requiredMessage="City can not be null" />
<p:message id="cityMsg" for="city" />
<p:commandButton id="add" value="Add" actionListener="#{personelController.createPersonel()}" update=":datalist1,form1" />
</h:panelGrid>
</h:form>
<p:dataTable id="datalist1" var="person" value="#{personelController.personels}" resizableColumns="true">
<f:facet name="header">List of Personel</f:facet>
<p:column headerText="ID">
<h:outputText value="#{person.id}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{person.adi}" />
</p:column>
<p:column headerText="Surname">
<h:outputText value="#{person.soyadi}" />
</p:column>
<p:column headerText="Age">
<h:outputText value="#{person.yasi}" />
</p:column>
<p:column headerText="Job">
<h:outputText value="#{person.meslek}" />
</p:column>
<p:column headerText="City">
<h:outputText value="#{person.sehir}" />
</p:column>
</p:dataTable>
</body>
</html>
Class:
#Named
#SpringViewScoped
public class PersonelController implements Serializable{
private static final long serialVersionUID = 1L;
#Inject
private PersonelService personelService;
private List<Personel> personels;
private List<Personel> selectedPersonel;
private Personel personel;
#PostConstruct
public void init(){
personels=personelService.findAll();
personel=new Personel();
}
public PersonelService getPersonelService() {
return personelService;
}
public void setPersonelService(PersonelService personelService) {
this.personelService = personelService;
}
public List<Personel> getPersonels() {
return personels;
}
public void setPersonels(List<Personel> personels) {
this.personels = personels;
}
public List<Personel> getSelectedPersonel() {
return selectedPersonel;
}
public void setSelectedPersonel(List<Personel> selectedPersonel) {
this.selectedPersonel = selectedPersonel;
}
public Personel getPersonel() {
return personel;
}
public void setPersonel(Personel personel) {
this.personel = personel;
}
public void createPersonel(){
System.out.println("Personel adding..");
personelService.create(personel);
personel=new Personel();
System.out.println("Personel added");
}
}
I have researched about primefaces command button update but all advices did not worked for me. Thank you in advance
It seems to me that the newly created personel it never added to the list. So you must for example say
personels.add(personel);
or
personels=personelService.findAll();
in createPersonel(), or set personels to null and do a lazy load in getPersonels().

Update managed bean with ajax ignoring the required

I want to update idOutput everytime that I change the value of selectOneMenu, but when it changes once a time to a value different of null I can't asign null another time, I think that is due to the required="true", but I don't know how to avoid the validation only in the ajax request.
Here is the code:
Bean:
#ViewScoped
#ManagedBean
public class ProbeNull implements Serializable
{
private static final long serialVersionUID = 1628174277372407129L;
private Boolean probe;
public ProbeNull()
{
super();
}
public void show()
{
System.err.println("Value : " + probe);
}
public void save()
{
System.err.println("Save : " + probe);
}
public Boolean getProbe()
{
return probe;
}
public void setProbe(Boolean probe)
{
System.err.println("Setter: " + probe);
this.probe = probe;
}
}
xhtml:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<h:outputText id="idOutput" value="#{probeNull.probe}" />
<h:form id="form">
<p:selectOneMenu id="select" required="true" value="#{probeNull.probe}">
<f:selectItem itemLabel="Select one" itemValue="#{null}" />
<f:selectItem itemLabel="Yes" itemValue="true" />
<f:selectItem itemLabel="No" itemValue="false" />
<p:ajax update=":idOutput" />
</p:selectOneMenu>
<p:commandButton value="Save" ajax="false" action="#{probeNull.save()}" />
</h:form>
<h:form>
<p:commandButton value="Show value" ajax="false" action="#{probeNull.show()}" />
</h:form>
</h:body>
</html>
How can avoid it?
You can do what you want by using two remoteCommand tags and JavaScript.
<p:remoteCommand name="makeSelection" process="select" update=":idOutput" />
<p:remoteCommand name="clearSelection" process="#this" update="select,:idOutput" >
<f:setPropertyActionListener value="#{null}" target="#{probeNull.probe}" />
</p:remoteCommand>
Now you can decide which one to call using a javascript funcion
<p:selectOneMenu id="select" required="true" value="#{probeNull.probe}" onchange="selectFunction(this)">
...
function selectFunction(el){
//if el.value is empty you call clearSelection();
//else you call makeSelection();
}
Don't forget to delete the <p:ajax update=":idOutput" />

validator for custom components in JSF fails

In my custom component, I have
<composite:interface>
<composite:editableValueHolder name="val_pwd" targets="form:pwd"/>
<composite:attribute name="name" required="true"/>
.....
</composite:interface>
<composite:implementation>
<h:form id="form">
<h:panelGrid columns="3">
<h:outputText value="#{cc.attrs.namePrompt}" />
<h:inputText value="#{cc.attrs.name}" id="name"/>
<h:outputText value="#{cc.attrs.passwordPrompt}" />
<h:inputSecret value="#{cc.attrs.pwd}" id="pwd"/>
<h:commandButton value="#{cc.attrs.submitButtonValue}" action="#{cc.attrs.actionMethod}"/>
</h:panelGrid>
</h:form>
</composite:implementation>
I have a validator,
#FacesValidator("passwordVal")
public class PasswordValidator implements Validator {
public PasswordValidator() {
super();
}
#Override
public void validate(FacesContext facesContext, UIComponent uIComponent, Object object) throws ValidatorException {
if(object instanceof String){
String s = (String) object;
if(s.contains("#"))
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error","Password cannot have #"));
}
}
}
In my JSF page, I have
<h:body>
<util:ccwithcustomval namePrompt="r_Name" passwordPrompt="r_pwd" name="#{person.name}"
pwd="#{person.pwd}" actionMethod="#{person.action}" submitButtonValue="r_submit">
<f:validateLength for="val_name" maximum="5"/>
<f:validator validatorId="passwordVal" for="val_pwd" />
</util:ccwithcustomval>
</h:body>
However, it fails with exception
InputComponent.xhtml #12,60 <f:validator> ADF_FACES-60085:Parent not an instance of
EditableValueHolder: javax.faces.component.UINamingContainer#4e18afaa
The problem is with my validator, if I comment it out the page displays

Custom scope of a ManagedBean in JSF2.0 with PrimeFaces 3.5

Following is my requirement-
Here I have a p:panelGrid which can add & delete the row of table. The grid contains some p:inputText and various other PrimeFaces components along with a p:fileUpload component in each row. The component p:fileUpload is set with mode="advanced" auto="true" attributes, which automatically uploads the file and hide itself after completing the successful upload.
The whole p:panelGrid is in #ViewScoped, hence working fine. I kept p:fileUpload component in #RequestScoped since for each upload request it has to upload the file but after adding new row, the previous state is not persisted anymore. so the p:fileUpload is starting visible in previous rows also. That's what I don't want. Do I need to write any custom scope for it?
Below is the view-|
<h:form>
<p:panel id="agentForm" header="#{msg.AGENTS_INFORMATION}"
style="overflow:auto; margin-bottom: 2px">
<div align="center" style="margin-top: 20px; margin-bottom: 2px">
<ui:repeat value="#{agent.scenarioList}" var="c">
<p:panelGrid>
<p:row>
<p:column>
<p:inputText id="ipaddress" value="#{c.machineIpAddress}"
style="width:90%">
<p:watermark for="ipaddress" value="#{msg.MACHINE_IP_ADDRESS}" />
</p:inputText>
</p:column>
<p:column>
<p:inputText id="username" value="#{c.machineUsername}"
style="width:90%">
<p:watermark for="username" value="#{msg.MACHINE_USERNAME}" />
</p:inputText>
</p:column>
<p:column>
<p:password id="passwd" value="#{c.machinePassword}">
<p:watermark for="passwd" value="#{msg.MACHINE_PASSWORD}" />
</p:password>
</p:column>
<p:column id="fileUpload">
<p:fileUpload rendered="#{!fileUploadController.hidden}"
label="Upload Script" style="font-size: 100% !important;"
showButtons="false"
fileUploadListener="#{fileUploadController.upload}"
mode="advanced" auto="true" sizeLimit="100000"
allowTypes="/(\.|\/)(py|txt)$/"
update="fileUpload, outPanel, :message" />
<p:outputPanel id="outPanel">
<!-- Below outputLabel will be linked to uploaded file, so that User can see the file -->
<p:outputLabel style="cursor: pointer" value="View uploded Script"
label="View Script" rendered="#{fileUploadController.hidden}" />
</p:outputPanel>
</p:column>
<p:column>
<p:inputText id="testname" value="#{c.testName}"
style="width:90%">
<p:watermark for="testname" value="#{msg.TEST_NAME}" />
</p:inputText>
</p:column>
<p:column>
<p:spinner id="threads" value="#{c.threads}" min="1" max="500"
size="8">
<p:tooltip for="threads" value="#{msg.TEST_NAME}"
showEffect="slide" hideEffect="slide" />
</p:spinner>
</p:column>
<p:column>
<p:selectBooleanCheckbox id="chkSelected" value="#{c.selected}">
<p:tooltip for="chkSelected" value="#{msg.CHECKBOX}"
showEffect="slide" hideEffect="slide" />
</p:selectBooleanCheckbox>
</p:column>
</p:row>
</p:panelGrid>
</ui:repeat>
<p:toolbar style="margin-top: 10px;">
<p:toolbarGroup align="right">
<p:commandButton value="#{msg.ADD_IT}"
update=":message, agentForm"
actionListener="#{agent.addComponent()}" />
<p:commandButton value="#{msg.DELETE_IT}"
update=":message, agentForm"
actionListener="#{agent.deleteComponent()}" />
</p:toolbarGroup>
</p:toolbar>
</div>
</p:panel>
</h:form>
My managed bean which is in #ViewScoped look like this-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.ravij.performance.model.Scenario;
#ManagedBean(name = "agent")
#ViewScoped
public class AgentInfo implements Serializable {
private static final long serialVersionUID = 1L;
List<Scenario> scenarioList;
#PostConstruct
public void initBean() {
this.scenarioList = new ArrayList<Scenario>();
this.scenarioList.add(new Scenario());
}
public void addComponent() {
if (this.scenarioList != null) {
this.scenarioList.add(new Scenario());
} else {
this.initBean();
}
}
public void deleteComponent() {
List<Scenario> itemsToDelete = new ArrayList<Scenario>();
if (this.scenarioList != null) {
for (Scenario b : this.scenarioList) {
if (b.isSelected()) {
itemsToDelete.add(b);
}
}
this.scenarioList.removeAll(itemsToDelete);
}
}
public List<Scenario> getScenarioList() {
return scenarioList;
}
public void setScenarioList(List<Scenario> scenarioList) {
this.scenarioList = scenarioList;
}
}
The Scenario object contains all the information of a row. Below is the code-
package org.ravij.performance.model;
import java.io.Serializable;
public class Scenario implements Serializable {
private String machineIpAddress;
private String machineUsername;
private String machinePassword;
private String uploadedFilePath;
private String testName;
private int threads = 1;
private boolean selected = false;
//Below are the getters and setter w.r.t all the above variables
//I am not putting it, to make the code short
}
The managed bean FileUploadController is in #RequestScoped
You should simply keep your hidden attribute with the other values in your #ViewScoped bean. Your current code has a single hidden attribute shared with all your <p:fileUpload components which is probably not what you want.
The behavior looks good because you are only updating the current fileUpload but according to your code all the others <p:fileUpload component are supposed to be hidden.
You should also put your <h:form into your <ui:repeat so that you can know the current line which is concerned by the file being uploaded by putting something like an index (which you can get from the <ui:repeat using varStatus attribute) or any other identifier to match the current line in an hidden input.
From #{fileUploadController.upload} the easiest manner to get the hidden parameter is to get the response from FacesContext as explained here : How to get parametrs to BackingBean from jsf page in <ui:repeat>
UPDATE
It was a bit harder than expected, the problem is that <p:fileUpload will send everything in the enclosing form (didn't try to play with process attribute) and thus it will be hard to know what row is concerned by the file upload.
Also I didn't knew that you couldn't put <h:form in your <ui:repeat but the behavior of your delete button is blocking as it expects to get everything in one form.
I made a working POC using dialog to put the fileupload outside, here is how :
The trivial Scenario.java :
public class Scenario implements Serializable {
private String machineIpAddress;
private String machineUsername;
private String machinePassword;
private String uploadedFilePath;
private String testName;
private int threads = 1;
private boolean selected = false;
private boolean hidden = false; // This is new
// + Getters/Setters
}
A few changes in the AgentInfo.java :
#ManagedBean(name = "agent")
#ViewScoped
public class AgentInfo implements Serializable {
private List<Scenario> scenarioList;
private Scenario currentScenario; // This is new
// I removed the #PostConstruct which I rarely use
public void addComponent() {
if (this.scenarioList != null) {
this.scenarioList.add(new Scenario());
}
}
public void deleteComponent() {
if (this.scenarioList == null) {
return;
}
List<Scenario> itemsToDelete = new ArrayList<Scenario>();
for (Scenario scenario : this.scenarioList) {
if (scenario.isSelected()) {
itemsToDelete.add(scenario);
}
}
this.scenarioList.removeAll(itemsToDelete);
}
// This is new, it must be called before opening the upload dialog
// in order to keep a pointer on the current scenario you are working on
public void prepareUpload(Scenario scenario) {
this.currentScenario = scenario;
}
// I put the upload method here
public void upload(FileUploadEvent event) {
// Do what you need to do here
this.currentScenario.setHidden(true);
RequestContext.getCurrentInstance().execute("uploadDialogWidget.hide()");
}
public List<Scenario> getScenarioList() {
if (this.scenarioList == null) {
this.scenarioList = new ArrayList<Scenario>();
this.scenarioList.add(new Scenario());
}
return scenarioList;
}
public void setScenarioList(List<Scenario> scenarioList) {
this.scenarioList = scenarioList;
}
public Scenario getCurrentScenario() {
return currentScenario;
}
public void setCurrentScenario(Scenario currentScenario) {
this.currentScenario = currentScenario;
}
}
The most changes are in the view, I put a <h:commandButton to open the dialog in the form. I also added the dialog, and added the redisplay attribute for your password fields (which is necessary to have if you want to keep the value after form submission).
Note that I removed references to a component with message id which was not gave, don't forget to reintroduce it.
the .xhtml :
<h:form id="agentForm">
<p:panel header="#{msg.AGENTS_INFORMATION}"
style="overflow:auto; margin-bottom: 2px">
<div align="center" style="margin-top: 20px; margin-bottom: 2px">
<ui:repeat value="#{agent.scenarioList}" var="c">
<p:panelGrid>
<p:row>
<p:column>
<p:inputText id="ipaddress" value="#{c.machineIpAddress}"
style="width:90%">
<p:watermark for="ipaddress" value="#{msg.MACHINE_IP_ADDRESS}" />
</p:inputText>
</p:column>
<p:column>
<p:inputText id="username" value="#{c.machineUsername}"
style="width:90%">
<p:watermark for="username" value="#{msg.MACHINE_USERNAME}" />
</p:inputText>
</p:column>
<p:column>
<p:password id="passwd" value="#{c.machinePassword}" redisplay="true">
<p:watermark for="passwd" value="#{msg.MACHINE_PASSWORD}" />
</p:password>
</p:column>
<p:column id="fileUpload">
<p:commandButton icon="ui-icon-arrowthick-1-n" value="Upload"
actionListener="#{agent.prepareUpload(c)}"
update=":uploadDialog"
oncomplete="uploadDialogWidget.show()"
rendered="#{!c.hidden}" />
<p:outputPanel id="outPanel">
<!-- Below outputLabel will be linked to uploaded file, so that User can see the file -->
<p:outputLabel style="cursor: pointer" value="View uploded Script"
rendered="#{c.hidden}" />
</p:outputPanel>
</p:column>
<p:column>
<p:inputText id="testname" value="#{c.testName}"
style="width:90%">
<p:watermark for="testname" value="#{msg.TEST_NAME}" />
</p:inputText>
</p:column>
<p:column>
<p:spinner id="threads" value="#{c.threads}" min="1" max="500"
size="8">
<p:tooltip for="threads" value="#{msg.TEST_NAME}"
showEffect="slide" hideEffect="slide" />
</p:spinner>
</p:column>
<p:column>
<p:selectBooleanCheckbox id="chkSelected" value="#{c.selected}">
<p:tooltip for="chkSelected" value="#{msg.CHECKBOX}"
showEffect="slide" hideEffect="slide" />
</p:selectBooleanCheckbox>
</p:column>
</p:row>
</p:panelGrid>
</ui:repeat>
<p:toolbar style="margin-top: 10px;">
<p:toolbarGroup align="right">
<p:commandButton value="#{msg.ADD_IT}" update="agentForm"
actionListener="#{agent.addComponent()}" />
<p:commandButton value="#{msg.DELETE_IT}" update="agentForm"
actionListener="#{agent.deleteComponent()}" />
</p:toolbarGroup>
</p:toolbar>
</div>
</p:panel>
</h:form>
<p:dialog id="uploadDialog" widgetVar="uploadDialogWidget" header="File upload">
<h:form rendered="#{!empty agent.currentScenario}">
<p:fileUpload
label="Upload Script" style="font-size: 100% !important;"
showButtons="false"
fileUploadListener="#{agent.upload}"
mode="advanced" auto="true" sizeLimit="100000"
allowTypes="/(\.|\/)(py|txt)$/"
update=":agentForm">
</p:fileUpload>
<p:commandButton value="Cancel" onclick="uploadDialogWidget.hide();" onstart="return false;" />
</h:form>
</p:dialog>
You should consider to move from <p:panelGrid to a <p:dataTable which has a built in mechanism to work with row selection.

add user entered data to database using jsf

As I'm new to JSF framework, wanted to know how to add the user entered data to the database.
More clearly, i'm using jsf with jsp, my jsp contains some input fields and a submit button.How do i capture all the user entered data and send it as input paramters for the button, as my back end takes all these as input parameters and updates the table with a new record.
Please look into my code and lety me know my mistake
Registration.jsp
<body>
<f:view>
<h:form>
<h:panelGrid columns="2" rules="all" width="100%" style="background:#03547C;color:#FDD017">
<h:column>
<h:outputText value="Stu No : "></h:outputText>
<h:inputText value="#{RegBean.stuNo}"/>
</h:column>
<h:column>
<h:outputText value="Stu Name : "></h:outputText>
<h:inputText value="#{RegBean.stuName}"/>
</h:column>
<h:column>
<h:outputText value="Standard : "></h:outputText>
<h:inputText value="#{RegBean.standard}" />
</h:column>
<h:column>
<h:outputText value="School : "></h:outputText>
<h:inputText value="#{RegBean.school}" />
</h:column>
</h:panelGrid>
<h:panelGrid columns="2" rules="all" width="100%" style="background:#03547C;color:#FDD017">
<h:column>
<h:form>
<h:commandButton id="submitBtn" value="Submit" action="#{RegBean.submitDetails}">
<f:param name="sNo" value="#{RegBean.stuNo}" />
<f:param name="sName" value="#{RegBean.stuName}" />
<f:param name="std" value="#{RegBean.standard}" />
<f:param name="schl" value="#{RegBean.school}" />
</h:commandButton>
</h:form>
</h:column>
</h:panelGrid>
</h:form>
</f:view>
</body>
Registration Bean
public class VendorRegBean {
private String stuNo;
private String stuName;
private String standard;
private String school;
// getters and setters
public void submitDetails() {
Map requestMap = context.getExternalContext().getRequestParameterMap();
String stNo = (String) requestMap.get("sNo");
String stName = (String) requestMap.get("sName");
String stndrd = (String) requestMap.get("std");
String scl = (String) requestMap.get("schl");
vReg.stuRegistration(stNo ,stName ,stndrd ,scl );
}
}
You don't need to get the parameters from the request parameter map as long as you register your bean as managed bean and provide getter and setter methodes for your bean members.
Use annotations for your bean to declare it as managed bean. Getter and setter example are given for stuNo member:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class RegBean {
private String stuNo;
...
private String getStuNo() {
return stuNo;
}
private String setStuNo(String stuNo) {
this.stuNod = stuNo;
}
}
In the view you have to reference the managed bean with first letter lower case, such as:
<h:inputText value="#{regBean.stuNo}"/>
Your command button doesn't need <f:param>, simply use:
<h:commandButton id="submitBtn" value="Submit" action="#{regBean.submitDetails}"/>
Then all parameters are automatically available in your submitDetails method and you don't need to get them from the parameter map.

Resources