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.
Related
The short version of my problem is that the inputtext will not change the value in bean after I modified the value from the bean.
The longer version:
There is a form in which is a dataTable with user information; some inputTexts, and two buttons. If you fill the inputTexts, a new user will be created with the given data, and appears in dataTable - this works fine, I can create as many users as I can.
The tricky part is if you select a row from the dataGrid, the user information has to appear in the inputText fields - this works fine - so the admin can modify them. But after changing the inputText values in the bean, if the admin changes someting in the inputText, the value "will not follow" tha changes, the value remains the same. What could I do wrong?
The JSF page looks like this:
<html>
<h:body>
<h:form style="font-size:14px;" id="setupform">
...
<p:panel header="Edit users" id="userAddingPanel" rendered="#{settingsbean.validLogin}">
<p:panelGrid columns="2" id="userAddingGrid">
<p:outputLabel value="User Name: " />
<p:inputText id="userName" value="#{settingsbean.userName}" />
<p:outputLabel value="User Password: " />
<p:password id="userPass" value="#{settingsbean.userPassword}" />
<p:outputLabel value="E-mail address: " />
<p:inputText id="userMailAddress" value="#{settingsbean.mailAddress}" />
<p:outputLabel id="userDelete" value="Inactivate User: " />
<p:selectBooleanCheckbox id="isUserDeleted" value="#{settingsbean.deletedUser}" />
<p:commandButton id="addUser" value="Create User" update="userAddingGrid" icon="ui-icon-disk" action="#{settingsbean.addNewUser}" />
<p:commandButton id="modifyUser" value="Modify User" icon="ui-icon-wrench" update="userAddingGrid" action="#{settingsbean.updateUser}" process="setupform"/>
</p:panelGrid>
<br/>
<p:dataTable id="usersTable" var="users" value="#{settingsbean.userList}" tableStyle="overflow: auto;" stickyHeader="true" selectionMode="single" rowKey="#{users.id}" selection="#{settingsbean.selectedUser}">
<p:ajax event="rowSelect" update=":setupform:userName, :setupform:userName,
:setupform:userPass, :setupform:userMailAddress, :setupform:isUserDeleted" />
<p:column headerText="#ID">
<h:outputText value="#{users.id}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{users.loginName}" />
</p:column>
...
</p:dataTable>
</p:panel>
</h:form>
</h:body>
</html>
And my bean looks like this:
#ManagedBean(name ="settingsbean")
#ViewScoped
public class SettingsBean {
private String userName;
private String userPassword;
private boolean deletedUser;
private List<UserDTO> userList;
private UserDTO selectedUser;
/*with getters and setters, what is uncenventional is this setter*/
public void setSelectedUser(UserDTO selectedUser) {
/*if admin selects/unselects a user from dataTable*/
this.selectedUser = selectedUser;
/*if unselect user*/
if(selectedUser == null){
userName = "";
mailAddress = "";
deletedUser = false;
/*if selects user*/
}else {
userName = selectedUser.getLoginName();
mailAddress = selectedUser.getMailAddress();
deletedUser = selectedUser.getDeleted();
}
}
...
public void addNewUser(){
//creates a new user in DB
}
public void updateUser(){
//will update user in DB
}
}
You have to process the components that you want to be updated
<p:commandButton id="modifyUser" value="Modify User" icon="ui-icon-wrench" update="userAddingGrid" action="#{settingsbean.updateUser}" process="userAddingGrid"/>
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.
I am trying to use the feature of prime faces which allows user to edit the cell data in the table itself.I have followed this link to achieve it:
Primefaces showcase
When I say edit a cell in the table, new values which are entered are not sent to the bean.It still shows the old values only.
My code JSF:
<h:form id="testform">
<p:growl id="messages" showDetail="true" />
<p:outputPanel id="testContainer" deferred="true">
<p:remoteCommand name="oncompleteCellEdit" update="cars messages" />
<p:dataTable id="cars" var="car" value="#{articlesbean.LMatpilotaccess1}" editable="true" editMode="cell" widgetVar="carsTable" update=":cars">
<f:facet name="header">
Matériel du pilotage et accessoires
</f:facet>
<p:ajax event="cellEdit" listener="#{articlesbean.onCellEdit}" oncomplete="oncompleteCellEdit()" update=":testform:messages" />
<p:column headerText="Serie" style="width:25%">
<p:cellEditor >
<f:facet name="output"><h:outputText value="#{car.serie}" /></f:facet>
<f:facet name="input"><p:inputText id="modelInput16" value="#{car.serie}" style="width:96%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Cap" style="width:25%">
<p:cellEditor >
<f:facet name="output"><h:outputText value="#{car.cap}" /></f:facet>
<f:facet name="input"><p:inputText id="modelInput15" value="#{car.cap}" style="width:96%"/></f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</p:outputPanel>
</h:form>
My code bean
#ManagedBean(name="articlesbean")
#ViewScoped
public class ArticlesBean implements Serializable{
#Inject
private ArticlesDAO articleDAO;
private Matpilotaccess1 matpilotaccess1;
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
System.out.println("/////"+(event.getNewValue());
System.out.println("/////"+(event.getOldValue());
FacesContext context = FacesContext.getCurrentInstance();
Matpilotaccess1 mpltiacc = context.getApplication().evaluateExpressionGet(context, "#{mpltiacc}", Matpilotaccess1.class);
articleDAO.Updatetable(mpltiacc);
}
/////////Getters and Setters
}
and as result of
System.out.println("/////"+(event.getNewValue());
System.out.println("/////"+(event.getOldValue());
i got in both case the old value!!!
Could anyone let me know how I can get the new values???I am using Jboss 7 and primefaces4 Thanks
You need to annotate your bean with #SessionScoped annotation.
i wish to display 2 different datatables in each tab of the tabview of primefaces 3.2.
there datatables will fetch data based on the 'type' variable set in the onChange event. but my problem is that the onChange event does not fire at all.
pls check my tabview code to check why this is happening:
<h:form id="frm">
<p:tabView activeIndex="#{equityBean.activeIndex}">
<p:ajax event="tabChange" listener="#{equityBean.onChange}" update=":frm"/>
<p:tab title="NSE" binding="#{equityBean.tbn}">
<p:dataTable binding="#{equityBean.dt}" value="#{equityBean.scripList}" var="scrip">
<f:facet name="header">
Scrip Symbol
</f:facet>
<h:outputText value="#{scrip.scripSymbol}"/>
<f:facet name="header">
Company Name
</f:facet>
<h:outputText value="#{scrip.companyName}"/>
<f:facet name="header">
Volume
</f:facet>
<h:outputText value="#{scrip.totalTradedVolume}"/>
</p:dataTable>
</p:tab>
<p:tab title="BSE" binding="#{equityBean.tb}">
</p:tab>
</p:tabView>
</h:form>
bean:
public void onChange(TabChangeEvent event) {
type=event.getTab().getTitle();
}
edited:
bean code to get datatable value:
public List<MasterScrip> getScripList() {
scripList=new ArrayList<MasterScrip> ();
scripList=getScripByVolumeType(type);
return scripList;
}
private java.util.List<service.MasterScrip> getScripByVolumeType(java.lang.String type) {
service.StatelessWebService port = service.getStatelessWebServicePort();
return port.getScripByVolumeType(type);
}
edited : jpa query
public Collection<MasterScrip> getScripByVolumeType(String type)
{
Collection sm=null;
sm=em.createQuery("select m from MasterScrip m where m.type = :type order by m.totalTradedVolume").setParameter("type", type).setMaxResults(2).getResultList(); // retuens no records
return sm;
}
records are returned but not displayed..
why does this happen? where am i wrong?
Your mistake is here.
listener="#{equityBean.onChange(event)}"
The event object does not exist in EL scope. Remove the argument. You don't need to specify it at all. JSF will supply the necessary action listener argument itself.
listener="#{equityBean.onChange}"
The same is true for all other listener and actionListener attributes. Only in action attribute of UICommand components you can specify custom arguments (which should be passed with real values, not with some random and non-existent variable name).
I want to create h:datatable with list of data:
<h:dataTable id="dataTable" value="#{SessionsController.dataList}" binding="#{table}" var="item">
<!-- Check box -->
<h:column>
<f:facet name="header">
<h:outputText value="Select" />
</f:facet>
<h:selectBooleanCheckbox onclick="highlight(this)"
value="#{item.selected}" />
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="№"
actionListener="#{SessionsController.sort}">
<f:attribute name="№" value="№" />
</h:commandLink>
</f:facet>
<h:outputText
value="#{table.rowIndex + SessionsController.firstRow + 1}" />
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="Account Session ID"
actionListener="#{SessionsController.sort}">
<f:attribute name="sortField" value="Account Session ID" />
</h:commandLink>
</f:facet>
<h:outputText value="#{item.aSessionID}" />
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="User ID"
actionListener="#{SessionsController.sort}">
<f:attribute name="sortField" value="User ID" />
</h:commandLink>
</f:facet>
<h:outputText value="#{item.userID}" />
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="Activity Start Time"
actionListener="#{SessionsController.sort}">
<f:attribute name="sortField" value="Activity Start Time" />
</h:commandLink>
</f:facet>
<h:outputText value="#{item.activityStart}" />
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="Activity End Time"
actionListener="#{SessionsController.sort}">
<f:attribute name="sortField" value="Activity End Time" />
</h:commandLink>
</f:facet>
<h:outputText value="#{item.activityEnd}" />
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="Activity"
actionListener="#{SessionsController.sort}">
<f:attribute name="sortField" value="Activity" />
</h:commandLink>
</f:facet>
<h:outputText value="#{item.activity}" />
</h:column>
</h:dataTable>
I want when I click on a table row to open a new page which displays more details. I want to use the table key aSessionID which will be used for SQL query to get a data from the database. I know that I can use h:commandLink to pass the key but I don't want ugly html link. Is there other way to click on the JSF table row, pass a key and open a new window?
Best Wishes
EDIT
I found one possible solution here
Using this JavaScript code it's possible to open a new window when the user clicks on a row:
<table id="row_link">
<tbody>
<tr>
<td>link</td>
<td>info 1</td>
</tr>
<tr>
<td>link</td>
<td>info 2</td>
</tr>
</tbody>
</table>
$("table#row_link tbody tr").click(function () {
window.location = $(this).find("a:first").attr("href");
});
The question is how I can pass this key aSessionID to the new window.
In the above example href is used to pass the link to the new window. What attribute can be used in JSF table?
#BalusC (JSF expert) has a post about managing Datatable in JSF 1.2 but it works for JSF 2.x too. You're interested in the select row on click section.
UPDATE:
Let me explain the example. First, every JSF component ID will have this form: :, example:
<h:form id="myForm">
<h:inputText id="myInputText" value="#{myBean.textValue}" />
</h:form>
This will generate the HTML:
<form id="myForm">
<input type="text" id="myForm:myInputText" />
</form>
Second, you have to update the generated DOM for the datatable. He's doing that by javascript and also gives you the js code:
function addOnclickToDatatableRows() {
//gets all the generated rows in the html table
var trs = document.getElementById('form:dataTable').getElementsByTagName('tbody')[0]
.getElementsByTagName('tr');
//on every row, add onclick function (this is what you're looking for)
for (var i = 0; i < trs.length; i++) {
trs[i].onclick = new Function("highlightAndSelectRow(this)");
}
}
Third, define the highlightAndSelectRow js function (you can change the name to whatever you want).
function highlightAndSelectRow(tr) {
//get all the datatable rows
var trs = document.getElementById('form:dataTable').getElementsByTagName('tbody')[0]
.getElementsByTagName('tr');
//find the selected rowby using the tr parameter
for (var i = 0; i < trs.length; i++) {
if (trs[i] == tr) {
//once found it, change the color (maybe you don't need this part)
trs[i].bgColor = '#ff0000';
//update a hidden value in the form (maybe you need this code)
document.form.rowIndex.value = trs[i].rowIndex;
//here, you can add js code to open a new window
//or simulate a button/link click or something else you need.
} else {
trs[i].bgColor = '#ffffff';
}
}
}
UPDATE 2:
I've made a test for this case. I'll show you the code to get it done using facelets.
DataTable.xhtml
<script type="text/javascript">
function addOnclickToDatatableRows() {
//gets all the generated rows in the html table
var trs = document.getElementById('myForm:dataTable').getElementsByTagName('tbody')[0]
.getElementsByTagName('tr');
//on every row, add onclick function (this is what you're looking for)
for (var i = 0; trs.length > i; i++) {
trs[i].onclick = new Function("rowOnclick(this)");
}
}
function rowOnclick(tr) {
var elements = tr.cells[0].childNodes;
for(var i = 0; elements.length > i; i++) {
//get the link
if ((typeof elements[i].id !== "undefined") &&
(elements[i].id.indexOf("lnkHidden") > -1)) {
//open a new window/tab using the href generated in link
window.open(elements[i].href);
break;
}
}
return false;
}
</script>
<h:form id="myForm">
<h1>Show data</h1>
<h:dataTable id="dataTable" var="data" value="#{datatableBean.lstData}">
<h:column>
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:outputText value="#{data.id}" />
<!-- define a hidden link for every row of the datatable
the value attribute contains the page to redirect. -->
<h:outputLink id="lnkHidden" value="AnotherPage.xhtml"
style="display:none">
<f:param name="id" value="#{data.id}" />
</h:outputLink>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Value" />
</f:facet>
<h:outputText value="#{data.value}" />
</h:column>
</h:dataTable>
</h:form>
DataTableBean class
#ManagedBean
#ViewScoped
public class DatatableBean {
private List<Data> lstData;
/**
* Creates a new instance of datatableBean
*/
public DatatableBean() {
lstData = new ArrayList<Data>();
lstData.add(new Data(1, "Hello World"));
lstData.add(new Data(2, "Hello StackOverflow"));
lstData.add(new Data(3, "Hello Luiggi"));
System.out.println("LOL");
}
//define getters and setters...
}
AnotherPage.xhtml
<h1>This is another page</h1>
<h:panelGrid columns="2">
<h:outputText value="Selected ID" />
<h:outputText value="#{anotherPageBean.id}" />
</h:panelGrid>
AnotherPageBean class
#ManagedBean
#RequestScoped
public class AnotherPageBean {
private int id;
/**
* Creates a new instance of AnotherPageBean
*/
public AnotherPageBean() {
try {
this.id = Integer.parseInt((String)FacesContext
.getCurrentInstance().getExternalContext()
.getRequestParameterMap().get("id"));
//by getting the id you can get more data
}
catch (Exception e) {
this.id = 0;
}
}