ENHANCEMENT Updated LeftAndMain->ajaxupdateparent() and ajaxupdatesort() to return JSON data rather than FormResponse eval()ed javascript, and let the clientside handle any updates. Also updated to use HTTPRequest instead of superglobals.

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92740 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2009-11-21 03:16:30 +00:00
parent 57b0bbc83a
commit c7cca847c8
2 changed files with 128 additions and 95 deletions

View File

@ -683,20 +683,19 @@ JS;
/** /**
* Ajax handler for updating the parent of a tree node * Ajax handler for updating the parent of a tree node
*/ */
public function ajaxupdateparent() { public function ajaxupdateparent($request) {
$id = $_REQUEST['ID'];
$parentID = $_REQUEST['ParentID'];
if($parentID == 'root'){
$parentID = 0;
}
$_REQUEST['ajax'] = 1;
$cleanupJS = '';
if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) { if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) {
FormResponse::status_message(_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved."),"bad"); $this->response->setStatusCode(
return FormResponse::respond(); 403,
_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved.")
);
return;
} }
$id = $request->requestVar('ID');
$parentID = $request->requestVar('ParentID');
$statusUpdates = array('modified'=>array());
if(is_numeric($id) && is_numeric($parentID) && $id != $parentID) { if(is_numeric($id) && is_numeric($parentID) && $id != $parentID) {
$node = DataObject::get_by_id($this->stat('tree_class'), $id); $node = DataObject::get_by_id($this->stat('tree_class'), $id);
if($node){ if($node){
@ -713,18 +712,33 @@ JS;
} }
} }
FormResponse::status_message(_t('LeftAndMain.SAVED','saved'), 'good'); $node = DataObject::get_by_id($this->stat('tree_class'), $id);
if($cleanupJS) FormResponse::add($cleanupJS); if($node){
if($node && !$node->canEdit()) return Security::permissionFailure($this);
$node->ParentID = $parentID;
$node->Status = "Saved (update)";
$node->write();
$statusUpdates['modified'][$node->ID] = array(
'TreeTitle'=>$node->TreeTitle
);
$this->response->addHeader(
'X-Status',
_t('LeftAndMain.SAVED','saved')
);
}else{ }else{
FormResponse::status_message(_t('LeftAndMain.PLEASESAVE',"Please Save Page: This page could not be upated because it hasn't been saved yet."),"good"); $this->response->setStatusCode(
500,
_t(
'LeftAndMain.PLEASESAVE',
"Please Save Page: This page could not be upated because it hasn't been saved yet."
)
);
} }
return Convert::raw2json($statusUpdates);
return FormResponse::respond();
} else {
user_error("Error in ajaxupdateparent request; id=$id, parentID=$parentID", E_USER_ERROR);
}
} }
/** /**
@ -732,53 +746,44 @@ JS;
* $_GET[ID]: An array of node ids in the correct order * $_GET[ID]: An array of node ids in the correct order
* $_GET[MovedNodeID]: The node that actually got moved * $_GET[MovedNodeID]: The node that actually got moved
*/ */
public function ajaxupdatesort() { public function ajaxupdatesort($request) {
if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) {
$this->response->setStatusCode(
403,
_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved.")
);
return;
}
$className = $this->stat('tree_class'); $className = $this->stat('tree_class');
$counter = 0; $counter = 0;
$js = ''; $statusUpdates = array('modified'=>array());
$_REQUEST['ajax'] = 1;
if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) { if(!is_array($request->requestVar('ID'))) return false;
FormResponse::status_message(_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved."),"bad");
return FormResponse::respond();
}
if(is_array($_REQUEST['ID'])) { //Sorting root
if($_REQUEST['MovedNodeID']==0){ //Sorting root if($request->requestVar('MovedNodeID')==0){
$movedNode = DataObject::get($className, "\"ParentID\"=0"); $movedNode = DataObject::get($className, "\"ParentID\"=0");
}else{ }else{
$movedNode = DataObject::get_by_id($className, $_REQUEST['MovedNodeID']); $movedNode = DataObject::get_by_id($className, $request->requestVar('MovedNodeID'));
} }
foreach($_REQUEST['ID'] as $id) { foreach($request->requestVar('ID') as $id) {
if($id == $movedNode->ID) { if($id == $movedNode->ID) {
$movedNode->Sort = ++$counter; $movedNode->Sort = ++$counter;
$movedNode->Status = "Saved (update)"; $movedNode->Status = "Saved (update)";
$movedNode->write(); $movedNode->write();
$statusUpdates['modified'][$movedNode->ID] = array(
$title = Convert::raw2js($movedNode->TreeTitle); 'TreeTitle'=>$movedNode->TreeTitle
$js .="$('sitetree').setNodeTitle($movedNode->ID, \"$title\");\n"; );
// Nodes that weren't "actually moved" shouldn't be registered as having been edited; do a direct SQL update instead
} else if(is_numeric($id)) { } else if(is_numeric($id)) {
// Nodes that weren't "actually moved" shouldn't be registered as
// having been edited; do a direct SQL update instead
++$counter; ++$counter;
DB::query("UPDATE \"$className\" SET \"Sort\" = $counter WHERE \"ID\" = '$id'"); DB::query("UPDATE \"$className\" SET \"Sort\" = $counter WHERE \"ID\" = '$id'");
} }
} }
// Virtual pages require selected to be null if the page is the same.
FormResponse::add(
"if( $('sitetree').selected && $('sitetree').selected[0]){
var idx = $('sitetree').selected[0].getIdx();
if(idx){
$('Form_EditForm').getPageFromServer(idx);
}
}\n" . $js
);
FormResponse::status_message(_t('LeftAndMain.SAVED'), 'good');
} else {
FormResponse::error(_t('LeftAndMain.REQUESTERROR',"Error in request"));
}
return FormResponse::respond(); return Convert::raw2json($statusUpdates);
} }
public function CanOrganiseSitetree() { public function CanOrganiseSitetree() {

View File

@ -445,6 +445,8 @@ SiteTreeNode.prototype = {
* Drag'n'drop handlers - Ajax saving * Drag'n'drop handlers - Ajax saving
*/ */
onParentChanged : function(node, oldParent, newParent) { onParentChanged : function(node, oldParent, newParent) {
var self = this;
if(newParent.id.match(/^record-new/)) { if(newParent.id.match(/^record-new/)) {
alert("You must save the page before dragging children into it"); alert("You must save the page before dragging children into it");
return false; return false;
@ -465,18 +467,30 @@ SiteTreeNode.prototype = {
return false; return false;
} }
var currentlyOpenPageID = 0; jQuery.post(
if($('Form_EditForm').elements.ID) currentlyOpenPageID = $('Form_EditForm').elements.ID.value; SiteTreeHandlers.parentChanged_url,
'ID=' + node.getIdx() + '&ParentID=' + newParent.getIdx(),
statusMessage(ss.i18n._t('CMSMAIN.SAVING'), '', true); function(data, status) {
new Ajax.Request(SiteTreeHandlers.parentChanged_url, { // TODO This should use a more common serialization in a new tree library
method : 'post', if(data.modified) {
postBody : 'ID=' + node.getIdx() + '&ParentID=' + newParent.getIdx() + '&CurrentlyOpenPageID=' + currentlyOpenPageID, for(var id in data.modified) {
onSuccess : Ajax.Evaluator, self.tree.setNodeTitle(id, data.modified[id]['TreeTitle']);
onFailure : function(response) {
errorMessage('error saving parent', response);
} }
}); }
// 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; return true;
}, },
@ -487,7 +501,7 @@ SiteTreeNode.prototype = {
* movedNode is the node that actually got moved to trigger this resorting * movedNode is the node that actually got moved to trigger this resorting
*/ */
onOrderChanged : function(nodeList, movedNode) { onOrderChanged : function(nodeList, movedNode) {
statusMessage(ss.i18n._t('CMSMAIN.SAVING'), '', true); var self = this;
var i, parts = Array(); var i, parts = Array();
sort = 0; sort = 0;
@ -497,10 +511,14 @@ SiteTreeNode.prototype = {
parts[parts.length] = 'ID[]=' + 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 // Ensure that the order of new records is preserved when they are moved THEN saved
if( nodeList[i].id.indexOf("record-new") == 0 ) if(
if( $('Form_EditForm_ID') && ( 'record-' + $('Form_EditForm_ID').value == nodeList[i].id ) ) nodeList[i].id.indexOf("record-new") == 0
if( $('Form_EditForm_Sort') ) && $('Form_EditForm_ID')
$('Form_EditForm_Sort').value = ++sort; && ('record-' + $('Form_EditForm_ID').value == nodeList[i].id)
&& $('Form_EditForm_Sort')
) {
$('Form_EditForm_Sort').value = ++sort
}
} }
} }
@ -508,21 +526,31 @@ SiteTreeNode.prototype = {
parts[parts.length] = 'MovedNodeID=' + movedNode.getIdx(); parts[parts.length] = 'MovedNodeID=' + movedNode.getIdx();
} }
var currentlyOpenPageID = 0;
if($('Form_EditForm').elements.ID) currentlyOpenPageID = $('Form_EditForm').elements.ID.value;
if(parts) { if(parts) {
new Ajax.Request(SiteTreeHandlers.orderChanged_url, { jQuery.post(
method : 'post', SiteTreeHandlers.orderChanged_url,
postBody : parts.join('&') + '&CurrentlyOpenPageID=' + currentlyOpenPageID, parts.join('&'),
/*onSuccess : function(response) { function(data, status) {
// statusMessage(response.responseText, 'good'); // TODO This should use a more common serialization in a new tree library
},*/ if(data.modified) {
onSuccess: Ajax.Evaluator, for(var id in data.modified) {
onFailure : function(response) { self.tree.setNodeTitle(id, data.modified[id]['TreeTitle']);
errorMessage('error saving order', response);
} }
}); }
// 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; return true;