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 ... }