Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

BUGFIX Respecting server-overrides on X-Pjax responses during ajax re…

…directs. Fixes GridFieldDetailForm redirect after delete, e.g. in ModelAdmin. Partially reverts 8b4b896. Closes pull request #488
  • Loading branch information...
commit 5b03f4924509adf03f2654bd0af575692110276e 1 parent 909c5bd
Ingo Schommer chillu authored
2  admin/code/LeftAndMain.php
View
@@ -351,6 +351,8 @@ function handleRequest(SS_HTTPRequest $request, DataModel $model = null) {
function redirect($url, $code=302) {
if($this->request->isAjax()) {
$this->response->addHeader('X-ControllerURL', $url);
+ if($header = $this->request->getHeader('X-Pjax')) $this->response->addHeader('X-Pjax', $header);
+ if($header = $this->request->getHeader('X-Pjax-Selector')) $this->response->addHeader('X-Pjax-Selector', $header);
return ''; // Actual response will be re-requested by client
} else {
parent::redirect($url, $code);
16 admin/javascript/LeftAndMain.Content.js
View
@@ -80,18 +80,14 @@
// as automatic browser ajax response redirects seem to discard the hash/fragment.
formData.push({name: 'BackURL', value:History.getPageUrl()});
- // Some action buttons are redirecting to content areas as oposed to reloading the form.
- // They will have pjax-content class on them.
- var pjaxType = 'CurrentForm', pjaxSelector = '.cms-edit-form';
- if ($(button).hasClass('pjax-content')) {
- pjaxType = 'Content';
- pjaxSelector = '.cms-content';
- }
-
+ // Standard Pjax behaviour is to replace the submitted form with new content.
+ // The returned view isn't always decided upon when the request
+ // is fired, so the server might decide to change it based on its own logic,
+ // sending back different `X-Pjax` headers and content
jQuery.ajax(jQuery.extend({
headers: {
- "X-Pjax" : pjaxType,
- 'X-Pjax-Selector': pjaxSelector
+ "X-Pjax" : "CurrentForm",
+ 'X-Pjax-Selector': '.cms-edit-form'
},
url: form.attr('action'),
data: formData,
13 admin/javascript/LeftAndMain.js
View
@@ -36,13 +36,13 @@ jQuery.noConflict();
$(document).ajaxComplete(function(e, xhr, settings) {
// Simulates a redirect on an ajax response.
if(window.History.enabled) {
- var url = xhr.getResponseHeader('X-ControllerURL');
+ var url = xhr.getResponseHeader('X-ControllerURL'), opts, requestHeaders = settings.headers;
// Normalize trailing slashes in URL to work around routing weirdnesses in SS_HTTPRequest.
var isSame = (url && History.getPageUrl().replace(/\/+$/, '') == url.replace(/\/+$/, ''));
if(url && !isSame) {
- var opts = {
- pjax: settings.headers ? settings.headers['X-Pjax'] : null,
- selector: settings.headers ? settings.headers['X-Pjax-Selector'] : null
+ opts = {
+ pjax: xhr.getResponseHeader('X-Pjax') ? xhr.getResponseHeader('X-Pjax') : settings.headers['X-Pjax'],
+ selector: xhr.getResponseHeader('X-Pjax-Selector') ? xhr.getResponseHeader('X-Pjax-Selector') : settings.headers['X-Pjax-Selector']
};
window.History.pushState(opts, '', url);
}
@@ -216,11 +216,14 @@ jQuery.noConflict();
state: state, element: contentEl
});
+ // Set Pjax headers, which can declare a preference for the returned view.
+ // The actually returned view isn't always decided upon when the request
+ // is fired, so the server might decide to change it based on its own logic.
var headers = {};
if(state.data.pjax) {
headers['X-Pjax'] = state.data.pjax;
} else {
- // Replace full RHS content area
+ // Standard Pjax behaviour is to replace right content area
headers["X-Pjax"] = 'Content';
}
headers['X-Pjax-Selector'] = selector;
3  docs/en/reference/cms-architecture.md
View
@@ -183,6 +183,9 @@ Within the PHP logic, the `[api:PjaxResponseNegotiator]` class determines which
Through a custom `X-Pjax` HTTP header, the client can declare which view he's expecting,
through identifiers like `CurrentForm` or `Content` (see `[api:LeftAndMain->getResponseNegotiator()]`).
These identifiers are passed to `loadPanel()` via the `pjax` data option.
+Keep in mind that the returned view isn't always decided upon when the Ajax request
+is fired, so the server might decide to change it based on its own logic,
+sending back different `X-Pjax` headers and content.
## Ajax Redirects
4 forms/gridfield/GridFieldDetailForm.php
View
@@ -291,9 +291,8 @@ function ItemEditForm() {
if($this->record->ID !== 0) {
$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))
->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept'));
- // The delete action will redirect, hence pjax-content class.
$actions->push(FormAction::create('doDelete', _t('GridFieldDetailForm.Delete', 'Delete'))
- ->addExtraClass('ss-ui-action-destructive')->addExtraClass('pjax-content'));
+ ->addExtraClass('ss-ui-action-destructive'));
}else{ // adding new record
//Change the Save label to 'Create'
$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Create', 'Create'))
@@ -405,6 +404,7 @@ function doDelete($data, $form) {
//when an item is deleted, redirect to the revelant admin section without the action parameter
$controller = Controller::curr();
$noActionURL = $controller->removeAction($data['url']);
+ $controller->getRequest()->addHeader('X-Pjax', 'Content'); // Force a content refresh
return $controller->redirect($noActionURL, 302); //redirect back to admin section
}
Please sign in to comment.
Something went wrong with that request. Please try again.