setting attribute value to String in managed Bean JSF 2.2 - java

I have an attribute called chemin in my managed bean, which I want to set It's value to a String ( the attribute value should be stored in database, and not coming from a form), but I don't know how to do that.
the attribute chemin is inside a method that upload a file and store it's relatives info in data base such as date, document title, description, and path to the uploaded file ( the file is stored in a directory).
this is the code doing that :
managed bean :
public String upload() throws IOException{
file.write(getFilename(file));
docDAO.createDoc(idDocument, titreDocument, descriptionDocument, sousCategorie, Categorie, chemin, dateMise, lien);
idDocument=null;
titreDocument="";
descriptionDocument="";
lien="";
sousCategorie="";
dateMise="";
Categorie="";
chemin="C:\\data\\" +getFilename(file);
}
DAO class :
public void createDoc(Integer idDocument, String titreDocument,
String descriptionDocument, String sousCategorie
, String Categorie, String chemin, String dateMise, String lien) {
em.getTransaction().begin();
Document f =new Document();
f.setIdDocument(idDocument);
f.setDateMise(dateMise);
f.setDescriptionDocument(descriptionDocument);
f.setLien(lien);
f.setChemin(chemin);
f.setTitreDocument(titreDocument);
f.setCategorie(Categorie);
f.setSousCategorie(sousCategorie);
em.persist(f);
em.getTransaction().commit();
}
the xhtml page :
<h:form>
<h:outputText value="chemin"></h:outputText>
<h:inputHidden value="#{docBean.chemin}"></h:inputHidden><br/>
<!-- <c:set value="mobil" target="#{docBean}" property="chemin" /> -->
<h:outputText value="Date de la mise "></h:outputText>
<h:inputText value="#{docBean.dateMise}"></h:inputText><br/>
<h:outputText value="Lien"></h:outputText>
<h:inputText value="#{docBean.lien}"></h:inputText><br/>
<h:outputText value="Catégorie"></h:outputText>
<h:inputText value="#{docBean.categorie}"></h:inputText><br/>
<h:outputText value="sous catégorie"> </h:outputText>
<h:inputText value="#{docBean.sousCategorie}"></h:inputText><br/>
<h:outputText> télécharger le document</h:outputText>
<h:inputFile value="#{docBean.file}"></h:inputFile><br/>
<h:commandButton value="valider" action="#{docBean.upload}"/>
</h:form>
any idea could help.

First , you have to remove <h:inputHidden value="#{docBean.chemin}"></h:inputHidden> from your xhtml page, and in your upload method give to chemin the desired value before calling docDAO.createDoc() so that you can save it in your database.

Related

JF2 Dynamic form element doesn't remember input and page refreshes every time I add element

