2009-11-21 04:15:40 +01:00
|
|
|
(function($) {
|
2009-11-21 04:19:59 +01:00
|
|
|
$.concrete('ss', function($){
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class Batch actions which take a bunch of selected pages,
|
|
|
|
* usually from the CMS tree implementation, and perform serverside
|
|
|
|
* callbacks on the whole set. We make the tree selectable when the jQuery.UI tab
|
|
|
|
* enclosing this form is opened.
|
|
|
|
* @name ss.Form_BatchActionsForm
|
|
|
|
*
|
|
|
|
* Events:
|
|
|
|
* - register: Called before an action is added.
|
|
|
|
* - unregister: Called before an action is removed.
|
|
|
|
*/
|
|
|
|
$('#Form_BatchActionsForm').concrete(/** @lends ss.Form_BatchActionsForm */{
|
2009-11-21 04:15:40 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @type {DOMElement}
|
|
|
|
*/
|
|
|
|
Tree: null,
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
/**
|
|
|
|
* @type {Array} Stores all actions that can be performed on the collected IDs as
|
|
|
|
* function closures. This might trigger filtering of the selected IDs,
|
|
|
|
* a confirmation message, etc.
|
|
|
|
*/
|
|
|
|
Actions: [],
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
onmatch: function() {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
this.setTree($('#sitetree')[0]);
|
2009-11-21 04:19:59 +01:00
|
|
|
|
|
|
|
$(this.getTree()).bind('selectionchanged', function(e, data) {
|
2009-11-21 04:15:40 +01:00
|
|
|
self._treeSelectionChanged(data.node);
|
|
|
|
});
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
// if tab which contains this form is shown, make the tree selectable
|
|
|
|
$('#TreeActions').bind('tabsselect', function(e, ui) {
|
2009-12-17 00:20:39 +01:00
|
|
|
// if we are selecting another tab, or the panel is visible (meaning about to be closed),
|
2009-11-21 04:15:40 +01:00
|
|
|
// disable tree selection and reset any values. Otherwise enable it.
|
2009-12-17 00:20:39 +01:00
|
|
|
if($(ui.panel).attr('id') != 'TreeActions-batchactions' || $(ui.panel).is(':visible')) {
|
|
|
|
// @TODO: this is unneccessarily fired also when switching between two other tabs
|
2009-11-21 04:19:59 +01:00
|
|
|
$(self.getTree()).removeClass('multiselect');
|
2009-11-21 04:15:40 +01:00
|
|
|
} else {
|
|
|
|
self._multiselectTransform();
|
|
|
|
}
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
});
|
|
|
|
|
2009-11-21 04:19:59 +01:00
|
|
|
this._super();
|
2009-11-21 04:15:40 +01:00
|
|
|
},
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
/**
|
|
|
|
* @param {String} type
|
|
|
|
* @param {Function} callback
|
|
|
|
*/
|
|
|
|
register: function(type, callback) {
|
|
|
|
this.trigger('register', {type: type, callback: callback});
|
2009-11-21 04:19:59 +01:00
|
|
|
var actions = this.getActions();
|
2009-11-21 04:15:40 +01:00
|
|
|
actions[type] = callback;
|
|
|
|
this.setActions(actions);
|
|
|
|
},
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
/**
|
|
|
|
* Remove an existing action.
|
|
|
|
*
|
|
|
|
* @param {String} type
|
|
|
|
*/
|
|
|
|
unregister: function(type) {
|
|
|
|
this.trigger('unregister', {type: type});
|
2009-11-21 04:19:59 +01:00
|
|
|
|
|
|
|
var actions = this.getActions();
|
2009-11-21 04:15:40 +01:00
|
|
|
if(actions[type]) delete actions[type];
|
|
|
|
this.setActions(actions);
|
|
|
|
},
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
/**
|
|
|
|
* Determines if we should allow and track tree selections.
|
|
|
|
*
|
|
|
|
* @todo Too much coupling with tabset
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
_isActive: function() {
|
|
|
|
return $('#TreeActions-batchactions').is(':visible');
|
|
|
|
},
|
2009-11-21 04:19:59 +01:00
|
|
|
|
|
|
|
onsubmit: function(e) {
|
2009-11-21 04:15:40 +01:00
|
|
|
var ids = [];
|
2009-11-21 04:19:59 +01:00
|
|
|
var tree = this.getTree();
|
2009-11-21 04:15:40 +01:00
|
|
|
// find all explicitly selected IDs
|
|
|
|
$(tree).find('li.selected').each(function() {
|
|
|
|
ids.push(tree.getIdxOf(this));
|
|
|
|
// find implicitly selected children
|
|
|
|
$(this).find('li').each(function() {
|
|
|
|
ids.push(tree.getIdxOf(this));
|
|
|
|
});
|
|
|
|
});
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
// if no nodes are selected, return with an error
|
|
|
|
if(!ids || !ids.length) {
|
|
|
|
alert(ss.i18n._t('CMSMAIN.SELECTONEPAGE'));
|
|
|
|
return false;
|
|
|
|
}
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
// apply callback, which might modify the IDs
|
|
|
|
var type = this.find(':input[name=Action]').val();
|
2009-11-21 04:19:59 +01:00
|
|
|
if(this.getActions()[type]) ids = this.getActions()[type].apply(this, [ids]);
|
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
// if no IDs are selected, stop here. This is an implict way for the
|
|
|
|
// callback to cancel the actions
|
2009-11-21 04:19:59 +01:00
|
|
|
if(!ids || !ids.length) return false;
|
2009-11-21 04:15:40 +01:00
|
|
|
|
|
|
|
// write IDs to the hidden field
|
|
|
|
this.find(':input[name=csvIDs]').val(ids.join(','));
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
var button = this.find(':submit:first');
|
|
|
|
button.addClass('loading');
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
jQuery.ajax({
|
|
|
|
// don't use original form url
|
|
|
|
url: type,
|
|
|
|
type: 'POST',
|
|
|
|
data: this.serializeArray(),
|
|
|
|
complete: function(xmlhttp, status) {
|
|
|
|
button.removeClass('loading');
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
// status message
|
|
|
|
var msg = (xmlhttp.getResponseHeader('X-Status')) ? xmlhttp.getResponseHeader('X-Status') : xmlhttp.statusText;
|
|
|
|
statusMessage(msg, (status == 'success') ? 'good' : 'bad');
|
|
|
|
},
|
|
|
|
success: 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) {
|
|
|
|
tree.setNodeTitle(id, data.modified[id]['TreeTitle']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(data.deleted) {
|
|
|
|
for(var id in data.deleted) {
|
|
|
|
var node = tree.getTreeNodeByIdx(id);
|
|
|
|
if(node && node.parentTreeNode) node.parentTreeNode.removeTreeNode(node);
|
|
|
|
}
|
|
|
|
}
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
// reset selection state
|
|
|
|
// TODO Should unselect all selected nodes as well
|
|
|
|
jQuery(tree).removeClass('multiselect');
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
// Check if current page still exists, and refresh it.
|
|
|
|
// Otherwise remove the current form
|
|
|
|
var selectedNode = tree.firstSelected();
|
|
|
|
if(selectedNode) {
|
|
|
|
var selectedNodeId = tree.getIdxOf(selectedNode);
|
|
|
|
if(data.modified[selectedNode.getIdx()]) {
|
|
|
|
// only if the current page was modified
|
|
|
|
selectedNode.selectTreeNode();
|
|
|
|
} else if(data.deleted[selectedNode.getIdx()]) {
|
2009-11-21 04:20:21 +01:00
|
|
|
jQuery('#Form_EditForm').concrete('ss').removeForm();
|
2009-11-21 04:15:40 +01:00
|
|
|
}
|
|
|
|
} else {
|
2009-11-21 04:20:21 +01:00
|
|
|
jQuery('#Form_EditForm').concrete('ss').removeForm();
|
2009-11-21 04:15:40 +01:00
|
|
|
}
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
// close panel
|
|
|
|
// TODO Coupling with tabs
|
2009-11-21 04:20:21 +01:00
|
|
|
jQuery('#TreeActions').tabs('select', -1);
|
2009-11-21 04:15:40 +01:00
|
|
|
},
|
|
|
|
dataType: 'json'
|
|
|
|
});
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @todo This is simulating MultiselectTree functionality, and shouldn't be necessary.
|
|
|
|
*/
|
|
|
|
_multiselectTransform : function() {
|
|
|
|
// make tree selectable
|
2009-11-21 04:19:59 +01:00
|
|
|
jQuery(this.getTree()).addClass('multiselect');
|
2009-11-21 04:15:40 +01:00
|
|
|
|
|
|
|
// auto-select the current node
|
2009-11-21 04:19:59 +01:00
|
|
|
var node = this.getTree().firstSelected();
|
2009-11-21 04:15:40 +01:00
|
|
|
if(node){
|
|
|
|
node.removeNodeClass('current');
|
|
|
|
node.addNodeClass('selected');
|
|
|
|
node.open();
|
|
|
|
|
|
|
|
// Open all existing children, which might trigger further
|
|
|
|
// ajaxExansion calls to ensure all nodes are selectable
|
|
|
|
var children = $(node).find('li').each(function() {
|
|
|
|
this.open();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
/**
|
|
|
|
* Only triggers if the field is considered 'active'.
|
|
|
|
* @todo Most of this is basically simulating broken behaviour of the MultiselectTree mixin,
|
|
|
|
* and should be removed.
|
|
|
|
*/
|
|
|
|
_treeSelectionChanged: function(node) {
|
|
|
|
if(!this._isActive()) return;
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
if(node.selected) {
|
|
|
|
node.removeNodeClass('selected');
|
|
|
|
node.selected = false;
|
|
|
|
} else {
|
|
|
|
// Select node
|
|
|
|
node.addNodeClass('selected');
|
|
|
|
node.selected = true;
|
2009-11-21 04:19:59 +01:00
|
|
|
|
2009-11-21 04:15:40 +01:00
|
|
|
// Open node in order to allow proper selection of children
|
|
|
|
if($(node).hasClass('unexpanded')) {
|
|
|
|
node.open();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Open all existing children, which might trigger further
|
|
|
|
// ajaxExansion calls to ensure all nodes are selectable
|
|
|
|
var children = $(node).find('li').each(function() {
|
|
|
|
this.open();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2009-11-21 04:19:59 +01:00
|
|
|
});
|
2009-11-21 04:15:40 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
$(document).ready(function() {
|
|
|
|
/**
|
|
|
|
* Publish selected pages action
|
|
|
|
*/
|
|
|
|
$('#Form_BatchActionsForm').concrete('ss').register('admin/batchactions/publish', function(ids) {
|
|
|
|
var confirmed = confirm(
|
|
|
|
"You have " + ids.length + " pages selected.\n\n"
|
|
|
|
+ "Do your really want to publish?"
|
|
|
|
);
|
|
|
|
return (confirmed) ? ids : false;
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unpublish selected pages action
|
|
|
|
*/
|
|
|
|
$('#Form_BatchActionsForm').concrete('ss').register('admin/batchactions/unpublish', function(ids) {
|
|
|
|
var confirmed = confirm(
|
|
|
|
"You have " + ids.length + " pages selected.\n\n"
|
|
|
|
+ "Do your really want to unpublish?"
|
|
|
|
);
|
|
|
|
return (confirmed) ? ids : false;
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delete selected pages action
|
|
|
|
*/
|
|
|
|
$('#Form_BatchActionsForm').concrete('ss').register('admin/batchactions/delete', function(ids) {
|
|
|
|
var confirmed = confirm(
|
|
|
|
"You have " + ids.length + " pages selected.\n\n"
|
|
|
|
+ "Do your really want to delete?"
|
|
|
|
);
|
|
|
|
return (confirmed) ? ids : false;
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delete selected pages from live action
|
|
|
|
*/
|
|
|
|
$('#Form_BatchActionsForm').concrete('ss').register('admin/batchactions/deletefromlive', function(ids) {
|
|
|
|
var confirmed = confirm(
|
|
|
|
"You have " + ids.length + " pages selected.\n\n"
|
|
|
|
+ "Do your really want to delete these pages from live?"
|
|
|
|
);
|
|
|
|
return (confirmed) ? ids : false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
})(jQuery);
|