rich:tree - drag/drop rerendering
dipasab1 Dec 31, 2007 10:43 AMHi
I'am new at this forum and also to richfaces - now I'm faceing different problems with rich:tree. I have two trees with nested recursiveTreeNodesAdaptor and treeNodesAdaptors. I would like to drag a Node from one tree to the other one. After the DropListener has finished, both trees shuld be rerendered and reflecting the updated model.
My problems are:
1. The model is updated after the DropEvent - no skip to renderResponse
<rich:tree id="dropZone" ajaxSingle="true" immediate="true" bypassUpdates="true" switchType="client" toggleOnClick="true" dropListener="#{sysUserAdmin.addBusinessUnitUserRoleAssToSysUser}" eventsQueue="businessUnitUserRoleQueue" acceptedTypes="userRoleAssDragType" dropValue="#{userRoleAssDrag}" ondrop="$('hiddenDropIndicator').value = new Date();" style="float: left; height: 400px; overflow: auto;">
I have solved this problem by forcing FacesContext directly to renderResponse in my DropListener-Method. But it would be better to provide this declaratively. I tried out nearly every possible combination of attributes, but nothing seems to work. Why?
2. On different parts of my trees I have implemented the included and includedNode attributs. The Problem now is, that the trees are reRendered before the dropListener-Method is invoked - so the trees are not correctly reflecting the state of the bean. If I update the trees with <a4j:commandLink> everything is o.k. I tried to provide own reRender-Zones in the trees but the behaviour is the same.
3. When I use adviseNodeOpened (with Seam 2.0 GA) I get javax.faces.el.MethodNotFoundException see: http://jira.jboss.com/jira/browse/RF-1713
4. I get the following Errors in the Console
15:21:32,953 ERROR [STDERR] TreeRendererBase.encodeAjaxChildren()[businessUnitDrop_:0:childsDrop_:8:childsDrop_:0:childsDrop_:0]
15:21:37,250 WARN [Parameters] Parameters: Invalid chunk ignored.
My draggable treeNodes are definded like this:
<rich:treeNode id="userRoleAssesNodeDrop" dragIndicator=":userRoleIndicator" dragType="userRoleAssDropType" dragValue="#{userRoleAssDrop}" icon="img/ui/security/userRoles.gif" iconLeaf="img/ui/security/userRoles.gif"> <rich:dndParam name="label" value="(#{userRoleAssDrop.userRole.name}) #{userRoleAssDrop.userRole.description}"/> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li class="b" style="float: left; overflow: hidden;">#{userRoleAssDrop.userRole.name}</li> <li class="b" style="float: right; width: 250px; overflow: hidden;">#{userRoleAssDrop.userRole.description}</li> </ul> </rich:treeNode>
5. Without the Seam Annotation @Begin(join = true, flushMode = FlushModeType.MANUAL) on my dropListenener-Methods the PersistenceContext is flushed e.g. written to the database without explicite DAO.store command - is this the normal behaviour of EntityManager or a bug?
6. If I do not reRead the dropped Object from the Persistence Context I get LazsInitializing.... Exceptions - witch is strange with Seam.
@Begin(join = true, flushMode = FlushModeType.MANUAL) public void addBusinessUnitUserRoleAssToSysUser(DropEvent event) { if (event.getDragValue() != null) { BusinessUnitUserRoleAss buura = (BusinessUnitUserRoleAss) event.getDragValue(); buura = businessUnitUserRoleAssDAO.findById(buura.getId()); sysUser.addBusinessUnitUserRoleAss(buura); List<BusinessUnitUserRoleAss> dummy = new ArrayList<BusinessUnitUserRoleAss>(); dummy.add(buura); loadBusinessUnitsForAssignedUserRoleAss(dummy); FacesContext.getCurrentInstance().renderResponse(); // force skip of model update - see ms not to work with rich:tree! } }
Can anybody help me to solve this problems?
Currently I'am using JBoss Seam 2.0 GA, richfaces 3.1.2.SP1, jsf-1_2_06 RI with facelet.
There are the entire tree-definitions if you need more informations:
<fieldset style="width: 48%; clear: none; margin-right: 2%;"> <legend>Zugewiesene Benutzerrollen nach Geschaeftseinheiten</legend> <rich:tree id="dropZone" ajaxSingle="true" immediate="true" bypassUpdates="true" switchType="client" toggleOnClick="true" dropListener="#{sysUserAdmin.addBusinessUnitUserRoleAssToSysUser}" eventsQueue="businessUnitUserRoleQueue" acceptedTypes="userRoleAssDragType" dropValue="#{userRoleAssDrag}" ondrop="$('hiddenDropIndicator').value = new Date();" style="float: left; height: 400px; overflow: auto;"> <rich:treeNodesAdaptor id="businessUnitDrop" nodes="#{sysUserAdmin.businessUnitsAssigned}" var="roots"> <rich:treeNode id="businessUnitNodeDrop" icon="img/ui/security/rootBU.gif" iconLeaf="img/ui/security/rootBU.gif"> <h:outputText value="#{roots.description}"/> </rich:treeNode> <rich:recursiveTreeNodesAdaptor id="childsDrop" var="child" roots="#{roots.childBusinessUnitsAsList}" included="#{sysUserAdmin.hasAssignedBusinessUnitsWithUserRights(child)}" nodes="#{child.childBusinessUnitsAsList}"> <rich:treeNode id="childsNodeDrop" icon="img/ui/security/childBU.gif" iconLeaf="img/ui/security/childBU.gif"> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li style="float: left; overflow: hidden;">#{child.description}</li> <li style="float: right; width: 250px; overflow: hidden;">#{child.name}</li> </ul> </rich:treeNode> <rich:treeNodesAdaptor id="userRoleAssesDrop" var="userRoleAssDrop" includedNode="#{sysUserAdmin.hasUserRightForCurrentRole(userRoleAssDrop)}" nodes="#{child.businessUnitUserRoleAssAsList}"> <rich:treeNode id="userRoleAssesNodeDrop" dragIndicator=":userRoleIndicator" dragType="userRoleAssDropType" dragValue="#{userRoleAssDrop}" icon="img/ui/security/userRoles.gif" iconLeaf="img/ui/security/userRoles.gif"> <rich:dndParam name="label" value="(#{userRoleAssDrop.userRole.name}) #{userRoleAssDrop.userRole.description}"/> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li class="b" style="float: left; overflow: hidden;">#{userRoleAssDrop.userRole.name}</li> <li class="b" style="float: right; width: 250px; overflow: hidden;">#{userRoleAssDrop.userRole.description}</li> </ul> </rich:treeNode> <rich:treeNodesAdaptor id="serviceCompsDrop" var="serviceComp" nodes="#{userRoleAssDrop.serviceCompActionsAsList[0]}"> <rich:treeNode id="serviceCompsNodeDrop" icon="img/ui/security/serviceComp.gif" iconLeaf="img/ui/security/serviceComp.gif"> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li style="float: left; overflow: hidden;">#{serviceComp.serviceComp.name}</li> <li style="float: right; width: 250px; overflow: hidden;">#{serviceComp.serviceComp.description} (BusinessUnitUserRoleAss)</li> </ul> </rich:treeNode> <rich:treeNodesAdaptor id="serviceCompActionsDrop" var="serviceCompAc" nodes="#{serviceComp.serviceComp.serviceCompActions}"> <rich:treeNode id="serviceCompActionsNodeDrop" icon="img/ui/security/serviceCompAction.gif" iconLeaf="img/ui/security/serviceCompAction.gif"> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li style="float: left; overflow: hidden;">#{serviceCompAc.name}</li> <li style="float: right; width: 250px; overflow: hidden;">#{serviceCompAc.description}</li> </ul> </rich:treeNode> </rich:treeNodesAdaptor> </rich:treeNodesAdaptor> </rich:treeNodesAdaptor> </rich:recursiveTreeNodesAdaptor> </rich:treeNodesAdaptor> </rich:tree> </fieldset> <fieldset style="width: 48%"> <legend>Benutzerrollen nach Geschaeftseinheiten </legend> <rich:tree id="dragZone" ajaxSingle="true" immediate="true" bypassUpdates="true" switchType="client" toggleOnClick="true" dropListener="#{sysUserAdmin.removeBusinessUnitUserRoleAssToSysUser}" eventsQueue="businessUnitUserRoleQueue" acceptedTypes="userRoleAssDropType" dropValue="#{userRoleAssDrop}" ondrop="$('hiddenDropIndicator').value = new Date();" style="float: left; height: 400px; overflow: auto;"> <rich:treeNodesAdaptor id="businessUnitDrag" nodes="#{sysUserAdmin.businessUnits}" var="roots"> <rich:treeNode id="businessUnitNode" icon="img/ui/security/rootBU.gif" iconLeaf="img/ui/security/rootBU.gif"> <h:outputText value="#{roots.description}"/> </rich:treeNode> <rich:recursiveTreeNodesAdaptor id="businessUnitRecursionDrag" var="child" roots="#{roots.childBusinessUnitsAsList}" nodes="#{child.childBusinessUnitsAsList}"> <rich:treeNode id="businessUnitRecursionChildDrag" icon="img/ui/security/childBU.gif" iconLeaf="img/ui/security/childBU.gif"> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li style="float: left; overflow: hidden;">#{child.description}</li> <li style="float: right; width: 250px; overflow: hidden;">#{child.name}</li> </ul> </rich:treeNode> <rich:treeNodesAdaptor id="userRoleAsses" var="userRoleAssDrag" nodes="#{child.businessUnitUserRoleAssAsList}" includedNode="#{sysUserAdmin.hasUserRightForCurrentRole(userRoleAssDrag) eq false}"> <rich:treeNode id="userRoleAssesNodeDrag" dragIndicator=":userRoleIndicator" dragType="userRoleAssDragType" dragValue="#{userRoleAssDrag}" icon="img/ui/security/userRoles.gif" iconLeaf="img/ui/security/userRoles.gif"> <rich:dndParam name="label" value="(#{userRoleAssDrag.userRole.name}) #{userRoleAssDrag.userRole.description}"/> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li class="b" style="float: left; overflow: hidden;">#{userRoleAssDrag.userRole.name}</li> <li class="b" style="float: right; width: 250px; overflow: hidden;">#{userRoleAssDrag.userRole.description}</li> </ul> </rich:treeNode> <rich:treeNodesAdaptor id="serviceCompsDrag" var="serviceComp" nodes="#{userRoleAssDrag.serviceCompActionsAsList[0]}"> <rich:treeNode id="serviceCompNode" icon="img/ui/security/serviceComp.gif" iconLeaf="img/ui/security/serviceComp.gif"> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li style="float: left; overflow: hidden;">#{serviceComp.serviceComp.name}</li> <li style="float: right; width: 250px; overflow: hidden;">#{serviceComp.serviceComp.description} (BusinessUnitUserRoleAss)</li> </ul> </rich:treeNode> <rich:treeNodesAdaptor id="serviceCompActionsDrag" var="serviceCompAc" nodes="#{serviceComp.serviceComp.serviceCompActions}"> <rich:treeNode id="serviceCompActionsNodeDrag" icon="img/ui/security/serviceCompAction.gif" iconLeaf="img/ui/security/serviceCompAction.gif"> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li style="float: left; overflow: hidden;">#{serviceCompAc.name}</li> <li style="float: right; width: 250px; overflow: hidden;">#{serviceCompAc.description}</li> </ul> </rich:treeNode> </rich:treeNodesAdaptor> </rich:treeNodesAdaptor> <rich:treeNodesAdaptor id="serviceCompUserRoleDrag" var="serviceCompUserRole" nodes="#{userRoleAssDrag.userRole.serviceCompActionsAsList}"> <rich:treeNode id="serviceCompUserRoleNodeDrag" icon="img/ui/security/serviceComp.gif" iconLeaf="img/ui/security/serviceComp.gif"> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li style="float: left; overflow: hidden;">#{serviceCompUserRole.serviceComp.name}</li> <li style="float: right; width: 250px; overflow: hidden;">#{serviceCompUserRole.serviceComp.description} (UserRoleAss)</li> </ul> </rich:treeNode> <rich:treeNodesAdaptor id="serviceCompActionsUserRoleDrag" var="serviceCompAcUserRole" nodes="#{serviceCompUserRole.serviceComp.serviceCompActions}"> <rich:treeNode id="serviceCompActionsNodeUserRoleDrag" icon="img/ui/security/serviceCompAction.gif" iconLeaf="img/ui/security/serviceCompAction.gif"> <ul style="float: left; width: 100%; margin-bottom: 0;"> <li style="float: left; overflow: hidden;">#{serviceCompAcUserRole.name}</li> <li style="float: right; width: 250px; overflow: hidden;">#{serviceCompAcUserRole.description}</li> </ul> </rich:treeNode> </rich:treeNodesAdaptor> </rich:treeNodesAdaptor> </rich:treeNodesAdaptor> </rich:recursiveTreeNodesAdaptor> </rich:treeNodesAdaptor> </rich:tree> </fieldset>
and my dropListeneres:
@Begin(join = true, flushMode = FlushModeType.MANUAL) public void addBusinessUnitUserRoleAssToSysUser(DropEvent event) { if (event.getDragValue() != null) { BusinessUnitUserRoleAss buura = (BusinessUnitUserRoleAss) event.getDragValue(); buura = businessUnitUserRoleAssDAO.findById(buura.getId()); sysUser.addBusinessUnitUserRoleAss(buura); List<BusinessUnitUserRoleAss> dummy = new ArrayList<BusinessUnitUserRoleAss>(); dummy.add(buura); loadBusinessUnitsForAssignedUserRoleAss(dummy); FacesContext.getCurrentInstance().renderResponse(); // force skip of model update - seems not to work with rich:tree! } } @Begin(join = true, flushMode = FlushModeType.MANUAL) public void removeBusinessUnitUserRoleAssToSysUser(DropEvent event) { if (event.getDragValue() != null) { BusinessUnitUserRoleAss buura = (BusinessUnitUserRoleAss) event.getDragValue(); buura = businessUnitUserRoleAssDAO.findById(buura.getId()); sysUser.removeBusinessUnitUserRoleAss(buura); childBusinessUnitsAssigned = new HashSet<BusinessUnit>(); loadBusinessUnitsForAssignedUserRoleAss(sysUser.getBusinessUnitUserRoleAssAsList()); FacesContext.getCurrentInstance().renderResponse(); // force skip of model update - seems not to work with rich:tree ! } }
I thank you very much for your help.