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 }; |