summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorGábor Hojtsy <gabor@hojtsy.hu>2007-10-05 09:35:09 +0000
committerGábor Hojtsy <gabor@hojtsy.hu>2007-10-05 09:35:09 +0000
commit31b73898af536da873e12cc0cf6f3a4ee7b7d9cc (patch)
treedd33ce8708f6b929a11b79ae90a2a6957afbe54f /misc
parent5fc06cec4c440ac21b3913c0c9b0c892a6091bb9 (diff)
downloadbrdo-31b73898af536da873e12cc0cf6f3a4ee7b7d9cc.tar.gz
brdo-31b73898af536da873e12cc0cf6f3a4ee7b7d9cc.tar.bz2
#157752 by quicksketch: extend AHAH functionality to most types of form elements, without writing JavaScript. Also AHAH enable the blocks admin page.
Diffstat (limited to 'misc')
-rw-r--r--misc/ahah.js136
-rw-r--r--misc/drupal.js102
2 files changed, 104 insertions, 134 deletions
diff --git a/misc/ahah.js b/misc/ahah.js
index 87ab19404..af226ced4 100644
--- a/misc/ahah.js
+++ b/misc/ahah.js
@@ -7,8 +7,8 @@
* page. The request returns a small chunk of HTML, which is then directly
* injected into the page.
*
- * Drupal uses this file to enhance form elements with #ahah_path and
- * #ahah_wrapper properties. If set, this file will automatically be included
+ * Drupal uses this file to enhance form elements with #ahah[path] and
+ * #ahah[wrapper] properties. If set, this file will automatically be included
* to provide AHAH capabilities.
*/
@@ -18,8 +18,13 @@
Drupal.behaviors.ahah = function(context) {
for (var base in Drupal.settings.ahah) {
if (!$('#'+ base + '.ahah-processed').size()) {
- var element = Drupal.settings.ahah[base];
- var ahah = new Drupal.ahah(base, element);
+ var element_settings = Drupal.settings.ahah[base];
+
+ $(element_settings.selector).each(function() {
+ element_settings.element = this;
+ var ahah = new Drupal.ahah(base, element_settings);
+ });
+
$('#'+ base).addClass('ahah-processed');
}
}
@@ -28,95 +33,148 @@ Drupal.behaviors.ahah = function(context) {
/**
* AHAH object.
*/
-Drupal.ahah = function(base, element) {
+Drupal.ahah = function(base, element_settings) {
// Set the properties for this object.
- this.id = '#' + base;
- this.event = element.event;
- this.uri = element.uri;
- this.wrapper = '#'+ element.wrapper;
- this.effect = element.effect;
- this.method = element.method;
+ this.element = element_settings.element;
+ this.selector = element_settings.selector;
+ this.event = element_settings.event;
+ this.url = element_settings.url;
+ this.wrapper = '#'+ element_settings.wrapper;
+ this.effect = element_settings.effect;
+ this.method = element_settings.method;
if (this.effect == 'none') {
this.showEffect = 'show';
this.hideEffect = 'hide';
+ this.showSpeed = '';
}
else if (this.effect == 'fade') {
this.showEffect = 'fadeIn';
this.hideEffect = 'fadeOut';
+ this.showSpeed = 'slow';
}
else {
this.showEffect = this.effect + 'Toggle';
this.hideEffect = this.effect + 'Toggle';
+ this.showSpeed = 'slow';
}
- Drupal.redirectFormButton(this.uri, $(this.id).get(0), this);
+
+ // Record the form action and target, needed for iFrame file uploads.
+ var form = $(this.element).parents('form');
+ this.form_action = form.attr('action');
+ this.form_target = form.attr('target');
+ this.form_encattr = form.attr('encattr');
+
+ // Set the options for the ajaxSubmit function.
+ // The 'this' variable will not persist inside of the options object.
+ var ahah = this;
+ var options = {
+ url: ahah.url,
+ beforeSubmit: function(form_values, element_settings, options) {
+ return ahah.beforeSubmit(form_values, element_settings, options);
+ },
+ success: function(response, status) {
+ // Sanity check for browser support (object expected).
+ // When using iFrame uploads, responses must be returned as a string.
+ if (typeof(response) == 'string') {
+ response = Drupal.parseJson(response);
+ }
+ return ahah.success(response, status);
+ },
+ complete: function(response, status) {
+ if (status == 'error') {
+ return ahah.error(response.responseText);
+ }
+ },
+ dataType: 'json',
+ type: 'POST'
+ };
+
+ // Bind the ajaxSubmit function to the element event.
+ $(element_settings.element).bind(element_settings.event, function() {
+ $(element_settings.element).parents('form').ajaxSubmit(options);
+ return false;
+ });
};
/**
* Handler for the form redirection submission.
*/
-Drupal.ahah.prototype.onsubmit = function () {
+Drupal.ahah.prototype.beforeSubmit = function (form_values, element, options) {
// Insert progressbar and stretch to take the same space.
this.progress = new Drupal.progressBar('ahah_progress');
this.progress.setProgress(-1, Drupal.t('Please wait...'));
- var wrapper = $(this.wrapper);
- var button = $(this.id);
- var progress_element = $(this.progress.element);
-
- progress_element.css('float', 'left').css({
- display: 'none',
- width: '10em',
- margin: '0 0 0 20px'
- });
- button.css('float', 'left').attr('disabled', true).after(progress_element);
- if (progress_element[this.showEffect]) {
- progress_element[this.showEffect]();
- }
+ var progress_element = $(this.progress.element).addClass('ahah-progress');
+ $(this.element).addClass('progress-disabled').attr('disabled', true).after(progress_element);
};
/**
* Handler for the form redirection completion.
*/
-Drupal.ahah.prototype.oncomplete = function (data) {
+Drupal.ahah.prototype.success = function (response, status) {
var wrapper = $(this.wrapper);
- var button = $(this.id);
+ var form = $(this.element).parents('form');
var progress_element = $(this.progress.element);
- var new_content = $('<div>' + data + '</div>');
+ // Manually insert HTML into the jQuery object, using $() directly crashes
+ // Safari with long string lengths. http://dev.jquery.com/ticket/1152
+ var new_content = $('<div></div>').html(response.data);
- Drupal.freezeHeight();
+ // Restore the previous action and target to the form.
+ form.attr('action', this.form_action);
+ this.form_target ? form.attr('target', this.form_target) : form.removeAttr('target');
+ this.form_encattr ? form.attr('target', this.form_encattr) : form.removeAttr('encattr');
// Remove the progress element.
progress_element.remove();
+ $(this.element).removeClass('progess-disabled').attr('disabled', false);
// Hide the new content before adding to page.
- new_content.hide();
+ if (this.showEffect != 'show') {
+ new_content.hide();
+ }
- // Add the form and re-attach behavior.
+ // Add the new content to the page.
+ Drupal.freezeHeight();
if (this.method == 'replace') {
wrapper.empty().append(new_content);
}
- else if (wrapper[this.method]) {
+ else {
wrapper[this.method](new_content);
}
- if (new_content[this.showEffect]) {
- new_content[this.showEffect]();
+
+ // Determine what effect use and what content will receive the effect, then
+ // show the new content. For browser compatibility, Safari is excluded from
+ // using effects on table rows.
+ if ($('.ahah-new-content', new_content).size() > 0 && !($.browser.safari && $("tr.ahah-new-content", new_content).size() > 0)) {
+ $('.ahah-new-content', new_content).hide();
+ new_content.show();
+ $(".ahah-new-content", new_content)[this.showEffect](this.showSpeed);
+ }
+ else if (this.showEffect != 'show') {
+ new_content[this.showEffect](this.showSpeed);
+ }
+
+ // Attach all javascript behaviors to the new content, if it was successfully
+ // added to the page, this if statement allows #ahah[wrapper] to be optional.
+ if (new_content.parents('html').length > 0) {
+ Drupal.attachBehaviors(new_content);
}
- button.css('float', 'none').attr('disabled', false);
- Drupal.attachBehaviors(new_content);
Drupal.unfreezeHeight();
};
/**
* Handler for the form redirection error.
*/
-Drupal.ahah.prototype.onerror = function (error) {
+Drupal.ahah.prototype.error = function (error) {
alert(Drupal.t('An error occurred:\n\n@error', { '@error': error }));
+ // Resore the previous action and target to the form.
+ element.parent('form').attr( { action: this.form_action, target: this.form_target} );
// Remove progressbar.
$(this.progress.element).remove();
this.progress = null;
// Undo hide.
$(this.wrapper).show();
// Re-enable the element.
- $(this.id).css('float', 'none').attr('disabled', false);
+ $(this.element).removeClass('progess-disabled').attr('disabled', false);
};
diff --git a/misc/drupal.js b/misc/drupal.js
index c7e955aae..edf621101 100644
--- a/misc/drupal.js
+++ b/misc/drupal.js
@@ -181,103 +181,15 @@ Drupal.theme = function(func) {
};
/**
- * Redirects a button's form submission to a hidden iframe and displays the result
- * in a given wrapper. The iframe should contain a call to
- * window.parent.iframeHandler() after submission.
- */
-Drupal.redirectFormButton = function (uri, button, handler) {
- // Trap the button
- button.onmouseover = button.onfocus = function() {
- button.onclick = function() {
- // Create target iframe
- Drupal.deleteIframe();
- Drupal.createIframe();
-
- // Prepare variables for use in anonymous function.
- var button = this;
- var action = button.form.action;
- var target = button.form.target;
-
- // Redirect form submission to iframe
- this.form.action = uri;
- this.form.target = 'redirect-target';
- this.form.submit();
-
- handler.onsubmit();
-
- // Set iframe handler for later
- window.iframeHandler = function () {
- var iframe = $('#redirect-target').get(0);
- // Restore form submission
- button.form.action = action;
- button.form.target = target;
-
- // Get response from iframe body
- try {
- response = (iframe.contentWindow || iframe.contentDocument || iframe).document.body.innerHTML;
- // Firefox 1.0.x hack: Remove (corrupted) control characters
- response = response.replace(/[\f\n\r\t]/g, ' ');
- if (window.opera) {
- // Opera-hack: it returns innerHTML sanitized.
- response = response.replace(/&quot;/g, '"');
- }
- }
- catch (e) {
- response = null;
- }
-
- response = eval('('+ response +');');
- // Check response code
- if (!response || response.status == 0) {
- handler.onerror(response.data || Drupal.t('Error parsing response'));
- return;
- }
- handler.oncomplete(response.data);
-
- return true;
- };
-
- return true;
- };
- };
- button.onmouseout = button.onblur = function() {
- button.onclick = null;
- };
-};
-
-/**
- * Create an invisible iframe for form submissions.
+ * Parse a JSON response.
+ *
+ * The result is either the JSON object, or an object with 'status' 0 and 'data' an error message.
*/
-Drupal.createIframe = function () {
- if ($('#redirect-holder').size()) {
- return;
+Drupal.parseJson = function (data) {
+ if ((data.substring(0, 1) != '{') && (data.substring(0, 1) != '[')) {
+ return { status: 0, data: data.length ? data : Drupal.t('Unspecified error') };
}
- // Note: some browsers require the literal name/id attributes on the tag,
- // some want them set through JS. We do both.
- window.iframeHandler = function () {};
- var div = document.createElement('div');
- div.id = 'redirect-holder';
- $(div).html('<iframe name="redirect-target" id="redirect-target" class="redirect" onload="window.iframeHandler();"></iframe>');
- var iframe = div.firstChild;
- $(iframe)
- .attr({
- name: 'redirect-target',
- id: 'redirect-target'
- })
- .css({
- position: 'absolute',
- height: '1px',
- width: '1px',
- visibility: 'hidden'
- });
- $('body').append(div);
-};
-
-/**
- * Delete the invisible iframe
- */
-Drupal.deleteIframe = function () {
- $('#redirect-holder').remove();
+ return eval('(' + data + ');');
};
/**