Skip to content
This repository
Browse code

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 authored May 29, 2012
2  admin/code/LeftAndMain.php
@@ -351,6 +351,8 @@ function handleRequest(SS_HTTPRequest $request, DataModel $model = null) {
351 351
 	function redirect($url, $code=302) {
352 352
 		if($this->request->isAjax()) {
353 353
 			$this->response->addHeader('X-ControllerURL', $url);
  354
+			if($header = $this->request->getHeader('X-Pjax')) $this->response->addHeader('X-Pjax', $header);
  355
+			if($header = $this->request->getHeader('X-Pjax-Selector')) $this->response->addHeader('X-Pjax-Selector', $header);
354 356
 			return ''; // Actual response will be re-requested by client
355 357
 		} else {
356 358
 			parent::redirect($url, $code);
16  admin/javascript/LeftAndMain.Content.js
@@ -80,18 +80,14 @@
80 80
 				// as automatic browser ajax response redirects seem to discard the hash/fragment.
81 81
 				formData.push({name: 'BackURL', value:History.getPageUrl()});
82 82
 
83  
-				// Some action buttons are redirecting to content areas as oposed to reloading the form.
84  
-				// They will have pjax-content class on them.
85  
-				var pjaxType = 'CurrentForm', pjaxSelector = '.cms-edit-form';
86  
-				if ($(button).hasClass('pjax-content')) {
87  
-					pjaxType = 'Content';
88  
-					pjaxSelector = '.cms-content';
89  
-				}
90  
-
  83
+				// Standard Pjax behaviour is to replace the submitted form with new content.
  84
+				// The returned view isn't always decided upon when the request
  85
+				// is fired, so the server might decide to change it based on its own logic,
  86
+				// sending back different `X-Pjax` headers and content
91 87
 				jQuery.ajax(jQuery.extend({
92 88
 					headers: {
93  
-						"X-Pjax" : pjaxType,
94  
-						'X-Pjax-Selector': pjaxSelector
  89
+						"X-Pjax" : "CurrentForm",
  90
+						'X-Pjax-Selector': '.cms-edit-form'
95 91
 					},
96 92
 					url: form.attr('action'), 
97 93
 					data: formData,
13  admin/javascript/LeftAndMain.js
@@ -36,13 +36,13 @@ jQuery.noConflict();
36 36
 		$(document).ajaxComplete(function(e, xhr, settings) {
37 37
 			// Simulates a redirect on an ajax response.
38 38
 			if(window.History.enabled) {
39  
-				var url = xhr.getResponseHeader('X-ControllerURL');
  39
+				var url = xhr.getResponseHeader('X-ControllerURL'), opts, requestHeaders = settings.headers;
40 40
 				// Normalize trailing slashes in URL to work around routing weirdnesses in SS_HTTPRequest.
41 41
 				var isSame = (url && History.getPageUrl().replace(/\/+$/, '') == url.replace(/\/+$/, ''));
42 42
 				if(url && !isSame) {
43  
-					var opts = {
44  
-						pjax: settings.headers ? settings.headers['X-Pjax'] : null, 
45  
-						selector: settings.headers ? settings.headers['X-Pjax-Selector'] : null
  43
+					opts = {
  44
+						pjax: xhr.getResponseHeader('X-Pjax') ? xhr.getResponseHeader('X-Pjax') : settings.headers['X-Pjax'], 
  45
+						selector: xhr.getResponseHeader('X-Pjax-Selector') ? xhr.getResponseHeader('X-Pjax-Selector') : settings.headers['X-Pjax-Selector']
46 46
 					};
47 47
 					window.History.pushState(opts, '', url);
48 48
 				}
@@ -216,11 +216,14 @@ jQuery.noConflict();
216 216
 					state: state, element: contentEl
217 217
 				});
218 218
 
  219
+				// Set Pjax headers, which can declare a preference for the returned view.
  220
+				// The actually returned view isn't always decided upon when the request
  221
+				// is fired, so the server might decide to change it based on its own logic.
219 222
 				var headers = {};
220 223
 				if(state.data.pjax) {
221 224
 					headers['X-Pjax'] = state.data.pjax;
222 225
 				} else {
223  
-					// Replace full RHS content area
  226
+					// Standard Pjax behaviour is to replace right content area
224 227
 					headers["X-Pjax"] = 'Content';
225 228
 				}
226 229
 				headers['X-Pjax-Selector'] = selector;
3  docs/en/reference/cms-architecture.md
Source Rendered
@@ -183,6 +183,9 @@ Within the PHP logic, the `[api:PjaxResponseNegotiator]` class determines which
183 183
 Through a custom `X-Pjax` HTTP header, the client can declare which view he's expecting,
184 184
 through identifiers like `CurrentForm` or `Content` (see `[api:LeftAndMain->getResponseNegotiator()]`).
185 185
 These identifiers are passed to `loadPanel()` via the `pjax` data option.
  186
+Keep in mind that the returned view isn't always decided upon when the Ajax request
  187
+is fired, so the server might decide to change it based on its own logic,
  188
+sending back different `X-Pjax` headers and content.
186 189
 
187 190
 ## Ajax Redirects
188 191
 
4  forms/gridfield/GridFieldDetailForm.php
@@ -291,9 +291,8 @@ function ItemEditForm() {
291 291
 		if($this->record->ID !== 0) {
292 292
 			$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))
293 293
 				->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept'));
294  
-			// The delete action will redirect, hence pjax-content class.
295 294
 			$actions->push(FormAction::create('doDelete', _t('GridFieldDetailForm.Delete', 'Delete'))
296  
-				->addExtraClass('ss-ui-action-destructive')->addExtraClass('pjax-content'));
  295
+				->addExtraClass('ss-ui-action-destructive'));
297 296
 		}else{ // adding new record
298 297
 			//Change the Save label to 'Create'
299 298
 			$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Create', 'Create'))
@@ -405,6 +404,7 @@ function doDelete($data, $form) {
405 404
 		//when an item is deleted, redirect to the revelant admin section without the action parameter
406 405
 		$controller = Controller::curr();
407 406
 		$noActionURL = $controller->removeAction($data['url']);
  407
+		$controller->getRequest()->addHeader('X-Pjax', 'Content'); // Force a content refresh
408 408
 
409 409
 		return $controller->redirect($noActionURL, 302); //redirect back to admin section
410 410
 	}

0 notes on commit 5b03f49

Please sign in to comment.
Something went wrong with that request. Please try again.