Permalink
Browse files

API CHANGE Moved submitForm() from $('.cms-content') to $('.cms-conta…

…iner'), unifying ajax response handling between panel loading and form submission
  • Loading branch information...
1 parent b3d99d5 commit 75e51de9ed26bbb0138460d6529f1e8c4f2d815a @chillu chillu committed May 30, 2012
@@ -91,7 +91,7 @@
data.push({name:button.attr('name'),value:button.val()});
// TODO Should be set by hiddenfield already
- $('.cms-content').submitForm(
+ $('.cms-container').submitForm(
this,
button,
function() {
@@ -27,168 +27,6 @@
this.add(this.find('.cms-tabset')).redrawTabs();
this.layout();
- },
-
- /**
- * Function: ajaxSubmit
- *
- * Parameters:
- * {DOMElement} button - The pressed button (optional)
- * {Function} callback - Called in complete() handler of jQuery.ajax()
- * {Object} ajaxOptions - Object literal to merge into $.ajax() call
- * {boolean} loadResponse - Render response through _loadResponse() (Default: true)
- *
- * Returns:
- * (boolean)
- */
- submitForm: function(form, button, callback, ajaxOptions, loadResponse) {
- var self = this;
-
- // look for save button
- if(!button) button = this.find('.Actions :submit[name=action_save]');
- // default to first button if none given - simulates browser behaviour
- if(!button) button = this.find('.Actions :submit:first');
-
- form.trigger('beforesave');
- this.trigger('submitform', {form: form, button: button});
-
- // set button to "submitting" state
- $(button).addClass('loading');
-
- // validate if required
- if(!form.validate()) {
- // TODO Automatically switch to the tab/position of the first error
- statusMessage("Validation failed.", "bad");
-
- $(button).removeClass('loading');
-
- return false;
- }
-
- // save tab selections in order to reconstruct them later
- var selectedTabs = [];
- form.find('.cms-tabset').each(function(i, el) {
- if($(el).attr('id')) selectedTabs.push({id:$(el).attr('id'), selected:$(el).tabs('option', 'selected')});
- });
-
- // get all data from the form
- var formData = form.serializeArray();
- // add button action
- formData.push({name: $(button).attr('name'), value:'1'});
- // Artificial HTTP referer, IE doesn't submit them via ajax.
- // Also rewrites anchors to their page counterparts, which is important
- // as automatic browser ajax response redirects seem to discard the hash/fragment.
- formData.push({name: 'BackURL', value:History.getPageUrl()});
-
- // 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" : "CurrentForm,Breadcrumbs"
- },
- url: form.attr('action'),
- data: formData,
- type: 'POST',
- complete: function(xmlhttp, status) {
- $(button).removeClass('loading');
-
- // TODO This should be using the plugin API
- form.removeClass('changed');
-
- if(callback) callback(xmlhttp, status);
-
- // pass along original form data to enable old/new comparisons
- if(loadResponse !== false) {
- self.submitForm_responseHandler(form, xmlhttp.responseText, status, xmlhttp, formData);
- }
-
- // Re-init tabs (in case the form tag itself is a tabset)
- if(self.hasClass('cms-tabset')) self.removeClass('cms-tabset').addClass('cms-tabset');
-
- // re-select previously saved tabs
- $.each(selectedTabs, function(i, selectedTab) {
- form.find('#' + selectedTab.id).tabs('select', selectedTab.selected);
- });
-
- // Redraw the layout
- $('.cms-container').redraw();
- },
- dataType: 'html'
- }, ajaxOptions));
-
- return false;
- },
-
- /**
- * Function: _loadResponse
- *
- * Parameters:
- * {String} data - Either HTML for straight insertion, or eval'ed JavaScript.
- * If passed as HTML, it is assumed that everying inside the <form> tag is replaced,
- * but the old <form> tag itself stays intact.
- * {String} status
- * {XMLHTTPRequest} xmlhttp - ..
- * {Array} origData - The original submitted data, useful to do comparisons of changed
- * values in new form output, e.g. to detect a URLSegment being changed on the serverside.
- * Array in jQuery serializeArray() notation.
- */
- submitForm_responseHandler: function(oldForm, data, status, xmlhttp, origData) {
- if(status == 'success') {
- if(!data) return;
-
- var form, newContent = $(data);
-
- // HACK If response contains toplevel panel rather than a form, replace it instead.
- // For example, a page view shows tree + edit form. Deleting this page redirects to
- // the "pages" overview, which doesn't have a separate tree panel.
- if(newContent.is('.cms-content')) {
- $('.cms-content').replaceWith(newContent);
- } else {
- form = this.replaceForm(oldForm, newContent);
- }
-
- if(typeof(Behaviour) != 'undefined') Behaviour.apply(); // refreshes ComplexTableField
-
- this.trigger('reloadeditform', {form: form, origData: origData, xmlhttp: xmlhttp});
- }
- },
-
- /**
- * @return {jQuery} New form element
- */
- replaceForm: function(form, html) {
- if(html) {
- var parent = form.parent(), id = form.attr('id');
- form.replaceWith(html);
- // Try to get the new form by ID (assuming they're identical), otherwise fall back to the first form in the parent
- return id ? $('#' + id) : parent.children('form:first');
- } else {
- this.removeForm(form);
- return null;
- }
- },
-
- /**
- * Function: removeForm
- *
- * Remove everying inside the <form> tag
- * with a custom HTML fragment. Useful e.g. for deleting a page in the CMS.
- * Checks for unsaved changes before removing the form
- *
- * Parameters:
- * {String} placeholderHtml - Short note why the form has been removed, displayed in <p> tags.
- * Falls back to the default RemoveText() option (Optional)
- */
- removeForm: function(form, placeholderHtml) {
- if(!placeholderHtml) placeholderHtml = this.getPlaceholderHtml();
- // Alert when unsaved changes are present
- if(!form.confirmUnsavedChanges()) return;
- this.trigger('removeform');
- this.html(placeholderHtml);
- // TODO This should be using the plugin API
- this.removeClass('changed');
}
});
@@ -29,7 +29,6 @@
* Events:
* ajaxsubmit - Form is about to be submitted through ajax
* validate - Contains validation result
- * removeform - A form is about to be removed from the DOM
* load - Form is about to be loaded through ajax
*/
$('.cms-edit-form').entwine(/** @lends ss.Form_EditForm */{
@@ -158,7 +157,7 @@
// which means the browser auto-selects the first available form button.
// This might be an unrelated button of the form field,
// or a destructive action (if "save" is not available, or not on first position).
- if(button) this.closest('.cms-content').submitForm(this, button);
+ if(button) this.closest('.cms-container').submitForm(this, button);
return false;
},
@@ -178,6 +178,98 @@ jQuery.noConflict();
window.location = $.path.makeUrlAbsolute(url, $('base').attr('href'));
}
},
+
+ /**
+ * Function: submitForm
+ *
+ * Parameters:
+ * {DOMElement} form - The form to be submitted. Needs to be passed
+ * in to avoid entwine methods/context being removed through replacing the node itself.
+ * {DOMElement} button - The pressed button (optional)
+ * {Function} callback - Called in complete() handler of jQuery.ajax()
+ * {Object} ajaxOptions - Object literal to merge into $.ajax() call
+ *
+ * Returns:
+ * (boolean)
+ */
+ submitForm: function(form, button, callback, ajaxOptions) {
+ var self = this;
+
+ // look for save button
+ if(!button) button = this.find('.Actions :submit[name=action_save]');
+ // default to first button if none given - simulates browser behaviour
+ if(!button) button = this.find('.Actions :submit:first');
+
+ form.trigger('beforesave');
+ this.trigger('submitform', {form: form, button: button});
+
+ // set button to "submitting" state
+ $(button).addClass('loading');
+
+ // validate if required
+ if(!form.validate()) {
+ // TODO Automatically switch to the tab/position of the first error
+ statusMessage("Validation failed.", "bad");
+
+ $(button).removeClass('loading');
+
+ return false;
+ }
+
+ // save tab selections in order to reconstruct them later
+ var selectedTabs = [];
+ form.find('.cms-tabset').each(function(i, el) {
+ if($(el).attr('id')) selectedTabs.push({id:$(el).attr('id'), selected:$(el).tabs('option', 'selected')});
+ });
+
+ // get all data from the form
+ var formData = form.serializeArray();
+ // add button action
+ formData.push({name: $(button).attr('name'), value:'1'});
+ // Artificial HTTP referer, IE doesn't submit them via ajax.
+ // Also rewrites anchors to their page counterparts, which is important
+ // as automatic browser ajax response redirects seem to discard the hash/fragment.
+ formData.push({name: 'BackURL', value:History.getPageUrl()});
+
+ // 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" : "CurrentForm,Breadcrumbs"},
+ url: form.attr('action'),
+ data: formData,
+ type: 'POST',
+ complete: function() {
+ $(button).removeClass('loading');
+ },
+ success: function(data, status, xhr) {
+ form.removeClass('changed'); // TODO This should be using the plugin API
+ if(callback) callback(xmlhttp, status);
+
+ var newContentEls = self.handleAjaxResponse(data, status, xhr);
+ if(!newContentEls) return;
+
+ var newForm = newContentEls.filter('form');
+
+ // Re-init tabs (in case the form tag itself is a tabset)
+ if(newForm.hasClass('cms-tabset')) newForm.removeClass('cms-tabset').addClass('cms-tabset');
+
+ // re-select previously saved tabs
+ $.each(selectedTabs, function(i, selectedTab) {
+ newForm.find('#' + selectedTab.id).tabs('select', selectedTab.selected);
+ });
+
+ // Redraw the layout
+ $('.cms-container').redraw();
+
+ form.trigger('reloadeditform', {form: newForm, formData: formData, xmlhttp: xhr});
+ },
+ dataType: 'json'
+ }, ajaxOptions));
+
+ return false;
+ },
/**
* Handles ajax loading of new panels through the window.History object.

0 comments on commit 75e51de

Please sign in to comment.