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">&nbsp;</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 };