mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-09-06 01:31:30 +02:00
API CHANGE Removed LeftAndMain->BatchActionList(), no longer necessary as we're creating the batch actions form in the same class ENHANCEMENT Changed CMSBatchAction logic to return JSON status changes rather than eval'ed JavaScript via FormResponse ENHANCEMENT Ported batchactions in CMSMain_left.js to concrete javascript, and moved to new CMSMain.BatchActions.js file ENHANCEMENT Using native CMSMain->BatchActionsForm() to render form instead of custom template markup in CMSMain_TreeTools.ss git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92722 467b73ca-7a2a-4603-9d3b-597d59a354a9
278 lines
7.9 KiB
JavaScript
278 lines
7.9 KiB
JavaScript
(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('ss', function($){
|
|
return/** @lends ss.Form_BatchActionsForm */{
|
|
|
|
/**
|
|
* @type {DOMElement}
|
|
*/
|
|
Tree: null,
|
|
|
|
/**
|
|
* @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: [],
|
|
|
|
onmatch: function() {
|
|
var self = this;
|
|
|
|
this.setTree($('#sitetree')[0]);
|
|
|
|
$(this.Tree()).bind('selectionchanged', function(e, data) {
|
|
self._treeSelectionChanged(data.node);
|
|
});
|
|
|
|
// if tab which contains this form is shown, make the tree selectable
|
|
$('#TreeActions').bind('tabsselect', function(e, ui) {
|
|
if($(ui.panel).attr('id') != 'TreeActions-batchactions') return;
|
|
|
|
// if the panel is visible (meaning about to be closed),
|
|
// disable tree selection and reset any values. Otherwise enable it.
|
|
if($(ui.panel).is(':visible')) {
|
|
$(self.Tree()).removeClass('multiselect');
|
|
} else {
|
|
self._multiselectTransform();
|
|
}
|
|
|
|
});
|
|
|
|
this.bind('submit', function(e) {return self._submit(e);});
|
|
},
|
|
|
|
/**
|
|
* @param {String} type
|
|
* @param {Function} callback
|
|
*/
|
|
register: function(type, callback) {
|
|
this.trigger('register', {type: type, callback: callback});
|
|
|
|
var actions = this.Actions();
|
|
actions[type] = callback;
|
|
this.setActions(actions);
|
|
},
|
|
|
|
/**
|
|
* Remove an existing action.
|
|
*
|
|
* @param {String} type
|
|
*/
|
|
unregister: function(type) {
|
|
this.trigger('unregister', {type: type});
|
|
|
|
var actions = this.Actions();
|
|
if(actions[type]) delete actions[type];
|
|
this.setActions(actions);
|
|
},
|
|
|
|
/**
|
|
* Determines if we should allow and track tree selections.
|
|
*
|
|
* @todo Too much coupling with tabset
|
|
* @return boolean
|
|
*/
|
|
_isActive: function() {
|
|
return $('#TreeActions-batchactions').is(':visible');
|
|
},
|
|
|
|
_submit: function(e) {
|
|
var ids = [];
|
|
var tree = this.Tree();
|
|
// 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));
|
|
});
|
|
});
|
|
|
|
// if no nodes are selected, return with an error
|
|
if(!ids || !ids.length) {
|
|
alert(ss.i18n._t('CMSMAIN.SELECTONEPAGE'));
|
|
return false;
|
|
}
|
|
|
|
// apply callback, which might modify the IDs
|
|
var type = this.find(':input[name=Action]').val();
|
|
if(this.Actions()[type]) ids = this.Actions()[type].apply(this, [ids]);
|
|
|
|
// if no IDs are selected, stop here. This is an implict way for the
|
|
// callback to cancel the actions
|
|
if(!ids || !ids.length) {
|
|
return false;
|
|
}
|
|
|
|
// write IDs to the hidden field
|
|
this.find(':input[name=csvIDs]').val(ids.join(','));
|
|
|
|
var button = this.find(':submit:first');
|
|
button.addClass('loading');
|
|
|
|
jQuery.ajax({
|
|
// don't use original form url
|
|
url: type,
|
|
type: 'POST',
|
|
data: this.serializeArray(),
|
|
complete: function(xmlhttp, status) {
|
|
button.removeClass('loading');
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
// reset selection state
|
|
// TODO Should unselect all selected nodes as well
|
|
jQuery(tree).removeClass('multiselect');
|
|
|
|
// 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()]) {
|
|
$('#Form_EditForm').concrete('ss').removeForm();
|
|
}
|
|
} else {
|
|
$('#Form_EditForm').concrete('ss').removeForm();
|
|
}
|
|
|
|
// close panel
|
|
// TODO Coupling with tabs
|
|
$('#TreeActions').tabs('select', -1);
|
|
},
|
|
dataType: 'json'
|
|
});
|
|
|
|
return false;
|
|
},
|
|
|
|
/**
|
|
* @todo This is simulating MultiselectTree functionality, and shouldn't be necessary.
|
|
*/
|
|
_multiselectTransform : function() {
|
|
// make tree selectable
|
|
jQuery(this.Tree()).addClass('multiselect');
|
|
|
|
// auto-select the current node
|
|
var node = this.Tree().firstSelected();
|
|
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();
|
|
});
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 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;
|
|
|
|
if(node.selected) {
|
|
node.removeNodeClass('selected');
|
|
node.selected = false;
|
|
} else {
|
|
// Select node
|
|
node.addNodeClass('selected');
|
|
node.selected = true;
|
|
|
|
// 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();
|
|
});
|
|
}
|
|
}
|
|
};
|
|
});
|
|
|
|
$(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); |