Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <apex:component controller="HierarchyController" allowDML="true">
- <!-- a VF component for modifying the hierarchy of an SObject (Campaign,
- Account, etc.) using an ExtJS TreePanel -->
- <!-- Jeff Trull jetrull@sbcglobal.net 2010-12-01 -->
- <apex:attribute name="object" type="Object" description="sObject to edit hierarchy on"
- default="Campaign" />
- <apex:attribute name="fn" type="String" description="name of a Javascript function to call with ID once a Campaign is selected."
- required="false" default="" />
- <!-- load ExtJS -->
- <apex:stylesheet value="{!$Resource.ExtJS}/resources/css/ext-all.css"
- />
- <apex:includeScript value="{!$Resource.ExtJS}/adapter/ext/ext-base.js"
- />
- <apex:includeScript value="{!$Resource.ExtJS}/ext-all.js" />
- <script type="text/javascript">
- Ext.BLANK_IMAGE_URL = "{!$Resource.ExtJS}/resources/images/default/s.gif"
- </script>
- <!-- Create a JS function that calls the child object finding Apex method,
- -->
- <!-- then loads the results when the AJAX request returns -->
- <apex:actionFunction name="fetchObjects" action="{!findChildObjects}"
- rerender="unrollpanel" oncomplete="fetchCallback.call();">
- <apex:param name="sobjname" assignTo="{!fetchObject}" value="" />
- <apex:param name="parentid" assignTo="{!fetchParentId}" value="" />
- </apex:actionFunction>
- <!-- Define function returning child data. Function definition changes
- after reach AJAX response -->
- <!-- to contain the result of our child record search -->
- <apex:outputPanel id="unrollpanel">
- <!-- if not in an outputPanel, the rerender fails! -->
- <!-- A function that just takes the results from a single tree query and
- returns it -->
- <!-- regenerated after every tree node expansion and then called from
- the actionFunction's oncomplete -->
- <script type="text/javascript">
- function nodeResults(forceLeaf) {
- var loadData = new Array();
- // unroll child nodes list with apex:repeat
- // node properties: if level 5, a leaf (cannot have children)
- // if no children, show as folder, but without "expand" button
- // if has children, folder with expand button
- < apex: repeat value = "{!fetchResults}"
- var = "obj" > loadData.push({
- id: "{!obj.id}",
- text: "{!obj.name}",
- expanded: { !! obj.hasChildren
- },
- loaded: { !! obj.hasChildren
- },
- leaf: forceLeaf
- }); < /apex:repeat>
- return loadData;
- }
- </script>
- </apex:outputPanel>
- <!-- Create a JS function to call the Apex method that reassigns a record
- parent -->
- <apex:actionFunction name="updateParent" action="{!setParent}" rerender="setstatuspanel">
- <apex:param name="parent" assignTo="{!parentIdToSet}" value="" />
- <apex:param name="child" assignTo="{!childIdToSet}" value="" />
- </apex:actionFunction>
- <!-- a function regenerated by the parent ID set result after server completes
- -->
- <apex:outputPanel id="setstatuspanel">
- <script type="text/javascript">
- function getSetStatus() {
- return {
- !idSetSuccess
- };
- }
- </script>
- </apex:outputPanel>
- <script type="text/javascript">
- Ext.onReady(function() {
- var tree = new Ext.tree.TreePanel({
- renderTo: 'treediv',
- useArrows: true,
- autoScroll: true,
- animate: true,
- containerScroll: true,
- border: false,
- enableDD: true,
- loader: new Ext.tree.TreeLoader({
- directFn: function(loadid, callback) {
- // determine if we are expanding a level 4 record (current limit is 5 -> leaf)
- var lvl4 = (tree.getNodeById(loadid).getDepth() >= 4);
- // establish callback for when AJAX request completes
- fetchCallback = function() {
- callback.apply(window, [nodeResults(lvl4),
- {
- status: true
- }]);
- }.createDelegate(this);
- // call actionFunction created for loading
- fetchObjects('{!object}', loadid);
- }
- }),
- root: new Ext.tree.AsyncTreeNode({
- text: 'All {!object}s',
- expanded: false,
- draggable: false,
- id: 'root' // because you cannot use a blank id (Ext would create one)
- }),
- listeners: {
- beforemovenode: function(tree, node, oldParent, newParent) {
- if (oldParent.id == newParent.id) {
- // just a change to ordering; no need for server request
- return true;
- }
- var parent = newParent.id;
- if (parent == 'root') {
- parent = ''; // translate back into Apex world
- }
- // this is, unfortunately, a synchronous approach
- updateParent(parent, node.id);
- // if level has changed to/from L5, adjust "leaf" property
- if ((oldParent.getDepth() == 4) || (newParent.getDepth() == 4)) {
- node.leaf = (newParent.getDepth() == 4);
- }
- return true;
- },
- movenode: function(tree, node, oldParent, newParent) {
- // TreePanel automatically shows nodes without children as leafs
- // it will also automatically change those leafs into folders when another
- // node is dropped on them. However, it will not change the folders back
- // into leaf icons when the last child is removed. This is a workaround.
- if (!oldParent.hasChildNodes()) {
- oldParent.getUI().removeClass("x-tree-node-collapsed");
- oldParent.getUI().addClass("x-tree-node-leaf");
- }
- },
- beforedblclick: function(node) {
- if (('{!fn}' != '') && (node.id != 'root')) {
- {
- !fn
- }(node.id);
- }
- }
- }
- });
- tree.getRootNode().expand(); // trigger load of top level objects
- });
- </script>
- <div id="treediv" />
- </apex:component>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement