Details
Description
I think this issue is best explained with an example, so here goes...
I have a tree root. It is not expanded. It has a checkbox, which is not checked.
[+][ ] root
Then I expand the root, which reveals 2 children. The children too have checkboxes that are not checked.
[-][ ] root
- [ ] child1
- [ ] child2
I now check the root and the 2 children. If I were to submit now, everything would work as expected. Values from all 3 checkboxes would be received. But I won't...
[-][x] root
- [x] child1
- [x] child2
... Instead I will collaps the tree again, leaving only the root visible.
[+][x] root
Finally, I submit the tree. In my backing bean I will then only receive the checkbox value of the root. The checkbox value of child1 and child2 is not submitted. Values from the 2 children do exist in the request scope, but for some reason the backing bean is not set with them.
Here follows the code I'm using...
JSF:
<html:form id="createHost">
<tomahawk:tree2 id="clientTree" value="#
"
var="node" showRootNode="false" clientSideToggle="true">
<core:facet name="root">
<html:panelGroup>
<tomahawk:htmlTag value="div">
<html:outputText value="#
<html:outputText value=" (#{node.childCount})"
styleClass="childCount"
rendered="#{!empty node.children}"/>
</tomahawk:htmlTag>
</html:panelGroup>
</core:facet>
<core:facet name="module">
<html:panelGroup>
<tomahawk:htmlTag value="div">
<tomahawk:selectManyCheckbox id="moduleId" layout="spread"
converter="#{HostBean.moduleIdTreeConverter}"
value="#{HostBean.moduleId}">
<tomahawk:treeCheckbox for="moduleId"
itemValue="#{node.identifier}"
itemLabel="#{node.description}
"/>
</tomahawk:selectManyCheckbox>
<html:outputText value=" (#
)"
styleClass="childCount"
rendered="#
"/>
</tomahawk:htmlTag>
</html:panelGroup>
</core:facet>
</tomahawk:tree2>
<html:commandButton value="OK" action="#
"
style="width: 25%;" styleClass="button"/>
</html:form>
HostBean:
private void addModuleId(String moduleId) {
if (moduleId != null && !moduleId.equals(""))
if (!this.moduleId.contains(moduleId))
this.moduleId.add(moduleId);
}
public List getModuleId() {
return moduleId;
}
public void setModuleId(List moduleId) {
for (int i = 0; i < moduleId.size(); i++)
}
public Converter getModuleIdTreeConverter() {
return new Converter() {
public Object getAsObject(FacesContext context,
UIComponent component, String newValue)
throws ConverterException
public String getAsString(FacesContext context,
UIComponent component, Object value)
throws ConverterException
};
}
public void loadHost(ActionEvent event) {
/* Initializes data, when the user first clicks the edit button on a
host.
Loads both host data and modules. Modules are added using
the addModuleId(String) method. */
}
public String updateHostAction() {
CachingServiceLocator csl = CachingServiceLocator.getInstance();
HostLocal hostLocal = csl.lookupHostBean();
Integer[] moduleId = new Integer[this.moduleId.size()];
for (int i = 0; i < moduleId.length; i++)
try
{ hostLocal.updateHost(id, languageId, currencyId, moduleId, name, mail, address); } catch (UpdateException ue) {}
return "success";
}
ModuleBean:
private void addChildModules(TreeNode node, TOList modules) {
for (int i = 0; i < modules.getLimitedSize(); i++)
}
public TreeNode getModuleHierarchy() {
CachingServiceLocator csl = CachingServiceLocator.getInstance();
ModuleLocal ml = csl.lookupModuleBean();
TreeNode base = new TreeNodeBase("root", "ROOT", false);
addChildModules(base, ml.loadModuleHierarchy());
return base;
}