mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 06:05:56 +00:00
FEATURE Replacing custom tree.js with jstree thirdparty library
This commit is contained in:
parent
fe126e1a23
commit
2d85a4596b
@ -247,8 +247,8 @@ class LeftAndMain extends Controller {
|
|||||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/scriptaculous/dragdrop.js');
|
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/scriptaculous/dragdrop.js');
|
||||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/scriptaculous/controls.js');
|
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/scriptaculous/controls.js');
|
||||||
|
|
||||||
Requirements::javascript(THIRDPARTY_DIR . '/tree/tree.js');
|
Requirements::javascript(THIRDPARTY_DIR . '/jstree/jquery.jstree.js');
|
||||||
Requirements::css(THIRDPARTY_DIR . '/tree/tree.css');
|
Requirements::css(THIRDPARTY_DIR . '/jstree/themes/default/style.css');
|
||||||
|
|
||||||
Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.js');
|
Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.js');
|
||||||
Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.Tree.js');
|
Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.Tree.js');
|
||||||
@ -299,8 +299,8 @@ class LeftAndMain extends Controller {
|
|||||||
'sapphire/thirdparty/scriptaculous/dragdrop.js',
|
'sapphire/thirdparty/scriptaculous/dragdrop.js',
|
||||||
'sapphire/thirdparty/scriptaculous/controls.js',
|
'sapphire/thirdparty/scriptaculous/controls.js',
|
||||||
'cms/javascript/LeftAndMain.js',
|
'cms/javascript/LeftAndMain.js',
|
||||||
'sapphire/javascript/tree/tree.js',
|
'sapphire/thirdparty/jstree/jquery.jstree.js',
|
||||||
'sapphire/javascript/TreeSelectorField.js',
|
'sapphire/javascript/TreeDropdownField.js',
|
||||||
'cms/javascript/ThumbnailStripField.js',
|
'cms/javascript/ThumbnailStripField.js',
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -523,7 +523,7 @@ class LeftAndMain extends Controller {
|
|||||||
|
|
||||||
// getChildrenAsUL is a flexible and complex way of traversing the tree
|
// getChildrenAsUL is a flexible and complex way of traversing the tree
|
||||||
$titleEval = '
|
$titleEval = '
|
||||||
"<li id=\"record-$child->ID\" class=\"" . $child->CMSTreeClasses($extraArg) . "\">" .
|
"<li id=\"record-$child->ID\" data-id=\"$child->ID\" class=\"" . $child->CMSTreeClasses($extraArg) . "\">" .
|
||||||
"<a href=\"" . Controller::join_links(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" class=\"" . $child->CMSTreeClasses($extraArg) . "\" title=\"'
|
"<a href=\"" . Controller::join_links(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" class=\"" . $child->CMSTreeClasses($extraArg) . "\" title=\"'
|
||||||
. _t('LeftAndMain.PAGETYPE','Page type: ')
|
. _t('LeftAndMain.PAGETYPE','Page type: ')
|
||||||
. '".$child->class."\" >" . ($child->TreeTitle) .
|
. '".$child->class."\" >" . ($child->TreeTitle) .
|
||||||
|
@ -2,650 +2,689 @@
|
|||||||
* File: LeftAndMain.Tree.js
|
* File: LeftAndMain.Tree.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* LeftAndMain_left.js
|
|
||||||
* Code for supporting the left-hand panel of all the 2-pane admin windows
|
|
||||||
* This includes code for the action panel at the top, and the draggable, ajax-linked tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(typeof SiteTreeHandlers == 'undefined') SiteTreeHandlers = {};
|
|
||||||
SiteTreeHandlers.parentChanged_url = 'admin/ajaxupdateparent';
|
|
||||||
SiteTreeHandlers.orderChanged_url = 'admin/ajaxupdatesort';
|
|
||||||
SiteTreeHandlers.showRecord_url = 'admin/show/';
|
|
||||||
SiteTreeHandlers.controller_url = 'admin';
|
|
||||||
|
|
||||||
var _HANDLER_FORMS = {
|
|
||||||
addpage : 'Form_AddForm',
|
|
||||||
batchactions : 'batchactionsforms',
|
|
||||||
search : 'search_options'
|
|
||||||
};
|
|
||||||
|
|
||||||
(function($) {
|
(function($) {
|
||||||
$(window).bind('load', function(e) {
|
$(document).ready(function() {
|
||||||
// behaviour.js load handlers need to be fired before this event, so we artificially delay it
|
$('#sitetree_ul').jstree({
|
||||||
setTimeout(function() {
|
'core': {
|
||||||
// make sure current ID of loaded form is actually selected in tree
|
'initially_open': ['record-0']
|
||||||
var tree = $('#sitetree')[0], id = $('#Form_EditForm :input[name=ID]').val();
|
|
||||||
if(!id) id = 0;
|
|
||||||
if(tree) tree.setCurrentByIdx(id);
|
|
||||||
}, 200);
|
|
||||||
});
|
|
||||||
}(jQuery));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overload this with a real context menu if necessary
|
|
||||||
*/
|
|
||||||
var TreeContextMenu = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class: TreeAPI
|
|
||||||
*
|
|
||||||
* Extra methods for the tree when used in the LHS of the CMS
|
|
||||||
*/
|
|
||||||
TreeAPI = Class.create();
|
|
||||||
TreeAPI.prototype = {
|
|
||||||
|
|
||||||
setCustomURL: function(url, arguments) {
|
|
||||||
this.customURL = url;
|
|
||||||
this.customArguments = $H(arguments);
|
|
||||||
},
|
},
|
||||||
|
'html_data': {
|
||||||
clearCustomURL: function() {
|
// TODO Hack to avoid ajax load on init, see http://code.google.com/p/jstree/issues/detail?id=911
|
||||||
this.customURL = this.customArguments = null;
|
'data': $('#sitetree_ul').html(),
|
||||||
},
|
'ajax': {
|
||||||
|
'url': 'admin/getsubtree',
|
||||||
url: function(args) {
|
'data': function(node) {
|
||||||
var args = $H(args).merge(this.customArguments);
|
return { ID : $(node).data("id") ? $(node).data("id") : 0 , ajax: 1};
|
||||||
|
|
||||||
var url = this.customURL ? this.customURL : SiteTreeHandlers.loadTree_url;
|
|
||||||
url = url + (url.match(/\?/) ? '&' : '?') + args.toQueryString();
|
|
||||||
|
|
||||||
return url;
|
|
||||||
},
|
|
||||||
|
|
||||||
reload: function(options) {
|
|
||||||
this.innerHTML = 'Loading...';
|
|
||||||
|
|
||||||
var args = {ajax:1, ID:0};
|
|
||||||
if ($('LangSelector')) args.locale = $('LangSelector').value;
|
|
||||||
|
|
||||||
var url = this.url(args);
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
jQuery.get(
|
|
||||||
url,
|
|
||||||
function(data, status){
|
|
||||||
self.innerHTML = data;
|
|
||||||
self.castAsTreeNode(self.firstChild);
|
|
||||||
if (options && options.onSuccess) options.onSuccess(data);
|
|
||||||
},
|
|
||||||
'html'
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform the given code on the each tree node with the given index.
|
|
||||||
* There could be more than one :-)
|
|
||||||
* @param idx The index of the tree node
|
|
||||||
* @param code A method to be executed, that will be passed the tree node
|
|
||||||
*/
|
|
||||||
performOnTreeNode: function(idx, code) {
|
|
||||||
var treeNode = this.getTreeNodeByIdx(idx);
|
|
||||||
if(!treeNode) return;
|
|
||||||
|
|
||||||
if(treeNode.className.indexOf('manyparents') == -1) {
|
|
||||||
code(treeNode);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
var i,item,allNodes = this.getElementsByTagName('li');
|
|
||||||
for(i=0;item=allNodes[i];i++) {
|
|
||||||
if(treeNode.id == item.id) code(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'ui': {
|
||||||
getTreeNodeByIdx : function(idx) {
|
"select_limit" : 1,
|
||||||
if(!idx) idx = "0";
|
'initially_select': [$('#sitetree_ul').find('.current').attr('id')]
|
||||||
var node = document.getElementById('record-' + idx);
|
|
||||||
if(idx == "0" && !node) node = document.getElementById('record-root');
|
|
||||||
return node;
|
|
||||||
},
|
},
|
||||||
getIdxOf : function(treeNode) {
|
'plugins': ['themes', 'html_data', 'ui']
|
||||||
if(treeNode && treeNode.id && treeNode.id.match(/record-([0-9a-zA-Z\-]+)$/))
|
|
||||||
return RegExp.$1;
|
|
||||||
},
|
|
||||||
createTreeNode : function(idx, title, pageType) {
|
|
||||||
var i;
|
|
||||||
var node = document.createElement('li');
|
|
||||||
node.id = 'record-' + idx;
|
|
||||||
node.className = pageType;
|
|
||||||
|
|
||||||
var aTag = document.createElement('a');
|
|
||||||
aTag.href = SiteTreeHandlers.showRecord_url + idx;
|
|
||||||
aTag.title = 'Page type: ' + pageType;
|
|
||||||
aTag.innerHTML = title;
|
|
||||||
node.appendChild(aTag);
|
|
||||||
|
|
||||||
SiteTreeNode.create(node, this.options);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
},
|
|
||||||
|
|
||||||
setNodeIdx : function(idx, newIdx) {
|
|
||||||
this.performOnTreeNode(idx, function(treeNode) {
|
|
||||||
treeNode.id = 'record-' + newIdx;
|
|
||||||
var aTag = treeNode.getElementsByTagName('a')[0];
|
|
||||||
aTag.href = aTag.href.replace(idx, newIdx);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var treeNode = this.getTreeNodeByIdx(idx);
|
$('#sitetree_ul').bind('select_node.jstree', function(e, data) {
|
||||||
},
|
var node = data.rslt.obj;
|
||||||
|
var url = $(node).find('a:first').attr('href');
|
||||||
setNodeTitle : function(idx, title) {
|
|
||||||
this.performOnTreeNode(idx, function(treeNode) {
|
|
||||||
var aTag = treeNode.getElementsByTagName('a')[0];
|
|
||||||
aTag.innerHTML = title;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
setNodeIcon: function(idx, newClassName) {
|
|
||||||
this.performOnTreeNode(idx, function(treeNode) {
|
|
||||||
treeNode.className = treeNode.className.replace(/(class-)[^\s]*/,'$1' + newClassName);
|
|
||||||
treeNode.aSpan.className = 'a ' + treeNode.className.replace('closed','spanClosed');
|
|
||||||
var aTag = treeNode.getElementsByTagName('a')[0];
|
|
||||||
aTag.title = 'Page type: ' + newClassName;
|
|
||||||
treeNode.setIconByClass();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the parent ID of a tree node
|
|
||||||
*/
|
|
||||||
setNodeParentID: function (idx, parentID) {
|
|
||||||
var treeNode = this.getTreeNodeByIdx(idx);
|
|
||||||
var parentNode = this.getTreeNodeByIdx(parentID);
|
|
||||||
var currentParentNode = jQuery(treeNode).parents('li')[0];
|
|
||||||
// Only change parent node if its different than the current,
|
|
||||||
// otherwise we affect the sort order unnecessarily due to
|
|
||||||
// appendTreeNode() not looking at existing sorts
|
|
||||||
if(!currentParentNode || parentNode != currentParentNode) parentNode.appendTreeNode(treeNode);
|
|
||||||
},
|
|
||||||
|
|
||||||
setCurrentByIdx : function(idx) {
|
|
||||||
if(this.selected) {
|
|
||||||
var i,item;
|
|
||||||
for(i=0;item=this.selected[i];i++) {
|
|
||||||
item.removeNodeClass('current');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__tree = this;
|
|
||||||
__tree.selected = [];
|
|
||||||
|
|
||||||
this.performOnTreeNode(idx, function(treeNode) {
|
|
||||||
__tree.selected.push(treeNode);
|
|
||||||
treeNode.expose();
|
|
||||||
treeNode.addNodeClass('current');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
changeCurrentTo : function(newNode) {
|
|
||||||
if(this.selected) {
|
|
||||||
var i,item;
|
|
||||||
for(i=0;item=this.selected[i];i++) {
|
|
||||||
item.removeNodeClass('current');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newNode.addNodeClass('current');
|
|
||||||
|
|
||||||
this.selected = [newNode];
|
|
||||||
newNode.expose();
|
|
||||||
},
|
|
||||||
|
|
||||||
firstSelected : function() {
|
|
||||||
if(this.selected) return this.selected[0];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extra methods for the tree node when used in the LHS of the CMS
|
|
||||||
*/
|
|
||||||
TreeNodeAPI = Class.create();
|
|
||||||
TreeNodeAPI.prototype = {
|
|
||||||
selectTreeNode : function() {
|
|
||||||
var url = jQuery(this).find('a').attr('href');
|
|
||||||
if(url && url != '#') {
|
if(url && url != '#') {
|
||||||
jQuery('#sitetree').trigger('selectionchanged', {node: this});
|
var xmlhttp = $('#Form_EditForm').entwine('ss').loadForm(
|
||||||
// don't get page if either event was cancelled,
|
url,
|
||||||
// or the tree is currently in a selectable state.
|
function(response) {}
|
||||||
if($('sitetree').notify('SelectionChanged', this) && !jQuery(this.tree).hasClass('multiselect')) {
|
);
|
||||||
this.getPageFromServer();
|
|
||||||
}
|
// TODO Mark node as loading
|
||||||
|
// if(xmlhttp) this.addNodeClass('loading');
|
||||||
} else {
|
} else {
|
||||||
jQuery('#Form_EditForm').entwine('ss').removeForm();
|
jQuery('#Form_EditForm').entwine('ss').removeForm();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
getPageFromServer : function() {
|
|
||||||
var self = this;
|
|
||||||
var xmlhttp = jQuery('#Form_EditForm').entwine('ss').loadForm(
|
|
||||||
jQuery(this).find('a').attr('href'),
|
|
||||||
function(response) {
|
|
||||||
self.removeNodeClass('loading');
|
|
||||||
|
|
||||||
var pageID = jQuery(this).find(':input[name=ID]').val();
|
|
||||||
jQuery('#sitetree')[0].setCurrentByIdx(pageID);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if(xmlhttp) this.addNodeClass('loading');
|
|
||||||
},
|
|
||||||
ajaxExpansion : function() {
|
|
||||||
this.addNodeClass('loading');
|
|
||||||
var ul = this.treeNodeHolder(false);
|
|
||||||
ul.innerHTML = 'loading...';
|
|
||||||
|
|
||||||
// Any attempts to add children to this page should, in fact, cue them up for insertion later
|
|
||||||
ul.cuedNewNodes = [];
|
|
||||||
ul.appendTreeNode = function(node) {
|
|
||||||
this.cuedNewNodes[this.cuedNewNodes.length] = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
var args = {ajax:1, ID:this.getIdx()};
|
|
||||||
|
|
||||||
// Add current locale for any subtree selection
|
|
||||||
if ($('LangSelector')) args.locale = $('LangSelector').value;
|
|
||||||
|
|
||||||
// If the tree is selectable, we have to show all available children without
|
|
||||||
// artificial limitations from the serverside (minNodeCount). This is a measure
|
|
||||||
// to ensure no unexpanded nodes are missed in batch selection
|
|
||||||
if(Element.hasClassName('sitetree', 'multiselect')) args.minNodeCount = 0;
|
|
||||||
|
|
||||||
url = this.tree.url(args);
|
|
||||||
|
|
||||||
new Ajax.Request(url, {
|
|
||||||
onSuccess : this.installSubtree.bind(this),
|
|
||||||
onFailure : this.showSubtreeLoadingError
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
showSubtreeLoadingError: function(response) {
|
|
||||||
errorMessage('error loading subtree', response);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Context menu
|
|
||||||
*/
|
|
||||||
oncontextmenu: function(event) {
|
|
||||||
if(TreeContextMenu) {
|
|
||||||
if(!event) event = window.event;
|
|
||||||
createContextMenu(event, this, TreeContextMenu);
|
|
||||||
Event.stop(event);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
duplicatePage: function() {
|
|
||||||
// Pass the parent ID to the duplicator, which helps ensure that multi-parent pages are duplicated into the node that the user clicked
|
|
||||||
var parentClause = "";
|
|
||||||
if(this.parentTreeNode && this.parentTreeNode.getIdx) {
|
|
||||||
parentClause = "&parentID=" + this.parentTreeNode.getIdx();
|
|
||||||
}
|
|
||||||
|
|
||||||
new Ajax.Request(jQuery('base').attr('href') + 'admin/duplicate/' + this.getIdx() + '?ajax=1' + parentClause, {
|
|
||||||
method : 'get',
|
|
||||||
onSuccess : Ajax.Evaluator,
|
|
||||||
onFailure : function(response) {
|
|
||||||
errorMessage('Error: ', response);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
duplicatePageWithChildren: function() {
|
}(jQuery));
|
||||||
new Ajax.Request(jQuery('base').attr('href') + 'admin/duplicatewithchildren/' + this.getIdx() + '?ajax=1', {
|
|
||||||
method : 'get',
|
|
||||||
onSuccess : Ajax.Evaluator,
|
|
||||||
onFailure : function(response) {
|
|
||||||
errorMessage('Error: ', response);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// if(typeof SiteTreeHandlers == 'undefined') SiteTreeHandlers = {};
|
||||||
/**
|
// SiteTreeHandlers.parentChanged_url = 'admin/ajaxupdateparent';
|
||||||
* In the case of Tree & DraggableTree, the root tree and the sub-trees all use the same class.
|
// SiteTreeHandlers.orderChanged_url = 'admin/ajaxupdatesort';
|
||||||
* In this case, however, SiteTree has a much bigger API and so SiteSubTree is smaller.
|
// SiteTreeHandlers.showRecord_url = 'admin/show/';
|
||||||
*/
|
// SiteTreeHandlers.controller_url = 'admin';
|
||||||
SiteSubTree = Class.extend('Tree').extend('TreeAPI');
|
//
|
||||||
SiteSubTree.prototype = {
|
// var _HANDLER_FORMS = {
|
||||||
castAsTreeNode: function(li) {
|
// addpage : 'Form_AddForm',
|
||||||
behaveAs(li, SiteTreeNode, this.options);
|
// batchactions : 'batchactionsforms',
|
||||||
}
|
// search : 'search_options'
|
||||||
}
|
// };
|
||||||
|
//
|
||||||
|
// (function($) {
|
||||||
/**
|
// $(window).bind('load', function(e) {
|
||||||
* Our SiteTree class extends the tree object with a richer manipulation API.
|
// // behaviour.js load handlers need to be fired before this event, so we artificially delay it
|
||||||
* The server will send a piece javascript that uses these functions. In this way, the server
|
// setTimeout(function() {
|
||||||
* has flexibility over its operation, but the Script->HTML interface is kept client-side.
|
// // make sure current ID of loaded form is actually selected in tree
|
||||||
*/
|
// var tree = $('#sitetree')[0], id = $('#Form_EditForm :input[name=ID]').val();
|
||||||
SiteTree = Class.extend('SiteSubTree');
|
// if(!id) id = 0;
|
||||||
SiteTree.prototype = {
|
// if(tree) tree.setCurrentByIdx(id);
|
||||||
initialize : function() {
|
// }, 200);
|
||||||
this.Tree.initialize();
|
// });
|
||||||
|
// }(jQuery));
|
||||||
/*
|
//
|
||||||
if(!this.tree.selected) this.tree.selected = [];
|
// /**
|
||||||
var els = this.getElementsByTagName('li');
|
// * Overload this with a real context menu if necessary
|
||||||
for(var i=0;i<els.length;i++) if(els[i].className.indexOf('current') > -1) {
|
// */
|
||||||
this.tree.selected.push(els[i]);
|
// var TreeContextMenu = null;
|
||||||
break;
|
//
|
||||||
}
|
// /**
|
||||||
*/
|
// * Class: TreeAPI
|
||||||
|
// *
|
||||||
this.observeMethod('SelectionChanged', this.interruptLoading.bind(this) );
|
// * Extra methods for the tree when used in the LHS of the CMS
|
||||||
|
// */
|
||||||
jQuery('#Form_EditForm').bind('loadnewpage', this.onLoadNewPage.bind(this));
|
// TreeAPI = Class.create();
|
||||||
},
|
// TreeAPI.prototype = {
|
||||||
destroy: function () {
|
//
|
||||||
if(this.Tree) this.Tree.destroy();
|
// setCustomURL: function(url, arguments) {
|
||||||
this.Tree = null;
|
// this.customURL = url;
|
||||||
this.SiteSubTree = null;
|
// this.customArguments = $H(arguments);
|
||||||
this.TreeAPI = null;
|
// },
|
||||||
this.selected = null;
|
//
|
||||||
},
|
// clearCustomURL: function() {
|
||||||
|
// this.customURL = this.customArguments = null;
|
||||||
/**
|
// },
|
||||||
* Stop the currently loading node from loading.
|
//
|
||||||
*/
|
// url: function(args) {
|
||||||
interruptLoading: function( newLoadingNode ) {
|
// var args = $H(args).merge(this.customArguments);
|
||||||
if( this.loadingNode ) this.loadingNode.removeNodeClass('loading');
|
//
|
||||||
this.loadingNode = newLoadingNode;
|
// var url = this.customURL ? this.customURL : SiteTreeHandlers.loadTree_url;
|
||||||
},
|
// url = url + (url.match(/\?/) ? '&' : '?') + args.toQueryString();
|
||||||
|
//
|
||||||
/**
|
// return url;
|
||||||
* Assumes to be triggered by a form element with the following input fields:
|
// },
|
||||||
* ID, ParentID, TreeTitle (or Title), ClassName
|
//
|
||||||
*/
|
// reload: function(options) {
|
||||||
onLoadNewPage: function(e, eventData) {
|
// this.innerHTML = 'Loading...';
|
||||||
// finds a certain value in an array generated by jQuery.serializeArray()
|
//
|
||||||
var findInSerializedArray = function(arr, name) {
|
// var args = {ajax:1, ID:0};
|
||||||
for(var i=0; i<arr.length; i++) {
|
// if ($('LangSelector')) args.locale = $('LangSelector').value;
|
||||||
if(arr[i].name == name) return arr[i].value;
|
//
|
||||||
};
|
// var url = this.url(args);
|
||||||
return false;
|
//
|
||||||
};
|
// var self = this;
|
||||||
|
// jQuery.get(
|
||||||
var id = jQuery(e.target.ID).val();
|
// url,
|
||||||
|
// function(data, status){
|
||||||
// check if a form with a valid ID exists
|
// self.innerHTML = data;
|
||||||
if(id) {
|
// self.castAsTreeNode(self.firstChild);
|
||||||
var parentID = jQuery(e.target.ParentID).val();
|
// if (options && options.onSuccess) options.onSuccess(data);
|
||||||
|
// },
|
||||||
// set title (either from TreeTitle or from Title fields)
|
// 'html'
|
||||||
// Treetitle has special HTML formatting to denote the status changes.
|
// );
|
||||||
var title = jQuery((e.target.TreeTitle) ? e.target.TreeTitle : e.target.Title).val();
|
// },
|
||||||
if(title) this.setNodeTitle(id, title);
|
//
|
||||||
|
// /**
|
||||||
// update icon (only if it has changed)
|
// * Perform the given code on the each tree node with the given index.
|
||||||
var className = jQuery(e.target.ClassName).val();
|
// * There could be more than one :-)
|
||||||
if(className) this.setNodeIcon(id, className);
|
// * @param idx The index of the tree node
|
||||||
|
// * @param code A method to be executed, that will be passed the tree node
|
||||||
// check if node exists, might have been created instead
|
// */
|
||||||
if(!this.getTreeNodeByIdx(id)) {
|
// performOnTreeNode: function(idx, code) {
|
||||||
var newNode = $('sitetree').createTreeNode(id, title, className);
|
// var treeNode = this.getTreeNodeByIdx(idx);
|
||||||
var parentNode = $('sitetree').getTreeNodeByIdx(parentID);
|
// if(!treeNode) return;
|
||||||
if(parentNode) parentNode.appendTreeNode(newNode);
|
//
|
||||||
//newNode.selectTreeNode();
|
// if(treeNode.className.indexOf('manyparents') == -1) {
|
||||||
}
|
// code(treeNode);
|
||||||
|
//
|
||||||
// set correct parent (only if it has changed)
|
// } else {
|
||||||
if(parentID) this.setNodeParentID(id, jQuery(e.target.ParentID).val());
|
// var i,item,allNodes = this.getElementsByTagName('li');
|
||||||
|
// for(i=0;item=allNodes[i];i++) {
|
||||||
// set current tree element
|
// if(treeNode.id == item.id) code(item);
|
||||||
this.setCurrentByIdx(id);
|
// }
|
||||||
} else {
|
// }
|
||||||
if(typeof eventData.origData != 'undefined') {
|
// },
|
||||||
var node = this.getTreeNodeByIdx(eventData.origData.ID);
|
//
|
||||||
if(node && node.parentTreeNode) node.parentTreeNode.removeTreeNode(node);
|
// getTreeNodeByIdx : function(idx) {
|
||||||
}
|
// if(!idx) idx = "0";
|
||||||
}
|
// var node = document.getElementById('record-' + idx);
|
||||||
|
// if(idx == "0" && !node) node = document.getElementById('record-root');
|
||||||
}
|
// return node;
|
||||||
}
|
// },
|
||||||
|
// getIdxOf : function(treeNode) {
|
||||||
SiteTreeNode = Class.extend('TreeNode').extend('TreeNodeAPI');
|
// if(treeNode && treeNode.id && treeNode.id.match(/record-([0-9a-zA-Z\-]+)$/))
|
||||||
SiteTreeNode.prototype = {
|
// return RegExp.$1;
|
||||||
initialize: function(options) {
|
// },
|
||||||
this.TreeNode.initialize(options);
|
// createTreeNode : function(idx, title, pageType) {
|
||||||
if(this.className && this.className.match(/class\-([^\s]*)/)) {
|
// var i;
|
||||||
var klass = RegExp.$1;
|
// var node = document.createElement('li');
|
||||||
if(typeof siteTreeHints != 'undefined' && siteTreeHints[klass]) {
|
// node.id = 'record-' + idx;
|
||||||
this.hints = siteTreeHints[klass];
|
// node.className = pageType;
|
||||||
this.dropperOptions = {
|
//
|
||||||
accept : (this.hints.allowedChildren && (this.className.indexOf('nochildren') == -1))
|
// var aTag = document.createElement('a');
|
||||||
? this.hints.allowedChildren : 'none'
|
// aTag.href = SiteTreeHandlers.showRecord_url + idx;
|
||||||
};
|
// aTag.title = 'Page type: ' + pageType;
|
||||||
}
|
// aTag.innerHTML = title;
|
||||||
}
|
// node.appendChild(aTag);
|
||||||
|
//
|
||||||
if(this.className.indexOf('current') > -1) {
|
// SiteTreeNode.create(node, this.options);
|
||||||
if(!this.tree.selected) this.tree.selected = [];
|
//
|
||||||
this.tree.selected.push(this);
|
// return node;
|
||||||
}
|
// },
|
||||||
|
//
|
||||||
if(!this.hints) this.hints = {}
|
// setNodeIdx : function(idx, newIdx) {
|
||||||
},
|
// this.performOnTreeNode(idx, function(treeNode) {
|
||||||
|
// treeNode.id = 'record-' + newIdx;
|
||||||
destroy: function () {
|
// var aTag = treeNode.getElementsByTagName('a')[0];
|
||||||
if(this.TreeNode) this.TreeNode.destroy();
|
// aTag.href = aTag.href.replace(idx, newIdx);
|
||||||
this.TreeNode = null;
|
// });
|
||||||
this.TreeNodeAPI = null;
|
//
|
||||||
},
|
// var treeNode = this.getTreeNodeByIdx(idx);
|
||||||
|
// },
|
||||||
castAsTree: function(childUL) {
|
//
|
||||||
behaveAs(childUL, SiteSubTree, this.options);
|
// setNodeTitle : function(idx, title) {
|
||||||
if(this.draggableObj) childUL.makeDraggable();
|
// this.performOnTreeNode(idx, function(treeNode) {
|
||||||
},
|
// var aTag = treeNode.getElementsByTagName('a')[0];
|
||||||
|
// aTag.innerHTML = title;
|
||||||
onselect: function() {
|
// });
|
||||||
this.selectTreeNode();
|
// },
|
||||||
return false;
|
//
|
||||||
},
|
// setNodeIcon: function(idx, newClassName) {
|
||||||
|
// this.performOnTreeNode(idx, function(treeNode) {
|
||||||
|
// treeNode.className = treeNode.className.replace(/(class-)[^\s]*/,'$1' + newClassName);
|
||||||
|
// treeNode.aSpan.className = 'a ' + treeNode.className.replace('closed','spanClosed');
|
||||||
/**
|
// var aTag = treeNode.getElementsByTagName('a')[0];
|
||||||
* Drag'n'drop handlers - Ajax saving
|
// aTag.title = 'Page type: ' + newClassName;
|
||||||
*/
|
// treeNode.setIconByClass();
|
||||||
onParentChanged : function(node, oldParent, newParent) {
|
// });
|
||||||
var self = this;
|
// },
|
||||||
|
//
|
||||||
if(newParent.id.match(/^record-new/)) {
|
// /**
|
||||||
alert("You must save the page before dragging children into it");
|
// * Set the parent ID of a tree node
|
||||||
return false;
|
// */
|
||||||
}
|
// setNodeParentID: function (idx, parentID) {
|
||||||
|
// var treeNode = this.getTreeNodeByIdx(idx);
|
||||||
if( node == newParent || node.getIdx() == newParent.getIdx() ) {
|
// var parentNode = this.getTreeNodeByIdx(parentID);
|
||||||
alert("You cannot add a page to itself");
|
// var currentParentNode = jQuery(treeNode).parents('li')[0];
|
||||||
return false;
|
// // Only change parent node if its different than the current,
|
||||||
}
|
// // otherwise we affect the sort order unnecessarily due to
|
||||||
|
// // appendTreeNode() not looking at existing sorts
|
||||||
if(node.innerHTML.toLowerCase().indexOf('<del') > -1) {
|
// if(!currentParentNode || parentNode != currentParentNode) parentNode.appendTreeNode(treeNode);
|
||||||
alert("You can't moved deleted pages");
|
// },
|
||||||
return false;
|
//
|
||||||
}
|
// setCurrentByIdx : function(idx) {
|
||||||
|
// if(this.selected) {
|
||||||
if( Element.hasClassName( newParent, 'nochildren' ) ) {
|
// var i,item;
|
||||||
alert("You can't add children to that node");
|
// for(i=0;item=this.selected[i];i++) {
|
||||||
return false;
|
// item.removeNodeClass('current');
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
jQuery.post(
|
//
|
||||||
SiteTreeHandlers.parentChanged_url,
|
// __tree = this;
|
||||||
'ID=' + node.getIdx() + '&ParentID=' + newParent.getIdx(),
|
// __tree.selected = [];
|
||||||
function(data, status) {
|
//
|
||||||
// TODO This should use a more common serialization in a new tree library
|
// this.performOnTreeNode(idx, function(treeNode) {
|
||||||
if(data.modified) {
|
// __tree.selected.push(treeNode);
|
||||||
for(var id in data.modified) {
|
// treeNode.expose();
|
||||||
self.tree.setNodeTitle(id, data.modified[id]['TreeTitle']);
|
// treeNode.addNodeClass('current');
|
||||||
}
|
// });
|
||||||
}
|
// },
|
||||||
|
//
|
||||||
// Check if current page still exists, and refresh it.
|
// changeCurrentTo : function(newNode) {
|
||||||
// Otherwise remove the current form
|
// if(this.selected) {
|
||||||
var selectedNode = self.tree.firstSelected();
|
// var i,item;
|
||||||
if(selectedNode) {
|
// for(i=0;item=this.selected[i];i++) {
|
||||||
var selectedNodeId = self.tree.getIdxOf(selectedNode);
|
// item.removeNodeClass('current');
|
||||||
if(data.modified[selectedNode.getIdx()]) {
|
// }
|
||||||
// only if the current page was modified
|
// }
|
||||||
selectedNode.selectTreeNode();
|
//
|
||||||
}
|
// newNode.addNodeClass('current');
|
||||||
}
|
//
|
||||||
},
|
// this.selected = [newNode];
|
||||||
'json'
|
// newNode.expose();
|
||||||
);
|
// },
|
||||||
|
//
|
||||||
return true;
|
// firstSelected : function() {
|
||||||
},
|
// if(this.selected) return this.selected[0];
|
||||||
|
// }
|
||||||
/**
|
// };
|
||||||
* Called when the tree has been resorted
|
//
|
||||||
* nodeList is a list of all the nodes in the correct rder
|
// /**
|
||||||
* movedNode is the node that actually got moved to trigger this resorting
|
// * Extra methods for the tree node when used in the LHS of the CMS
|
||||||
*/
|
// */
|
||||||
onOrderChanged : function(nodeList, movedNode) {
|
// TreeNodeAPI = Class.create();
|
||||||
var self = this;
|
// TreeNodeAPI.prototype = {
|
||||||
|
// selectTreeNode : function() {
|
||||||
var i, parts = Array();
|
// var url = jQuery(this).find('a').attr('href');
|
||||||
sort = 0;
|
// if(url && url != '#') {
|
||||||
|
// jQuery('#sitetree').trigger('selectionchanged', {node: this});
|
||||||
for(i=0;i<nodeList.length;i++) {
|
// // don't get page if either event was cancelled,
|
||||||
if(nodeList[i].getIdx && nodeList[i].getIdx()) {
|
// // or the tree is currently in a selectable state.
|
||||||
parts[parts.length] = 'ID[]=' + nodeList[i].getIdx();
|
// if($('sitetree').notify('SelectionChanged', this) && !jQuery(this.tree).hasClass('multiselect')) {
|
||||||
|
// this.getPageFromServer();
|
||||||
// Ensure that the order of new records is preserved when they are moved THEN saved
|
// }
|
||||||
if(
|
// } else {
|
||||||
nodeList[i].id.indexOf("record-new") == 0
|
// jQuery('#Form_EditForm').entwine('ss').removeForm();
|
||||||
&& $('Form_EditForm_ID')
|
// }
|
||||||
&& ('record-' + $('Form_EditForm_ID').value == nodeList[i].id)
|
// },
|
||||||
&& $('Form_EditForm_Sort')
|
//
|
||||||
) {
|
// getPageFromServer : function() {
|
||||||
$('Form_EditForm_Sort').value = ++sort
|
// var self = this;
|
||||||
}
|
// var xmlhttp = jQuery('#Form_EditForm').entwine('ss').loadForm(
|
||||||
}
|
// jQuery(this).find('a').attr('href'),
|
||||||
}
|
// function(response) {
|
||||||
|
// self.removeNodeClass('loading');
|
||||||
if(movedNode.getIdx && movedNode.getIdx()) {
|
//
|
||||||
parts[parts.length] = 'MovedNodeID=' + movedNode.getIdx();
|
// var pageID = jQuery(this).find(':input[name=ID]').val();
|
||||||
}
|
// jQuery('#sitetree')[0].setCurrentByIdx(pageID);
|
||||||
|
// }
|
||||||
if(parts) {
|
// );
|
||||||
jQuery.post(
|
//
|
||||||
SiteTreeHandlers.orderChanged_url,
|
// if(xmlhttp) this.addNodeClass('loading');
|
||||||
parts.join('&'),
|
// },
|
||||||
function(data, status) {
|
// ajaxExpansion : function() {
|
||||||
// TODO This should use a more common serialization in a new tree library
|
// this.addNodeClass('loading');
|
||||||
if(data.modified) {
|
// var ul = this.treeNodeHolder(false);
|
||||||
for(var id in data.modified) {
|
// ul.innerHTML = 'loading...';
|
||||||
self.tree.setNodeTitle(id, data.modified[id]['TreeTitle']);
|
//
|
||||||
}
|
// // Any attempts to add children to this page should, in fact, cue them up for insertion later
|
||||||
}
|
// ul.cuedNewNodes = [];
|
||||||
|
// ul.appendTreeNode = function(node) {
|
||||||
// Check if current page still exists, and refresh it.
|
// this.cuedNewNodes[this.cuedNewNodes.length] = node;
|
||||||
// Otherwise remove the current form
|
// }
|
||||||
var selectedNode = self.tree.firstSelected();
|
//
|
||||||
if(selectedNode) {
|
// var args = {ajax:1, ID:this.getIdx()};
|
||||||
var selectedNodeId = self.tree.getIdxOf(selectedNode);
|
//
|
||||||
if(data.modified[selectedNode.getIdx()]) {
|
// // Add current locale for any subtree selection
|
||||||
// only if the current page was modified
|
// if ($('LangSelector')) args.locale = $('LangSelector').value;
|
||||||
selectedNode.selectTreeNode();
|
//
|
||||||
}
|
// // If the tree is selectable, we have to show all available children without
|
||||||
}
|
// // artificial limitations from the serverside (minNodeCount). This is a measure
|
||||||
},
|
// // to ensure no unexpanded nodes are missed in batch selection
|
||||||
'json'
|
// if(Element.hasClassName('sitetree', 'multiselect')) args.minNodeCount = 0;
|
||||||
);
|
//
|
||||||
}
|
// url = this.tree.url(args);
|
||||||
|
//
|
||||||
return true;
|
// new Ajax.Request(url, {
|
||||||
}
|
// onSuccess : this.installSubtree.bind(this),
|
||||||
}
|
// onFailure : this.showSubtreeLoadingError
|
||||||
|
// });
|
||||||
// Build the site tree
|
// },
|
||||||
SiteTree.applyTo('#sitetree');
|
// showSubtreeLoadingError: function(response) {
|
||||||
|
// errorMessage('error loading subtree', response);
|
||||||
/**
|
// },
|
||||||
* Reorganise action checkbox
|
//
|
||||||
*/
|
// /**
|
||||||
ReorganiseAction = Class.create();
|
// * Context menu
|
||||||
ReorganiseAction.applyTo('#sortitems');
|
// */
|
||||||
ReorganiseAction.prototype = {
|
// oncontextmenu: function(event) {
|
||||||
initialize: function () {
|
// if(TreeContextMenu) {
|
||||||
},
|
// if(!event) event = window.event;
|
||||||
|
// createContextMenu(event, this, TreeContextMenu);
|
||||||
onclick : function() {
|
// Event.stop(event);
|
||||||
if ($('sitetree').isDraggable == false) {
|
// return false;
|
||||||
$('sitetree').makeDraggable();
|
// }
|
||||||
} else {
|
// },
|
||||||
$('sitetree').stopBeingDraggable();
|
// duplicatePage: function() {
|
||||||
}
|
// // Pass the parent ID to the duplicator, which helps ensure that multi-parent pages are duplicated into the node that the user clicked
|
||||||
}
|
// var parentClause = "";
|
||||||
}
|
// if(this.parentTreeNode && this.parentTreeNode.getIdx) {
|
||||||
|
// parentClause = "&parentID=" + this.parentTreeNode.getIdx();
|
||||||
var _CURRENT_CONTEXT_MENU = null;
|
// }
|
||||||
|
//
|
||||||
/**
|
// new Ajax.Request(jQuery('base').attr('href') + 'admin/duplicate/' + this.getIdx() + '?ajax=1' + parentClause, {
|
||||||
* Create a new context menu
|
// method : 'get',
|
||||||
* @param event The event object
|
// onSuccess : Ajax.Evaluator,
|
||||||
* @param owner The DOM element that this context-menu was requested from
|
// onFailure : function(response) {
|
||||||
* @param menuItems A map of title -> method; context-menu operations to get called
|
// errorMessage('Error: ', response);
|
||||||
*/
|
// }
|
||||||
function createContextMenu(event, owner, menuItems) {
|
// });
|
||||||
if(_CURRENT_CONTEXT_MENU) {
|
// },
|
||||||
document.body.removeChild(_CURRENT_CONTEXT_MENU);
|
// duplicatePageWithChildren: function() {
|
||||||
_CURRENT_CONTEXT_MENU = null;
|
// new Ajax.Request(jQuery('base').attr('href') + 'admin/duplicatewithchildren/' + this.getIdx() + '?ajax=1', {
|
||||||
}
|
// method : 'get',
|
||||||
|
// onSuccess : Ajax.Evaluator,
|
||||||
var menu = document.createElement("ul");
|
// onFailure : function(response) {
|
||||||
menu.className = 'contextMenu';
|
// errorMessage('Error: ', response);
|
||||||
menu.style.position = 'absolute';
|
// }
|
||||||
menu.style.left = event.clientX + 'px';
|
// });
|
||||||
menu.style.top = event.clientY + 'px';
|
// }
|
||||||
|
// }
|
||||||
var menuItemName, menuItemTag, menuATag;
|
//
|
||||||
for(menuItemName in menuItems) {
|
//
|
||||||
menuItemTag = document.createElement("li");
|
//
|
||||||
|
//
|
||||||
menuATag = document.createElement("a");
|
// /**
|
||||||
menuATag.href = "#";
|
// * In the case of Tree & DraggableTree, the root tree and the sub-trees all use the same class.
|
||||||
menuATag.onclick = menuATag.oncontextmenu = contextmenu_onclick;
|
// * In this case, however, SiteTree has a much bigger API and so SiteSubTree is smaller.
|
||||||
menuATag.innerHTML = menuItemName;
|
// */
|
||||||
menuATag.handler = menuItems[menuItemName];
|
// SiteSubTree = Class.extend('Tree').extend('TreeAPI');
|
||||||
menuATag.owner = owner;
|
// SiteSubTree.prototype = {
|
||||||
|
// castAsTreeNode: function(li) {
|
||||||
menuItemTag.appendChild(menuATag);
|
// behaveAs(li, SiteTreeNode, this.options);
|
||||||
menu.appendChild(menuItemTag);
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
document.body.appendChild(menu);
|
//
|
||||||
|
// /**
|
||||||
document.body.onclick = contextmenu_close;
|
// * Our SiteTree class extends the tree object with a richer manipulation API.
|
||||||
|
// * The server will send a piece javascript that uses these functions. In this way, the server
|
||||||
_CURRENT_CONTEXT_MENU = menu;
|
// * has flexibility over its operation, but the Script->HTML interface is kept client-side.
|
||||||
|
// */
|
||||||
return menu;
|
// SiteTree = Class.extend('SiteSubTree');
|
||||||
}
|
// SiteTree.prototype = {
|
||||||
|
// initialize : function() {
|
||||||
function contextmenu_close() {
|
// this.Tree.initialize();
|
||||||
if(_CURRENT_CONTEXT_MENU) {
|
//
|
||||||
document.body.removeChild(_CURRENT_CONTEXT_MENU);
|
// /*
|
||||||
_CURRENT_CONTEXT_MENU = null;
|
// if(!this.tree.selected) this.tree.selected = [];
|
||||||
}
|
// var els = this.getElementsByTagName('li');
|
||||||
}
|
// for(var i=0;i<els.length;i++) if(els[i].className.indexOf('current') > -1) {
|
||||||
|
// this.tree.selected.push(els[i]);
|
||||||
function contextmenu_onclick() {
|
// break;
|
||||||
this.handler(this.owner);
|
// }
|
||||||
contextmenu_close();
|
// */
|
||||||
return false;
|
//
|
||||||
}
|
// this.observeMethod('SelectionChanged', this.interruptLoading.bind(this) );
|
||||||
|
//
|
||||||
|
// jQuery('#Form_EditForm').bind('loadnewpage', this.onLoadNewPage.bind(this));
|
||||||
|
// },
|
||||||
|
// destroy: function () {
|
||||||
|
// if(this.Tree) this.Tree.destroy();
|
||||||
|
// this.Tree = null;
|
||||||
|
// this.SiteSubTree = null;
|
||||||
|
// this.TreeAPI = null;
|
||||||
|
// this.selected = null;
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Stop the currently loading node from loading.
|
||||||
|
// */
|
||||||
|
// interruptLoading: function( newLoadingNode ) {
|
||||||
|
// if( this.loadingNode ) this.loadingNode.removeNodeClass('loading');
|
||||||
|
// this.loadingNode = newLoadingNode;
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Assumes to be triggered by a form element with the following input fields:
|
||||||
|
// * ID, ParentID, TreeTitle (or Title), ClassName
|
||||||
|
// */
|
||||||
|
// onLoadNewPage: function(e, eventData) {
|
||||||
|
// // finds a certain value in an array generated by jQuery.serializeArray()
|
||||||
|
// var findInSerializedArray = function(arr, name) {
|
||||||
|
// for(var i=0; i<arr.length; i++) {
|
||||||
|
// if(arr[i].name == name) return arr[i].value;
|
||||||
|
// };
|
||||||
|
// return false;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// var id = jQuery(e.target.ID).val();
|
||||||
|
//
|
||||||
|
// // check if a form with a valid ID exists
|
||||||
|
// if(id) {
|
||||||
|
// var parentID = jQuery(e.target.ParentID).val();
|
||||||
|
//
|
||||||
|
// // set title (either from TreeTitle or from Title fields)
|
||||||
|
// // Treetitle has special HTML formatting to denote the status changes.
|
||||||
|
// var title = jQuery((e.target.TreeTitle) ? e.target.TreeTitle : e.target.Title).val();
|
||||||
|
// if(title) this.setNodeTitle(id, title);
|
||||||
|
//
|
||||||
|
// // update icon (only if it has changed)
|
||||||
|
// var className = jQuery(e.target.ClassName).val();
|
||||||
|
// if(className) this.setNodeIcon(id, className);
|
||||||
|
//
|
||||||
|
// // check if node exists, might have been created instead
|
||||||
|
// if(!this.getTreeNodeByIdx(id)) {
|
||||||
|
// var newNode = $('sitetree').createTreeNode(id, title, className);
|
||||||
|
// var parentNode = $('sitetree').getTreeNodeByIdx(parentID);
|
||||||
|
// if(parentNode) parentNode.appendTreeNode(newNode);
|
||||||
|
// //newNode.selectTreeNode();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // set correct parent (only if it has changed)
|
||||||
|
// if(parentID) this.setNodeParentID(id, jQuery(e.target.ParentID).val());
|
||||||
|
//
|
||||||
|
// // set current tree element
|
||||||
|
// this.setCurrentByIdx(id);
|
||||||
|
// } else {
|
||||||
|
// if(typeof eventData.origData != 'undefined') {
|
||||||
|
// var node = this.getTreeNodeByIdx(eventData.origData.ID);
|
||||||
|
// if(node && node.parentTreeNode) node.parentTreeNode.removeTreeNode(node);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// SiteTreeNode = Class.extend('TreeNode').extend('TreeNodeAPI');
|
||||||
|
// SiteTreeNode.prototype = {
|
||||||
|
// initialize: function(options) {
|
||||||
|
// this.TreeNode.initialize(options);
|
||||||
|
// if(this.className && this.className.match(/class\-([^\s]*)/)) {
|
||||||
|
// var klass = RegExp.$1;
|
||||||
|
// if(typeof siteTreeHints != 'undefined' && siteTreeHints[klass]) {
|
||||||
|
// this.hints = siteTreeHints[klass];
|
||||||
|
// this.dropperOptions = {
|
||||||
|
// accept : (this.hints.allowedChildren && (this.className.indexOf('nochildren') == -1))
|
||||||
|
// ? this.hints.allowedChildren : 'none'
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(this.className.indexOf('current') > -1) {
|
||||||
|
// if(!this.tree.selected) this.tree.selected = [];
|
||||||
|
// this.tree.selected.push(this);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(!this.hints) this.hints = {}
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// destroy: function () {
|
||||||
|
// if(this.TreeNode) this.TreeNode.destroy();
|
||||||
|
// this.TreeNode = null;
|
||||||
|
// this.TreeNodeAPI = null;
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// castAsTree: function(childUL) {
|
||||||
|
// behaveAs(childUL, SiteSubTree, this.options);
|
||||||
|
// if(this.draggableObj) childUL.makeDraggable();
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// onselect: function() {
|
||||||
|
// this.selectTreeNode();
|
||||||
|
// return false;
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Drag'n'drop handlers - Ajax saving
|
||||||
|
// */
|
||||||
|
// onParentChanged : function(node, oldParent, newParent) {
|
||||||
|
// var self = this;
|
||||||
|
//
|
||||||
|
// if(newParent.id.match(/^record-new/)) {
|
||||||
|
// alert("You must save the page before dragging children into it");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if( node == newParent || node.getIdx() == newParent.getIdx() ) {
|
||||||
|
// alert("You cannot add a page to itself");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(node.innerHTML.toLowerCase().indexOf('<del') > -1) {
|
||||||
|
// alert("You can't moved deleted pages");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if( Element.hasClassName( newParent, 'nochildren' ) ) {
|
||||||
|
// alert("You can't add children to that node");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// jQuery.post(
|
||||||
|
// SiteTreeHandlers.parentChanged_url,
|
||||||
|
// 'ID=' + node.getIdx() + '&ParentID=' + newParent.getIdx(),
|
||||||
|
// function(data, status) {
|
||||||
|
// // TODO This should use a more common serialization in a new tree library
|
||||||
|
// if(data.modified) {
|
||||||
|
// for(var id in data.modified) {
|
||||||
|
// self.tree.setNodeTitle(id, data.modified[id]['TreeTitle']);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Check if current page still exists, and refresh it.
|
||||||
|
// // Otherwise remove the current form
|
||||||
|
// var selectedNode = self.tree.firstSelected();
|
||||||
|
// if(selectedNode) {
|
||||||
|
// var selectedNodeId = self.tree.getIdxOf(selectedNode);
|
||||||
|
// if(data.modified[selectedNode.getIdx()]) {
|
||||||
|
// // only if the current page was modified
|
||||||
|
// selectedNode.selectTreeNode();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// 'json'
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// return true;
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Called when the tree has been resorted
|
||||||
|
// * nodeList is a list of all the nodes in the correct rder
|
||||||
|
// * movedNode is the node that actually got moved to trigger this resorting
|
||||||
|
// */
|
||||||
|
// onOrderChanged : function(nodeList, movedNode) {
|
||||||
|
// var self = this;
|
||||||
|
//
|
||||||
|
// var i, parts = Array();
|
||||||
|
// sort = 0;
|
||||||
|
//
|
||||||
|
// for(i=0;i<nodeList.length;i++) {
|
||||||
|
// if(nodeList[i].getIdx && nodeList[i].getIdx()) {
|
||||||
|
// parts[parts.length] = 'ID[]=' + nodeList[i].getIdx();
|
||||||
|
//
|
||||||
|
// // Ensure that the order of new records is preserved when they are moved THEN saved
|
||||||
|
// if(
|
||||||
|
// nodeList[i].id.indexOf("record-new") == 0
|
||||||
|
// && $('Form_EditForm_ID')
|
||||||
|
// && ('record-' + $('Form_EditForm_ID').value == nodeList[i].id)
|
||||||
|
// && $('Form_EditForm_Sort')
|
||||||
|
// ) {
|
||||||
|
// $('Form_EditForm_Sort').value = ++sort
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(movedNode.getIdx && movedNode.getIdx()) {
|
||||||
|
// parts[parts.length] = 'MovedNodeID=' + movedNode.getIdx();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(parts) {
|
||||||
|
// jQuery.post(
|
||||||
|
// SiteTreeHandlers.orderChanged_url,
|
||||||
|
// parts.join('&'),
|
||||||
|
// function(data, status) {
|
||||||
|
// // TODO This should use a more common serialization in a new tree library
|
||||||
|
// if(data.modified) {
|
||||||
|
// for(var id in data.modified) {
|
||||||
|
// self.tree.setNodeTitle(id, data.modified[id]['TreeTitle']);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Check if current page still exists, and refresh it.
|
||||||
|
// // Otherwise remove the current form
|
||||||
|
// var selectedNode = self.tree.firstSelected();
|
||||||
|
// if(selectedNode) {
|
||||||
|
// var selectedNodeId = self.tree.getIdxOf(selectedNode);
|
||||||
|
// if(data.modified[selectedNode.getIdx()]) {
|
||||||
|
// // only if the current page was modified
|
||||||
|
// selectedNode.selectTreeNode();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// 'json'
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Build the site tree
|
||||||
|
// SiteTree.applyTo('#sitetree');
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Reorganise action checkbox
|
||||||
|
// */
|
||||||
|
// ReorganiseAction = Class.create();
|
||||||
|
// ReorganiseAction.applyTo('#sortitems');
|
||||||
|
// ReorganiseAction.prototype = {
|
||||||
|
// initialize: function () {
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// onclick : function() {
|
||||||
|
// if ($('sitetree').isDraggable == false) {
|
||||||
|
// $('sitetree').makeDraggable();
|
||||||
|
// } else {
|
||||||
|
// $('sitetree').stopBeingDraggable();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var _CURRENT_CONTEXT_MENU = null;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Create a new context menu
|
||||||
|
// * @param event The event object
|
||||||
|
// * @param owner The DOM element that this context-menu was requested from
|
||||||
|
// * @param menuItems A map of title -> method; context-menu operations to get called
|
||||||
|
// */
|
||||||
|
// function createContextMenu(event, owner, menuItems) {
|
||||||
|
// if(_CURRENT_CONTEXT_MENU) {
|
||||||
|
// document.body.removeChild(_CURRENT_CONTEXT_MENU);
|
||||||
|
// _CURRENT_CONTEXT_MENU = null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var menu = document.createElement("ul");
|
||||||
|
// menu.className = 'contextMenu';
|
||||||
|
// menu.style.position = 'absolute';
|
||||||
|
// menu.style.left = event.clientX + 'px';
|
||||||
|
// menu.style.top = event.clientY + 'px';
|
||||||
|
//
|
||||||
|
// var menuItemName, menuItemTag, menuATag;
|
||||||
|
// for(menuItemName in menuItems) {
|
||||||
|
// menuItemTag = document.createElement("li");
|
||||||
|
//
|
||||||
|
// menuATag = document.createElement("a");
|
||||||
|
// menuATag.href = "#";
|
||||||
|
// menuATag.onclick = menuATag.oncontextmenu = contextmenu_onclick;
|
||||||
|
// menuATag.innerHTML = menuItemName;
|
||||||
|
// menuATag.handler = menuItems[menuItemName];
|
||||||
|
// menuATag.owner = owner;
|
||||||
|
//
|
||||||
|
// menuItemTag.appendChild(menuATag);
|
||||||
|
// menu.appendChild(menuItemTag);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// document.body.appendChild(menu);
|
||||||
|
//
|
||||||
|
// document.body.onclick = contextmenu_close;
|
||||||
|
//
|
||||||
|
// _CURRENT_CONTEXT_MENU = menu;
|
||||||
|
//
|
||||||
|
// return menu;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// function contextmenu_close() {
|
||||||
|
// if(_CURRENT_CONTEXT_MENU) {
|
||||||
|
// document.body.removeChild(_CURRENT_CONTEXT_MENU);
|
||||||
|
// _CURRENT_CONTEXT_MENU = null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// function contextmenu_onclick() {
|
||||||
|
// this.handler(this.owner);
|
||||||
|
// contextmenu_close();
|
||||||
|
// return false;
|
||||||
|
// }
|
Loading…
x
Reference in New Issue
Block a user