Mercurial > defr > drupal > core
comparison misc/ahah.js @ 1:c1f4ac30525a 6.0
Drupal 6.0
| author | Franck Deroche <webmaster@defr.org> |
|---|---|
| date | Tue, 23 Dec 2008 14:28:28 +0100 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:5a113a1c4740 | 1:c1f4ac30525a |
|---|---|
| 1 // $Id: ahah.js,v 1.7.2.1 2008/02/11 14:46:27 goba Exp $ | |
| 2 | |
| 3 /** | |
| 4 * Provides AJAX-like page updating via AHAH (Asynchronous HTML and HTTP). | |
| 5 * | |
| 6 * AHAH is a method of making a request via Javascript while viewing an HTML | |
| 7 * page. The request returns a small chunk of HTML, which is then directly | |
| 8 * injected into the page. | |
| 9 * | |
| 10 * Drupal uses this file to enhance form elements with #ahah[path] and | |
| 11 * #ahah[wrapper] properties. If set, this file will automatically be included | |
| 12 * to provide AHAH capabilities. | |
| 13 */ | |
| 14 | |
| 15 /** | |
| 16 * Attaches the ahah behavior to each ahah form element. | |
| 17 */ | |
| 18 Drupal.behaviors.ahah = function(context) { | |
| 19 for (var base in Drupal.settings.ahah) { | |
| 20 if (!$('#'+ base + '.ahah-processed').size()) { | |
| 21 var element_settings = Drupal.settings.ahah[base]; | |
| 22 | |
| 23 $(element_settings.selector).each(function() { | |
| 24 element_settings.element = this; | |
| 25 var ahah = new Drupal.ahah(base, element_settings); | |
| 26 }); | |
| 27 | |
| 28 $('#'+ base).addClass('ahah-processed'); | |
| 29 } | |
| 30 } | |
| 31 }; | |
| 32 | |
| 33 /** | |
| 34 * AHAH object. | |
| 35 */ | |
| 36 Drupal.ahah = function(base, element_settings) { | |
| 37 // Set the properties for this object. | |
| 38 this.element = element_settings.element; | |
| 39 this.selector = element_settings.selector; | |
| 40 this.event = element_settings.event; | |
| 41 this.keypress = element_settings.keypress; | |
| 42 this.url = element_settings.url; | |
| 43 this.wrapper = '#'+ element_settings.wrapper; | |
| 44 this.effect = element_settings.effect; | |
| 45 this.method = element_settings.method; | |
| 46 this.progress = element_settings.progress; | |
| 47 this.button = element_settings.button || { }; | |
| 48 | |
| 49 if (this.effect == 'none') { | |
| 50 this.showEffect = 'show'; | |
| 51 this.hideEffect = 'hide'; | |
| 52 this.showSpeed = ''; | |
| 53 } | |
| 54 else if (this.effect == 'fade') { | |
| 55 this.showEffect = 'fadeIn'; | |
| 56 this.hideEffect = 'fadeOut'; | |
| 57 this.showSpeed = 'slow'; | |
| 58 } | |
| 59 else { | |
| 60 this.showEffect = this.effect + 'Toggle'; | |
| 61 this.hideEffect = this.effect + 'Toggle'; | |
| 62 this.showSpeed = 'slow'; | |
| 63 } | |
| 64 | |
| 65 // Record the form action and target, needed for iFrame file uploads. | |
| 66 var form = $(this.element).parents('form'); | |
| 67 this.form_action = form.attr('action'); | |
| 68 this.form_target = form.attr('target'); | |
| 69 this.form_encattr = form.attr('encattr'); | |
| 70 | |
| 71 // Set the options for the ajaxSubmit function. | |
| 72 // The 'this' variable will not persist inside of the options object. | |
| 73 var ahah = this; | |
| 74 var options = { | |
| 75 url: ahah.url, | |
| 76 data: ahah.button, | |
| 77 beforeSubmit: function(form_values, element_settings, options) { | |
| 78 return ahah.beforeSubmit(form_values, element_settings, options); | |
| 79 }, | |
| 80 success: function(response, status) { | |
| 81 // Sanity check for browser support (object expected). | |
| 82 // When using iFrame uploads, responses must be returned as a string. | |
| 83 if (typeof(response) == 'string') { | |
| 84 response = Drupal.parseJson(response); | |
| 85 } | |
| 86 return ahah.success(response, status); | |
| 87 }, | |
| 88 complete: function(response, status) { | |
| 89 if (status == 'error' || status == 'parsererror') { | |
| 90 return ahah.error(response, ahah.url); | |
| 91 } | |
| 92 }, | |
| 93 dataType: 'json', | |
| 94 type: 'POST' | |
| 95 }; | |
| 96 | |
| 97 // Bind the ajaxSubmit function to the element event. | |
| 98 $(element_settings.element).bind(element_settings.event, function() { | |
| 99 $(element_settings.element).parents('form').ajaxSubmit(options); | |
| 100 return false; | |
| 101 }); | |
| 102 // If necessary, enable keyboard submission so that AHAH behaviors | |
| 103 // can be triggered through keyboard input as well as e.g. a mousedown | |
| 104 // action. | |
| 105 if (element_settings.keypress) { | |
| 106 $(element_settings.element).keypress(function(event) { | |
| 107 // Detect enter key. | |
| 108 if (event.keyCode == 13) { | |
| 109 $(element_settings.element).trigger(element_settings.event); | |
| 110 return false; | |
| 111 } | |
| 112 }); | |
| 113 } | |
| 114 }; | |
| 115 | |
| 116 /** | |
| 117 * Handler for the form redirection submission. | |
| 118 */ | |
| 119 Drupal.ahah.prototype.beforeSubmit = function (form_values, element, options) { | |
| 120 // Disable the element that received the change. | |
| 121 $(this.element).addClass('progress-disabled').attr('disabled', true); | |
| 122 | |
| 123 // Insert progressbar or throbber. | |
| 124 if (this.progress.type == 'bar') { | |
| 125 var progressBar = new Drupal.progressBar('ahah-progress-' + this.element.id, eval(this.progress.update_callback), this.progress.method, eval(this.progress.error_callback)); | |
| 126 if (this.progress.message) { | |
| 127 progressBar.setProgress(-1, this.progress.message); | |
| 128 } | |
| 129 if (this.progress.url) { | |
| 130 progressBar.startMonitoring(this.progress.url, this.progress.interval || 1500); | |
| 131 } | |
| 132 this.progress.element = $(progressBar.element).addClass('ahah-progress ahah-progress-bar'); | |
| 133 this.progress.object = progressBar; | |
| 134 $(this.element).after(this.progress.element); | |
| 135 } | |
| 136 else if (this.progress.type == 'throbber') { | |
| 137 this.progress.element = $('<div class="ahah-progress ahah-progress-throbber"><div class="throbber"> </div></div>'); | |
| 138 if (this.progress.message) { | |
| 139 $('.throbber', this.progress.element).after('<div class="message">' + this.progress.message + '</div>') | |
| 140 } | |
| 141 $(this.element).after(this.progress.element); | |
| 142 } | |
| 143 }; | |
| 144 | |
| 145 /** | |
| 146 * Handler for the form redirection completion. | |
| 147 */ | |
| 148 Drupal.ahah.prototype.success = function (response, status) { | |
| 149 var wrapper = $(this.wrapper); | |
| 150 var form = $(this.element).parents('form'); | |
| 151 // Manually insert HTML into the jQuery object, using $() directly crashes | |
| 152 // Safari with long string lengths. http://dev.jquery.com/ticket/1152 | |
| 153 var new_content = $('<div></div>').html(response.data); | |
| 154 | |
| 155 // Restore the previous action and target to the form. | |
| 156 form.attr('action', this.form_action); | |
| 157 this.form_target ? form.attr('target', this.form_target) : form.removeAttr('target'); | |
| 158 this.form_encattr ? form.attr('target', this.form_encattr) : form.removeAttr('encattr'); | |
| 159 | |
| 160 // Remove the progress element. | |
| 161 if (this.progress.element) { | |
| 162 $(this.progress.element).remove(); | |
| 163 } | |
| 164 if (this.progress.object) { | |
| 165 this.progress.object.stopMonitoring(); | |
| 166 } | |
| 167 $(this.element).removeClass('progress-disabled').attr('disabled', false); | |
| 168 | |
| 169 // Add the new content to the page. | |
| 170 Drupal.freezeHeight(); | |
| 171 if (this.method == 'replace') { | |
| 172 wrapper.empty().append(new_content); | |
| 173 } | |
| 174 else { | |
| 175 wrapper[this.method](new_content); | |
| 176 } | |
| 177 | |
| 178 // Immediately hide the new content if we're using any effects. | |
| 179 if (this.showEffect != 'show') { | |
| 180 new_content.hide(); | |
| 181 } | |
| 182 | |
| 183 // Determine what effect use and what content will receive the effect, then | |
| 184 // show the new content. For browser compatibility, Safari is excluded from | |
| 185 // using effects on table rows. | |
| 186 if (($.browser.safari && $("tr.ahah-new-content", new_content).size() > 0)) { | |
| 187 new_content.show(); | |
| 188 } | |
| 189 else if ($('.ahah-new-content', new_content).size() > 0) { | |
| 190 $('.ahah-new-content', new_content).hide(); | |
| 191 new_content.show(); | |
| 192 $(".ahah-new-content", new_content)[this.showEffect](this.showSpeed); | |
| 193 } | |
| 194 else if (this.showEffect != 'show') { | |
| 195 new_content[this.showEffect](this.showSpeed); | |
| 196 } | |
| 197 | |
| 198 // Attach all javascript behaviors to the new content, if it was successfully | |
| 199 // added to the page, this if statement allows #ahah[wrapper] to be optional. | |
| 200 if (new_content.parents('html').length > 0) { | |
| 201 Drupal.attachBehaviors(new_content); | |
| 202 } | |
| 203 | |
| 204 Drupal.unfreezeHeight(); | |
| 205 }; | |
| 206 | |
| 207 /** | |
| 208 * Handler for the form redirection error. | |
| 209 */ | |
| 210 Drupal.ahah.prototype.error = function (response, uri) { | |
| 211 alert(Drupal.ahahError(response, uri)); | |
| 212 // Resore the previous action and target to the form. | |
| 213 $(this.element).parent('form').attr( { action: this.form_action, target: this.form_target} ); | |
| 214 // Remove the progress element. | |
| 215 if (this.progress.element) { | |
| 216 $(this.progress.element).remove(); | |
| 217 } | |
| 218 if (this.progress.object) { | |
| 219 this.progress.object.stopMonitoring(); | |
| 220 } | |
| 221 // Undo hide. | |
| 222 $(this.wrapper).show(); | |
| 223 // Re-enable the element. | |
| 224 $(this.element).removeClass('progess-disabled').attr('disabled', false); | |
| 225 }; |
