From ed9bca2c682de39dea6344ee8914afeda184dd00 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sun, 16 Sep 2007 15:04:09 +0000 Subject: [PATCH] elofgren: NEW FEATURE: Replace the 'Delete...' button with a 'Batch Actions' button and add a 'Publish the selected pages' button. See: http://www.silverstripe.com/google-summer-of-code-forum/flat/1636?showPost=1859#post1859 And: http://www.silverstripe.com/silverstripe-development/flat/3799?showPost=4070#post4070 TODO: Make the new 'Search' button functional. (merged from branches/gsoc) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@42081 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/CMSMain.php | 53 ++++++++- css/cms_right.css | 2 +- javascript/CMSMain_left.js | 165 ++++++++++++++++++----------- javascript/LeftAndMain_left.js | 2 +- lang/en_US.php | 15 ++- templates/Includes/CMSMain_left.ss | 29 +++-- 6 files changed, 185 insertions(+), 81 deletions(-) diff --git a/code/CMSMain.php b/code/CMSMain.php index 52854587..fd545dce 100644 --- a/code/CMSMain.php +++ b/code/CMSMain.php @@ -849,6 +849,53 @@ HTML; ))->renderWith('Dialog'); } + /** + * Publishes a number of items. + * Called by AJAX + */ + public function publishitems() { + // This method can't be called without ajax. + if(!Director::is_ajax()) { + Director::redirectBack(); + return; + } + + $ids = split(' *, *', $_REQUEST['csvIDs']); + + $notifications = array(); + + $idList = array(); + + // make sure all the ids are numeric. + // Add all the children to the list of IDs if they are missing + foreach($ids as $id) { + $brokenPageList = ''; + if(is_numeric($id)) { + $record = DataObject::get_by_id($this->stat('tree_class'), $id); + + if($record) { + // Publish this page + $this->performPublish($record); + + // Now make sure the 'changed' icon is removed + $publishedRecord = DataObject::get_by_id($this->stat('tree_class'), $id); + $JS_title = Convert::raw2js($publishedRecord->TreeTitle()); + FormResponse::add("\$('sitetree').setNodeTitle($id, '$JS_title');"); + FormResponse::add("$('Form_EditForm').reloadIfSetTo($record->ID);"); + $record->destroy(); + unset($record); + } + } + } + + if (sizeof($ids) > 1) $message = sprintf(_t('CMSMain.PAGESPUB', "%d pages published "), sizeof($ids)); + else $message = sprintf(_t('CMSMain.PAGEPUB', "%d page published "), sizeof($ids)); + + FormResponse::add('statusMessage("'.$message.'","good");'); + + return FormResponse::respond(); + } + /** * Delete a number of items. * This code supports notification @@ -933,13 +980,13 @@ HTML; } } - if (sizeof($ids) > 1) $message = sprintf(_t('CMSMain.PAGEDEL', "%d page deleted "), sizeof($ids)); - else $message = sprintf(_t('CMSMain.PAGESDEL', "%d pages deleted "), sizeof($ids)); + if (sizeof($ids) > 1) $message = sprintf(_t('CMSMain.PAGESDEL', "%d pages deleted "), sizeof($ids)); + else $message = sprintf(_t('CMSMain.PAGEDEL', "%d page deleted "), sizeof($ids)); if(isset($brokenPageList) && $brokenPageList != '') { $message .= _t('CMSMain.NOWBROKEN'," The following pages now have broken links:")."" . _t('CMSMain.NOWBROKEN2',"Their owners have been emailed and they will fix up those pages."); } - FormResponse::status_message($message); + FormResponse::add('statusMessage("'.$message.'","good");'); return FormResponse::respond(); } diff --git a/css/cms_right.css b/css/cms_right.css index abe3937d..61108147 100644 --- a/css/cms_right.css +++ b/css/cms_right.css @@ -385,7 +385,7 @@ input.delete:hover { background: #ce0000; color: #fff; } -.ajaxActions input.loading { +input.loading { background-color: #fff; background-image: url(../images/network-save.gif); background-position: center left; diff --git a/javascript/CMSMain_left.js b/javascript/CMSMain_left.js index a84ed11c..8977f9b5 100755 --- a/javascript/CMSMain_left.js +++ b/javascript/CMSMain_left.js @@ -97,28 +97,42 @@ addpage.prototype = { } /** - * Delete page action + * Batch Actions button click action */ -deletepage = { - button_onclick : function() { +batchactions = Class.create(); +batchactions.applyTo('#batchactions'); +batchactions.prototype = { + + initialize : function() { + Observable.applyTo($(_HANDLER_FORMS.batchactions)); + }, + onclick : function() { if(treeactions.toggleSelection(this)) { - deletepage.o1 = $('sitetree').observeMethod('SelectionChanged', deletepage.treeSelectionChanged); - deletepage.o2 = $(_HANDLER_FORMS.deletepage).observeMethod('Close', deletepage.popupClosed); + batchActionGlobals.o1 = $('sitetree').observeMethod('SelectionChanged', batchActionGlobals.treeSelectionChanged); + batchActionGlobals.o2 = $(_HANDLER_FORMS.batchactions).observeMethod('Close', batchActionGlobals.popupClosed); addClass($('sitetree'),'multiselect'); - deletepage.selectedNodes = { }; + batchActionGlobals.selectedNodes = { }; var sel = $('sitetree').firstSelected(); if(sel && sel.className.indexOf('nodelete') == -1) { var selIdx = $('sitetree').getIdxOf(sel); - deletepage.selectedNodes[selIdx] = true; + batchActionGlobals.selectedNodes[selIdx] = true; sel.removeNodeClass('current'); sel.addNodeClass('selected'); } } return false; - }, + } +} +// batchActionGlobals is needed because calls to observeMethod doesn't seem to preserve instance variables so a Prototype can't be used +batchActionGlobals = { + selectedNodes: { }, + // count Int - The number of nodes selected + count: { }, + // TODO: Remove 'new-' code http://open.silverstripe.com/ticket/875 + newNodes: { }, treeSelectionChanged : function(selectedNode) { var idx = $('sitetree').getIdxOf(selectedNode); @@ -126,12 +140,12 @@ deletepage = { if(selectedNode.selected) { selectedNode.removeNodeClass('selected'); selectedNode.selected = false; - deletepage.selectedNodes[idx] = false; + batchActionGlobals.selectedNodes[idx] = false; } else { selectedNode.addNodeClass('selected'); selectedNode.selected = true; - deletepage.selectedNodes[idx] = true; + batchActionGlobals.selectedNodes[idx] = true; } } @@ -140,11 +154,11 @@ deletepage = { popupClosed : function() { removeClass($('sitetree'),'multiselect'); - $('sitetree').stopObserving(deletepage.o1); - $(_HANDLER_FORMS.deletepage).stopObserving(deletepage.o2); + $('sitetree').stopObserving(batchActionGlobals.o1); + $(_HANDLER_FORMS.batchactions).stopObserving(batchActionGlobals.o2); - for(var idx in deletepage.selectedNodes) { - if(deletepage.selectedNodes[idx]) { + for(var idx in batchActionGlobals.selectedNodes) { + if(batchActionGlobals.selectedNodes[idx]) { node = $('sitetree').getTreeNodeByIdx(idx); if(node) { node.removeNodeClass('selected'); @@ -152,41 +166,87 @@ deletepage = { } } } + batchActionGlobals.selectedNodes = { }; }, - form_submit : function() { - var csvIDs = "", count = 0; + getCsvIds : function() { + var csvIDs = ""; + batchActionGlobals.count = 0; var st = $('sitetree'); - var newNodes = new Array(); - - for(var idx in deletepage.selectedNodes) { - if(deletepage.selectedNodes[idx]) { + batchActionGlobals.newNodes = new Array(); + for(var idx in batchActionGlobals.selectedNodes) { + if(batchActionGlobals.selectedNodes[idx]) { - // delete new nodes + // Delete/Publish new nodes? (Leftover from delete code?) TODO: Remove 'new-' code http://open.silverstripe.com/ticket/875 if( idx.match(/^new-[a-z0-9A-Z\-]+$/) ) { - newNodes.push( idx ); + batchActionGlobals.newNodes.push( idx ); } else { - var i, item, childrenToDelete = st.getTreeNodeByIdx(idx).getElementsByTagName('li'); - for(i=0;item=childrenToDelete[i];i++) { - csvIDs += (csvIDs ? "," : "") + st.getIdxOf(childrenToDelete[i]); - count++; + var i, item, childrenTopublish = st.getTreeNodeByIdx(idx).getElementsByTagName('li'); + for(i=0;item=childrenTopublish[i];i++) { + csvIDs += (csvIDs ? "," : "") + st.getIdxOf(childrenTopublish[i]); + batchActionGlobals.count++; } csvIDs += (csvIDs ? "," : "") + idx; - count++; + batchActionGlobals.count++; } } } + return csvIDs; + } +} - if(csvIDs || newNodes.length > 0) { - count += newNodes.length; +/** + * Publish selected pages action + */ +publishpage = Class.create(); +publishpage.applyTo('#publishpage_options'); +publishpage.prototype = { + onsubmit : function() { + csvIDs = batchActionGlobals.getCsvIds(); + if(csvIDs) { + this.elements.csvIDs.value = csvIDs; - if(confirm("Do you really want to delete the " + count + " marked pages?")) { - $(_HANDLER_FORMS.deletepage).elements.csvIDs.value = csvIDs; + statusMessage('Publishing pages...'); + + // Put an AJAXY loading icon on the button + $('action_publish_selected').className = 'loading'; + Ajax.SubmitForm(this, null, { + onSuccess : function(response) { + Ajax.Evaluator(response); + $('action_publish_selected').className = ''; + treeactions.closeSelection($('batchactions')); + }, + onFailure : function(response) { + errorMessage('Error publishing pages', response); + } + }); + } else { + alert("Please select at least 1 page."); + } + + return false; + } +} + + +/** + * Delete selected pages action + */ +deletepage = Class.create(); +deletepage.applyTo('#deletepage_options'); +deletepage.prototype = { + onsubmit : function() { + csvIDs = batchActionGlobals.getCsvIds(); + if(csvIDs || batchActionGlobals.newNodes.length > 0) { + batchActionGlobals.count += batchActionGlobals.newNodes.length; + + if(confirm("Do you really want to delete the " + batchActionGlobals.count + " marked pages?")) { + this.elements.csvIDs.value = csvIDs; - statusMessage('deleting pages'); - - for( var idx = 0; idx < newNodes.length; idx++ ) { - var newNode = $('sitetree').getTreeNodeByIdx( newNodes[idx] ); + statusMessage('Deleting pages...'); + // TODO: Remove 'new-' code http://open.silverstripe.com/ticket/875 + for( var idx = 0; idx < batchActionGlobals.newNodes.length; idx++ ) { + var newNode = $('sitetree').getTreeNodeByIdx( batchActionGlobals.newNodes[idx] ); if( newNode.parentTreeNode ) newNode.parentTreeNode.removeTreeNode( newNode ); @@ -196,16 +256,19 @@ deletepage = { $('Form_EditForm').reloadIfSetTo(idx); } - newNodes = new Array(); - - Ajax.SubmitForm(_HANDLER_FORMS.deletepage, null, { - onSuccess : deletepage.submit_success, + batchActionGlobals.newNodes = new Array(); + // Put an AJAXY loading icon on the button + $('action_delete_selected').className = 'loading'; + Ajax.SubmitForm(this, null, { + onSuccess : function(response) { + Ajax.Evaluator(response); + $('action_delete_selected').className = ''; + treeactions.closeSelection($('batchactions')); + }, onFailure : function(response) { errorMessage('Error deleting pages', response); } }); - - $('deletepage').getElementsByTagName('button')[0].onclick(); } } else { @@ -213,29 +276,9 @@ deletepage = { } return false; - }, - submit_success: function(response) { - deletepage.selectedNodes = {}; - - Ajax.Evaluator(response); - treeactions.closeSelection($('deletepage')); } } -/** - * Initialisation function to set everything up - */ -appendLoader(function () { - // Set up deleet page - if( !$('deletepage') ) - return; - - Observable.applyTo($(_HANDLER_FORMS.deletepage)); - $('deletepage').onclick = deletepage.button_onclick; - $('deletepage').getElementsByTagName('button')[0].onclick = function() { return false; }; - $(_HANDLER_FORMS.deletepage).onsubmit = deletepage.form_submit; -}); - /** * Tree context menu */ diff --git a/javascript/LeftAndMain_left.js b/javascript/LeftAndMain_left.js index 15d6da40..9cf3b9ce 100755 --- a/javascript/LeftAndMain_left.js +++ b/javascript/LeftAndMain_left.js @@ -12,7 +12,7 @@ SiteTreeHandlers.controller_url = 'admin'; var _HANDLER_FORMS = { addpage : 'Form_AddPageOptionsForm', - deletepage : 'deletepage_options' + batchactions : 'batchactionsforms' }; diff --git a/lang/en_US.php b/lang/en_US.php index 35730588..4eea6b57 100755 --- a/lang/en_US.php +++ b/lang/en_US.php @@ -47,6 +47,8 @@ $lang['en_US']['CMSMain']['COMPARINGV'] = 'You are comparing versions #%d and #% $lang['en_US']['CMSMain']['COPYPUBTOSTAGE'] = 'Do you really want to copy the published content to the stage site?'; $lang['en_US']['CMSMain']['OK'] = 'OK'; $lang['en_US']['CMSMain']['CANCEL'] = 'Cancel'; +$lang['en_US']['CMSMain']['PAGEPUB'] = '%d page published '; +$lang['en_US']['CMSMain']['PAGESPUB'] = '%d pages published '; $lang['en_US']['CMSMain']['PAGEDEL'] = '%d page deleted '; $lang['en_US']['CMSMain']['PAGESDEL'] = '%d pages deleted '; $lang['en_US']['CMSMain']['NOWBROKEN'] = ' The following pages now have broken links:'; @@ -126,19 +128,24 @@ $lang['en_US']['CMSMain_left.ss']['SITECONTENT TITLE'] = array( PR_HIGH ); $lang['en_US']['CMSMain_left.ss']['CREATE'] = array( - 'Create...', + 'Create', PR_HIGH ); -$lang['en_US']['CMSMain_left.ss']['DELETE'] = array( - 'Delete...', +$lang['en_US']['CMSMain_left.ss']['SEARCH'] = array( + 'Search', + PR_HIGH +); +$lang['en_US']['CMSMain_left.ss']['BATCHACTIONS'] = array( + 'Batch Actions', PR_HIGH ); $lang['en_US']['CMSMain_left.ss']['ENABLEDRAGGING'] = array( 'Allow drag & drop reordering', PR_HIGH ); -$lang['en_US']['CMSMain_left.ss']['SELECTPAGESDEL'] = 'Select the pages that you want to delete and then click the button below'; +$lang['en_US']['CMSMain_left.ss']['SELECTPAGESACTIONS'] = 'Select the pages that you want to change & then click an action:'; $lang['en_US']['CMSMain_left.ss']['DELETECONFIRM'] = 'Delete the selected pages'; +$lang['en_US']['CMSMain_left.ss']['PUBLISHCONFIRM'] = 'Publish the selected pages'; $lang['en_US']['CMSMain_left.ss']['SELECTPAGESDUP'] = 'Select the pages that you want to duplicate, whether it\'s children should be included, and where you want the duplicates placed'; $lang['en_US']['CMSMain_left.ss']['KEY'] = 'Key:'; $lang['en_US']['CMSMain_left.ss']['ADDEDNOTPUB'] = 'Added to the draft site and not published yet'; diff --git a/templates/Includes/CMSMain_left.ss b/templates/Includes/CMSMain_left.ss index 4b346499..cafb021e 100755 --- a/templates/Includes/CMSMain_left.ss +++ b/templates/Includes/CMSMain_left.ss @@ -9,8 +9,9 @@
@@ -41,15 +42,21 @@ <% end_control %> - - - + <% control DuplicatePagesOptionsForm %>