I am trying to make a form with options to add rows. However, after I type in some input and click the add button again, the input I enter disappears. I'm not sure what is wrong with my code. In addition, when I click the add button, the page refreshes. Is there way to stop this page refresh?
Person.java
public class Person{
private List<String> guys = new ArrayList<String>();
public List<String> getGuys() {
return guys;
}
public void setGuys(List<String> guys) {
this.guys = guys;
public void addNewItem(){
guys.add("");
}
}
form.xhtml
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men">
<h:column>
<p:inputText value="#{men}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton name="submit" type="submit" value="Submit"></h:commandButton>
</h:form>
Provided that the bean is placed in the right scope for the functional requirement, the view scope, the only major mistake left is that you're expecting that the String class has some magic setter method.
It hasn't. The String class is immutable. The following will never work on a String:
<p:inputText value="#{men}" />
You have 2 options:
Create a real model class. You can find complete examples in the following answers:
How to dynamically add JSF components
Recommended JSF 2.0 CRUD frameworks
Set the value by row index instead:
<h:dataTable binding="#{table}" value="#{person.guys}">
<h:column>
<p:inputText value="#{person.guys[table.rowIndex]}" />
</h:column>
</h:dataTable>
(note: no additional bean property necessary for the table! the code is as-is)
This does basically a person.getGuys().add(table.getRowIndex(), submittedValue). I.e. the setter is invoked on the List itself, which works perfectly fine. See also the following related answers concerning ui:repeat:
Using <ui:repeat><h:inputText> on a List<String> doesn't update model values
How map multiple inputText to an array property?
You never update your list, you are just adding empty items. You should do something like this:
Person.java (viewscoped)
public class Person implements Serializable {
private List<String> guys = new ArrayList<String>();
private HtmlDataTable dtGuys;
public void addNewItem() {
guys.add("");
}
public void addToList(ValueChangeEvent e) {
guys.set(dtGuys.getRowIndex(), e.getNewValue().toString());
}
public String save() {
System.out.println("saving...");
for (String item : guys) {
System.out.println("item= " + item);
}
return null;
}
//gettes and setters
}
form.xhtml
<h:form id="frmPrincipal">
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men" binding="#{person.dtGuys}" >
<h:column>
<p:inputText value="#{men}" valueChangeListener="#{person.addToList}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton id="submit" name="submit" value="Submit" action="#{person.save}"/>
</h:form>
Using jsf 2.0.10 and primefaces 3.5
Its because you don't have an scope for that bean, so its request scoped, so when you call the action the bean is created again, you can fix this using a sessionScope or conversationScope

How to send/recieve data to/from bean function using JSF Richfaces AJAX?

I'm trying to get some code working in an XHTML/JSF/Spring application through which I send an ID to a bean function and expect a string in return. I haven't found an understandable tutorial on this nor any answered question here on SO.
XHTML:
<h:form>
<h:inputText id="inputId" value="#{npBean.idString}"/>
<a4j:commandButton value="get def" render="out">
<f:param value="#{npBean.idString}" name="id" />
<f:setPropertyActionListener target="#{npBean.definition}"/>
</a4j:commandButton>
<a4j:outputPanel id="out">
<h:outputText id="outputId" value="#{npBean.def}"
rendered="#{not empty npBean.def}"/>
</a4j:outputPanel>
</h:form>
Java:
public String getDefinition(int id)
{
def = this.getXService().getXData(id).getDefinition();
return def;
}
All values shown have their getters and setters in the bean.
What we basically do:
Map the value of the <h:inputText> component to a property (with getter/setter) in the managed-bean (which is called myBean)
By using the reRender attribute of the <a4j:commandButton> component, we point which component on the page to be re-rendered (refreshed) when the button is clicked.
When clicking on the button, the invokeService() method from the managedBean is executed and it updates the other property of the managedBean.
In the <h:panelGroup> below, we have several <h:outputText> components and with the rendered attribute we specify when a component has to be displayed on the page.
Exploring the managed-bean, the only thing that is required, are the accessors for the property, which holds the result from the service invoke.
Here's the *.xhtml sample:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<a4j:form>
<h:panelGrid columns="3">
<h:outputText value="String value:" />
<h:inputText value="#{myBean.value}" />
<a4j:commandButton value="Click" reRender="out">
<a4j:actionListener listener="#{myBean.invokeService}" />
</a4j:comandButton>
</h:panelGrid>
</a4j:form>
<rich:spacer height="7"/>
<br />
<h:panelGroup id="out">
<h:outputText value="Service returned: " rendered="#{not empty myBean.result}" />
<h:outputText value="#{myBean.result}" />
</h:panelGroup>
</ui:composition>
Managed-bean:
#ManagedBean(name = "myBean")
#SessionScoped //for example
public class MyBean {
private String value;
private String result;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getResult() {
return result;
}
public void invokeService(ActionEvent actionEvent) {
this.result = "Hello, " + value + "!";
}
}
As #Luiggi mentioned, the accessor methods MUST meet the following conventions (if we assume you have a private <some-type> property; in the managed-bean.)
public <some-type> getProperty {
return property;
}
public void setProperty(<some-type> property) {
this.property = property:
}
In order to learn how the RichFaces components work, combined with good code examples, I suggest you open this address and play around with the components.

primefaces multiple file upload only updating tree table with first file uploaded

I have a treetable with a multiple file upload component. If i upload 1 file, it correctly updates my treetable with that file.
If i try and upload multiple files at the same time (lets say file1 and file2), it only updates the tree table with file 1. If i then upload another file (file3), it then updates the tree table with file1, file2, and file3 so it seems to be an issue with updating.
Does anyone have any insight into this or know if it's a bug?
<h:form id="attachmentsForm" enctype="multipart/form-data">
<p:treeTable value="#{contentEditorBacking.attachments}" var="node">
<p:column>
<f:facet name="header">Name</f:facet>
<h:outputLink value="#{node.link}" target="_blank" disabled="#{node.disabled}">
<h:outputText value="#{node.displayName}"/>
</h:outputLink>
</p:column>
<p:column>
<f:facet name="header">Size</f:facet>
<h:outputText value="#{node.size}" />
</p:column>
<p:column>
<f:facet name="header">Modified By</f:facet>
<h:outputText value="#{node.modifier}" />
</p:column>
<p:column>
<f:facet name="header">Delete</f:facet>
<p:commandLink styleClass="ui-icon ui-icon-trash" id="deleteProperty" actionListener="#{contentEditorBacking.deleteAttachment}"
rendered="#{node.canDelete}" update="attachmentsForm">
<f:attribute name="filename" value="#{node.displayName}" />
</p:commandLink>
</p:column>
</p:treeTable>
<p:fileUpload fileUploadListener="#{contentEditorBacking.handleFileUpload}"
mode="advanced" sizeLimit="#{contentEditorBacking.fileSizeLimit}"
invalidSizeMessage="#{contentEditorBacking.fileSizeMessage}"
allowTypes="#{contentEditorBacking.allowedFileTypes}" update=":controlTabs:attachmentsForm" />
</h:form>
Backer
public void handleFileUpload(FileUploadEvent event) throws Exception{
UploadedFile toSave = event.getFile();
System.out.println("fileName = "+event.getFile());
String fileName = toSave.getFileName();
String downloadLink = "";
Long size = event.getFile().getSize();
long version = 1;
User user = cm.getUser();
String creator = user.getUserName();
Date modDate = new Date();
boolean canDelete = true;
boolean canUpdate = true;
String displayName = fileName + "- pending";
new DefaultTreeNode(new Attachment(downloadLink,size,version,creator,modDate,canDelete,canUpdate,displayName,true), attachRoot);
addNeedToSaveMessage();
}
EDIT
I added an id to the treeTable and changed my fileUpload update to the id of the treeTable rather than the id of the form tag and then solved my problem.
I always thought that by updating a parent element, it should update all of its children. Is that not true or are there exceptions to this as in the treeTable?
Apparently for the file upload component, i had to update the actual tree table rather its parent form tag.

JSF Output not coming as expected by using commandLink, ViewScope in dataTable

Below are the files I have.
manageStaff.xhtml
<h:dataTable var="c" value="#{newStaffMemberServiceBean.newStaffMemberDataBeanList}"
styleClass="order-table"
headerClass="order-table-header"
rowClasses="order-table-odd-row,order-table-even-row"
border="1" id="staffListDataTable" width="100%">
<h:column>
<f:facet name="header">
Staff Member Name
</f:facet>
<h:form>
<h:commandLink action="viewStaffMemberProfileData" value="#{c.firstName}">
<f:setPropertyActionListener target="#{newStaffMemberServiceBean.userId}" value="XXXYYYZZZZ"/>
</h:commandLink>
</h:form>
</h:column>
</h:dataTable>
viewStaffMemberProfileData.xhtml
My Name is -<h:outputText value="#{newStaffMemberServiceBean.userId}" />-
NewStaffMemberServiceBean.java
#ManagedBean(name = "newStaffMemberServiceBean")
//#RequestScoped
#ViewScoped
//#SessionScoped
public class NewStaffMemberServiceBean {
private String userId;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
In output what I get is in below format
Staff Member Name
++++++++++++++++++
Name 1
Name 2
Name 3
.
.
.
.
On Clicking Name 1, I get re-directed to viewStaffMemberProfileData.xhtml.
BUT problems are
To get re-directed on viewStaffMemberProfileData.xhtml page, I have to click link (Name 1, Name 2, etc) twice :(
When I get re-directed to viewStaffMemberProfileData.xhtml I only see output as
My Name is --
What I want is My Name is -XXXYYYZZZZ-.
Suggest me where I am going wrong.
NOTE
I have all beans in ViewScope.
Update 1
#prajeeshkumar
Getter setter are as below
public List<NewStaffMemberDataBean> getNewStaffMemberDataBeanList() {
return newStaffMemberDataBeanList;
}
public void setNewStaffMemberDataBeanList(List<NewStaffMemberDataBean> newStaffMemberDataBeanList) {
this.newStaffMemberDataBeanList = newStaffMemberDataBeanList;
}
The reason for this behavior is the view scope of the newStaffMemberServiceBean , its being destroyed and created again... so the value is being nullified... here an alternative solution:
haven't tried this one, But worth trying
change
<h:commandLink action="viewStaffMemberProfileData" value="#{c.firstName}">
<f:setPropertyActionListener target="#{newStaffMemberServiceBean.userId}" value="XXXYYYZZZZ"/>
</h:commandLink>
into
<h:link value="#{c.firstName}" outcome="nameOfXhtmlGoesHere">
<f:param name="id" value="XXXYYYZZZZ" />
</h:link>
and in viewStaffMemberProfileData.xhtml
add this before the <h:head>
<f:metadata>
<f:viewParam name="id" value="#{newStaffMemberServiceBean.userId}" />
</f:metadata>
you can also add <f:event type="preRenderView" listener="#{newStaffMemberServiceBean.init}" /> to the f:metadata in order to do some init...
based on this BalusC great article - Communication in JSF 2.0
OR
you can turn the scope of newStaffMemberServiceBean into SessionScope...
If you have newStaffMemberServiceBean in view scope, then when you are going to a different page (view) will that bean be available in that scope ? I mean manageStaff.xhtml will have one instance and viewStaffMemberProfileData.xhtml will have another one. Your solution here will be using the session scope or using the h:link or h:outputLink

JSF1.2 Messages not rendered

Migrating from WAS6.1+JSF1.1+richfaces.3.1.5 to WAS7+JSF1.2+facelets1.1.14+richfaces3.3.3.
Error/Status messages are not rendering using h:messages, even though on debugging the facescontext.getMessages() contains the messages.
On submitting a form, I am validating an input. If the validation fails I am adding an error msg to the facescontext. It can be for multiple inputs. Each error msg is added to the facescontext
FacesMessage message = new FacesMessage();
message.setDetail(msg);
message.setSummary(msg);
message.setSeverity(FacesMessage.SEVERITY_ERROR);
getFacesContext().addMessage(componentID, message);
and on the xhtml I am displaying it using h:messages
I was using jsp in WAS6.1 and JSF1.1 and this used to work fine
Thanks
Adding more details
My xhtml
<ui:composition template="/template.xhtml">
<ui:define name="content">
<div id="content-nosidebar">
<h:form id="uploadDoc1" >
<h:messages/>
<h:panelGrid id="panelGridContact" headerClass="standardPageHeader" width="100%" cellpadding="5">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Upload Contact Info" />
<hr/>
</h:panelGroup>
</f:facet>
<h:panelGroup id="msgId">
<xyz:errorMessages />
<xyz:statusMessages />
</h:panelGroup>
<h:panelGrid style="text-align: center;font-weight: bold;">
<h:outputText value="Click on Browse button to identify CSV file with contact information for upload."/>
<h:outputText value="File size limit is 10MB."/>
<h:panelGroup>
<rich:fileUpload id="fileuploader" fileUploadListener="#{uploadContactCntrl.onSubmit}"
acceptedTypes="csv" allowFlash="true" listHeight="50" addControlLabel="Select File" uploadControlLabel="Submit" clearControlLabel="clear"/>
</h:panelGroup>
<h:outputText value=" "/>
</h:panelGrid>
</h:panelGrid>
</h:form>
</div>
</ui:define>
</ui:composition>
errorMessages and statusMessages are common tags to display error(validation error) and status((like Update complete) messages
In the the backingbean on submit if an error is encountered (like "File not found" or "Database is down" I call a common method with the error/status message from the resource file.
WebUtils.addCustomErrorMessage("global.error.ContactInfo-DuplicateRecords-UserID", new String[]{userid,Integer.toString(j+1)}, Constants.RESOURCE_BUNDLE_NAME);
or
WebUtils.addCustomStatusMessage("global.error.ContactInfo-successMessage", new String[]{Integer.toString(noOfRowsInserted)}, Constants.RESOURCE_BUNDLE_NAME);
public static void addCustomErrorMessage(String msg, String componentID) {
FacesMessage message = new FacesMessage();
message.setDetail(msg);
message.setSummary(msg);
message.setSeverity(FacesMessage.SEVERITY_ERROR);
getFacesContext().addMessage(componentID, message);
}
public static void addCustomStatusMessage(String msg, String componentID) {
if (errorCodeParameters != null && errorCodeParameters.length > 0)
msg = MessageFormat.format(msg, (Object[])errorCodeParameters);
FacesMessage message = new FacesMessage();
message.setDetail(msg);
message.setSummary(msg);
message.setSeverity(FacesMessage.SEVERITY_INFO);
getFacesContext().addMessage(componentID, message);
}
We also use the same tags to display an error message when an error is encountered on an input field. For e.g. a Firstname field has invalid characters.
As mentioned earlier, this was working fine before we migrated to JSF1.2
Your answer need to have xhtml code too, any way i'm giving u sample for using validation in JSF 1.2...
The xhtml code should be like..
<h:inputText id="txt_project_name"
value="#{FIS_Project_Master.txt_project_name_value}"
validator="#{FIS_Project_Master.txt_project_name_validator}"/>
<h:message id="msg_txt_project_name" for="txt_project_name" />
The java code should be like...
public void txt_project_name_validator(FacesContext context, UIComponent component, Object value) {
if (bmwpProjectMstFacade.ispmProjName_exists(value.toString().toUpperCase().trim())) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "Warning", "Project Name Already Exist");
throw new ValidatorException(message);
}
}

Categories

Resources