Modifying Multiple Selection Rows
brianc.brian.700c.net Nov 10, 2009 9:13 AMI have a scrollableDataTable that contains a List of NodeFile objects, which is a wrapper around a File entity. A button (rename), when clicked, calls processDetailSelection which processes the selection and creates a list of FileNodes to work with. A modelPanel is brought up with the list of fileNodes bound to the name property in an <h:inputText> boxe. The user is asked to rename the files. When done, they click on a button that calls renameSelected.
The problem I am having is that the renamed names are not getting assigned the changed values on postback.
Any ideas are appreciated!
...
<h:form>
<rich:toolBar height="34" itemSeparator="line">
<rich:toolBarGroup>
<a:commandLink id="rename"
action="#{fileManager.processDetailSelection}"
oncomplete="#{rich:component('renamePanel')}.show();"
reRender = "renamePanel">
<h:graphicImage id="renameIcon" value="/img/rename.gif" />
<h:outputLabel value="Rename" for="renameIcon" />
</a:commandLink>
</rich:toolBarGroup>
</rich:toolBar>
</h:form>
<h:panelGrid columns="2" rowClasses="fmGrid">
<h:panelGroup>
...
<h:form>
<rich:scrollableDataTable
value="#{detailFiles}" var="_file"
width="580px" height="400px"
id="detailFiles"
binding="#{fileTable}"
sortOrder="#{fileManager.detailSortOrder}"
sortMode="single"
selection="#{fileManager.detailSelection}">
<rich:column
id="name"
width="170px">
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<ui:remove><!-- <h:graphicImage value="#{_file.type.icon}" /> --></ui:remove>
<h:outputText value="#{_file.name}" />
</rich:column>
... more columns...
</rich:scrollableDataTable>
</h:form>
</h:panelGroup>
</h:panelGrid>
<rich:modalPanel id="renamePanel"
width="400" height="150"
autosized="true">
<f:facet name="header">
<h:outputText value="Rename?"></h:outputText>
</f:facet>
<f:facet name="controls">
<span style="cursor:pointer" onclick="javascript:Richfaces.hideModalPanel('renamePanel')">X</span>
</f:facet>
<h:outputText value="Rename files?" />
<h:form>
<rich:dataList value="#{fileManager.detailSelected}" var="_sel" rows="10">
<h:outputText value="#{_sel.name}"/>: <rich:spacer height="1" width="2" />
<h:inputText id="name" value="#{_sel.file.fileName}" /><br/>
</rich:dataList>
<s:button value="Yes" reRender="tree, detailFiles"
action="#{fileManager.renameSelected}"
oncomplete="javascript:Richfaces.hideModalPanel('renamePanel');" />
<s:button value="Cancel"
oncomplete="javascript:Richfaces.hideModalPanel('renamePanel');" />
</h:form>
</rich:modalPanel>
...
My backing Bean
package com.projectSpace.action;
//imports removed to save space
@Name("fileManager")
@Scope(ScopeType.CONVERSATION)
public class FileManager implements Serializable {
@In(create = true)
ProjectHome projectHome;
@In
protected EntityManager entityManager;
@In
FacesMessages facesMessages;
@RequestParameter
protected Integer projectId;
private static final long serialVersionUID = 6484170532121358284L;
// Tree Variables
public FileNode selectedNode;
private List<FileNode> fileRoots = new ArrayList<FileNode>();
// Detail Variables
@DataModel
protected List<FileNode> detailFiles;
private SimpleSelection detailSelection;
private ArrayList<FileNode> detailSelected = new ArrayList<FileNode>(0);
private SortOrder detailSortOrder;
@In(required = false)
@Out(required = false)
private HtmlScrollableDataTable fileTable;
private String tableState;
private boolean deleteFailed = false;
@Transactional
public String renameSelected(){
if (this.detailSelected.isEmpty()) {
return "noSelection";
}
else {
try {
Iterator<FileNode> iterator = getDetailSelected().iterator();
while (iterator.hasNext()){
FileNode fileNode = iterator.next();
log.info("Renaming: fileNode.name= " +
fileNode.getName() +
", fileNode.file.fileName = " +
fileNode.getFile().getFileName());
entityManager.flush();
}
renamedMessage();
this.refresh();
return "renamed";
} catch (Exception e) {
facesMessages.add("The selected files could not be renamed");
return null;
}
}
}
public String processDetailSelection() {
if (this.detailSelection.size() !=0) {
this.detailSelected.clear();
Iterator<Object> iterator = getDetailSelection().getKeys();
while (iterator.hasNext()){
Integer key = (Integer) iterator.next();
this.detailSelected.add(getDetailFiles().get(key.intValue()));
}
}
return null;
}
...
}
The FileNode
@Name("FileNode")
@Scope(ScopeType.CONVERSATION)
public class FileNode implements Serializable {
private static final long serialVersionUID = 7729590153661819332L;
private File file;
private static List<FileNode> CHILDREN_ABSENT = new ArrayList<FileNode>(0);
private List<FileNode> childFolders;
private List<FileNode> childFiles;
private String name;
private FileNode parent;
public FileNode(File file) {
this.file = file;
this.setName(file);
}
public FileNode(File file, FileNode parent) {
this.file = file;
this.setName(file);
this.setParent(parent);
}
public String getName(){
return this.name;
}
public void setName(File file){
if (file.getFileName().equals("ROOT"))
this.name = file.getProject().getProjectNumber() + " - " + file.getProject().getName();
else
this.name = file.getFileName();
}
public void setName(String name){
if (this.file.getFileName().equals("ROOT"))
return; // we cannot rename the project.
// TODO probably should throw an exception or warn user.
else {
this.name = name;
this.file.setFileName(name);
}
}
public File getFile() {
return this.file;
}
public void setFile(File file) {
this.file = file;
}
....
}
And Finally, the File Entity
@Entity
@Table(name = "files")
public class File implements java.io.Serializable {
private static final long serialVersionUID = -8800801738264510972L;
private Long id;
private Project project;
private String fileName;
private Date dateCreated;
private Date dateModified;
private Type type;
private Boolean folder = false;
private File parent;
private Set<File> subFiles = new HashSet<File>();
private Set<FileRevision> fileRevisions = new HashSet<FileRevision>();
@In
private EntityManager entityManager;
public File() {
}
...
getters/setters
...
}