1 // $Id: ajax-responder.js,v 1.18.2.6 2010/01/22 06:48:08 merlinofchaos Exp $ |
|
2 /** |
|
3 * @file |
|
4 * |
|
5 * CTools flexible AJAX responder object. |
|
6 */ |
|
7 |
|
8 (function ($) { |
|
9 Drupal.CTools = Drupal.CTools || {}; |
|
10 Drupal.CTools.AJAX = Drupal.CTools.AJAX || {}; |
|
11 Drupal.CTools.AJAX.commands = Drupal.CTools.AJAX.commands || {}; |
|
12 |
|
13 /** |
|
14 * Success callback for an ajax request. |
|
15 * |
|
16 * This function expects to receive a packet of data from a JSON object |
|
17 * which is essentially a list of commands. Each commands must have a |
|
18 * 'command' setting and this setting must resolve to a function in the |
|
19 * Drupal.CTools.AJAX.commands space. |
|
20 */ |
|
21 Drupal.CTools.AJAX.respond = function(data) { |
|
22 for (i in data) { |
|
23 if (data[i]['command'] && Drupal.CTools.AJAX.commands[data[i]['command']]) { |
|
24 Drupal.CTools.AJAX.commands[data[i]['command']](data[i]); |
|
25 } |
|
26 } |
|
27 }; |
|
28 |
|
29 /** |
|
30 * Generic replacement click handler to open the modal with the destination |
|
31 * specified by the href of the link. |
|
32 */ |
|
33 Drupal.CTools.AJAX.clickAJAXLink = function() { |
|
34 if ($(this).hasClass('ctools-ajaxing')) { |
|
35 return false; |
|
36 } |
|
37 |
|
38 var url = $(this).attr('href'); |
|
39 var object = $(this); |
|
40 $(this).addClass('ctools-ajaxing'); |
|
41 try { |
|
42 url = url.replace(/nojs/g, 'ajax'); |
|
43 $.ajax({ |
|
44 type: "POST", |
|
45 url: url, |
|
46 data: { 'js': 1, 'ctools_ajax': 1 }, |
|
47 global: true, |
|
48 success: Drupal.CTools.AJAX.respond, |
|
49 error: function(xhr) { |
|
50 Drupal.CTools.AJAX.handleErrors(xhr, url); |
|
51 }, |
|
52 complete: function() { |
|
53 object.removeClass('ctools-ajaxing'); |
|
54 }, |
|
55 dataType: 'json' |
|
56 }); |
|
57 } |
|
58 catch (err) { |
|
59 alert("An error occurred while attempting to process " + url); |
|
60 $(this).removeClass('ctools-ajaxing'); |
|
61 return false; |
|
62 } |
|
63 |
|
64 return false; |
|
65 }; |
|
66 |
|
67 /** |
|
68 * Generic replacement click handler to open the modal with the destination |
|
69 * specified by the href of the link. |
|
70 */ |
|
71 Drupal.CTools.AJAX.clickAJAXButton = function() { |
|
72 if ($(this).hasClass('ctools-ajaxing')) { |
|
73 return false; |
|
74 } |
|
75 |
|
76 // Put our button in. |
|
77 this.form.clk = this; |
|
78 |
|
79 var url = Drupal.CTools.AJAX.findURL(this); |
|
80 $(this).addClass('ctools-ajaxing'); |
|
81 var object = $(this); |
|
82 try { |
|
83 if (url) { |
|
84 url = url.replace('/nojs/', '/ajax/'); |
|
85 $.ajax({ |
|
86 type: "POST", |
|
87 url: url, |
|
88 data: { 'js': 1, 'ctools_ajax': 1 }, |
|
89 global: true, |
|
90 success: Drupal.CTools.AJAX.respond, |
|
91 error: function(xhr) { |
|
92 Drupal.CTools.AJAX.handleErrors(xhr, url); |
|
93 }, |
|
94 complete: function() { |
|
95 object.removeClass('ctools-ajaxing'); |
|
96 }, |
|
97 dataType: 'json' |
|
98 }); |
|
99 } |
|
100 else { |
|
101 var form = this.form; |
|
102 url = $(form).attr('action'); |
|
103 url = url.replace('/nojs/', '/ajax/'); |
|
104 $(form).ajaxSubmit({ |
|
105 type: "POST", |
|
106 url: url, |
|
107 data: { 'js': 1, 'ctools_ajax': 1 }, |
|
108 global: true, |
|
109 success: Drupal.CTools.AJAX.respond, |
|
110 error: function(xhr) { |
|
111 Drupal.CTools.AJAX.handleErrors(xhr, url); |
|
112 }, |
|
113 complete: function() { |
|
114 object.removeClass('ctools-ajaxing'); |
|
115 }, |
|
116 dataType: 'json' |
|
117 }); |
|
118 } |
|
119 } |
|
120 catch (err) { |
|
121 alert("An error occurred while attempting to process " + url); |
|
122 $(this).removeClass('ctools-ajaxing'); |
|
123 return false; |
|
124 } |
|
125 return false; |
|
126 }; |
|
127 |
|
128 /** |
|
129 * Display error in a more fashion way |
|
130 */ |
|
131 Drupal.CTools.AJAX.handleErrors = function(xhr, path) { |
|
132 var error_text = ''; |
|
133 |
|
134 if ((xhr.status == 500 && xhr.responseText) || xhr.status == 200) { |
|
135 error_text = xhr.responseText; |
|
136 |
|
137 // Replace all < and > by < and > |
|
138 error_text = error_text.replace("/&(lt|gt);/g", function (m, p) { |
|
139 return (p == "lt")? "<" : ">"; |
|
140 }); |
|
141 |
|
142 // Now, replace all html tags by empty spaces |
|
143 error_text = error_text.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi,""); |
|
144 |
|
145 // Fix end lines |
|
146 error_text = error_text.replace(/[\n]+\s+/g,"\n"); |
|
147 } |
|
148 else if (xhr.status == 500) { |
|
149 error_text = xhr.status + ': ' + Drupal.t("Internal server error. Please see server or PHP logs for error information."); |
|
150 } |
|
151 else { |
|
152 error_text = xhr.status + ': ' + xhr.statusText; |
|
153 } |
|
154 |
|
155 alert(Drupal.t("An error occurred at @path.\n\nError Description: @error", {'@path': path, '@error': error_text})); |
|
156 } |
|
157 |
|
158 /** |
|
159 * Generic replacement for change handler to execute ajax method. |
|
160 */ |
|
161 Drupal.CTools.AJAX.changeAJAX = function () { |
|
162 if ($(this).hasClass('ctools-ajaxing')) { |
|
163 return false; |
|
164 } |
|
165 |
|
166 var url = Drupal.CTools.AJAX.findURL(this); |
|
167 $(this).addClass('ctools-ajaxing'); |
|
168 var object = $(this); |
|
169 var form_id = $(object).parents('form').get(0).id; |
|
170 try { |
|
171 if (url) { |
|
172 url = url.replace('/nojs/', '/ajax/'); |
|
173 $.ajax({ |
|
174 type: "POST", |
|
175 url: url, |
|
176 data: {'ctools_changed': $(this).val(), 'js': 1, 'ctools_ajax': 1 }, |
|
177 global: true, |
|
178 success: Drupal.CTools.AJAX.respond, |
|
179 error: function(xhr) { |
|
180 Drupal.CTools.AJAX.handleErrors(xhr, url); |
|
181 }, |
|
182 complete: function() { |
|
183 object.removeClass('ctools-ajaxing'); |
|
184 if ($(object).hasClass('ctools-ajax-submit-onchange')) { |
|
185 $('form#' + form_id).submit(); |
|
186 } |
|
187 }, |
|
188 dataType: 'json' |
|
189 }); |
|
190 } |
|
191 else { |
|
192 if ($(object).hasClass('ctools-ajax-submit-onchange')) { |
|
193 $('form#' + form_id).submit(); |
|
194 } |
|
195 return false; |
|
196 } |
|
197 } |
|
198 catch (err) { |
|
199 alert("An error occurred while attempting to process " + url); |
|
200 $(this).removeClass('ctools-ajaxing'); |
|
201 return false; |
|
202 } |
|
203 return false; |
|
204 }; |
|
205 |
|
206 /** |
|
207 * Find a URL for an AJAX button. |
|
208 * |
|
209 * The URL for this gadget will be composed of the values of items by |
|
210 * taking the ID of this item and adding -url and looking for that |
|
211 * class. They need to be in the form in order since we will |
|
212 * concat them all together using '/'. |
|
213 */ |
|
214 Drupal.CTools.AJAX.findURL = function(item) { |
|
215 var url = ''; |
|
216 var url_class = '.' + $(item).attr('id') + '-url'; |
|
217 $(url_class).each( |
|
218 function() { |
|
219 if (url && $(this).val()) { |
|
220 url += '/'; |
|
221 } |
|
222 url += $(this).val(); |
|
223 }); |
|
224 return url; |
|
225 }; |
|
226 |
|
227 Drupal.CTools.AJAX.commands.prepend = function(data) { |
|
228 $(data.selector).prepend(data.data); |
|
229 Drupal.attachBehaviors($(data.selector)); |
|
230 }; |
|
231 |
|
232 Drupal.CTools.AJAX.commands.append = function(data) { |
|
233 $(data.selector).append(data.data); |
|
234 Drupal.attachBehaviors($(data.selector)); |
|
235 }; |
|
236 |
|
237 Drupal.CTools.AJAX.commands.replace = function(data) { |
|
238 $(data.selector).replaceWith(data.data); |
|
239 Drupal.attachBehaviors($(data.selector)); |
|
240 }; |
|
241 |
|
242 Drupal.CTools.AJAX.commands.after = function(data) { |
|
243 var object = $(data.data); |
|
244 $(data.selector).after(object); |
|
245 Drupal.attachBehaviors(object); |
|
246 }; |
|
247 |
|
248 Drupal.CTools.AJAX.commands.before = function(data) { |
|
249 var object = $(data.data); |
|
250 $(data.selector).before(object); |
|
251 Drupal.attachBehaviors(object); |
|
252 }; |
|
253 |
|
254 Drupal.CTools.AJAX.commands.html = function(data) { |
|
255 $(data.selector).html(data.data); |
|
256 Drupal.attachBehaviors($(data.selector)); |
|
257 }; |
|
258 |
|
259 Drupal.CTools.AJAX.commands.remove = function(data) { |
|
260 $(data.selector).remove(); |
|
261 }; |
|
262 |
|
263 Drupal.CTools.AJAX.commands.changed = function(data) { |
|
264 if (!$(data.selector).hasClass('changed')) { |
|
265 $(data.selector).addClass('changed'); |
|
266 if (data.star) { |
|
267 $(data.selector).find(data.star).append(' <span class="star">*</span> '); |
|
268 } |
|
269 } |
|
270 }; |
|
271 |
|
272 Drupal.CTools.AJAX.commands.alert = function(data) { |
|
273 alert(data.text, data.title); |
|
274 }; |
|
275 |
|
276 Drupal.CTools.AJAX.commands.css = function(data) { |
|
277 /* |
|
278 if (data.selector && data.selector.contains('* html ')) { |
|
279 // This indicates an IE hack and we should only do it if we are IE. |
|
280 if (!jQuery.browser.msie) { |
|
281 return; |
|
282 } |
|
283 data.selector = data.selector.replace('* html ', ''); |
|
284 } |
|
285 */ |
|
286 $(data.selector).css(data.argument); |
|
287 }; |
|
288 |
|
289 Drupal.CTools.AJAX.commands.settings = function(data) { |
|
290 $.extend(Drupal.settings, data.argument); |
|
291 }; |
|
292 |
|
293 Drupal.CTools.AJAX.commands.data = function(data) { |
|
294 $(data.selector).data(data.name, data.value); |
|
295 }; |
|
296 |
|
297 Drupal.CTools.AJAX.commands.attr = function(data) { |
|
298 $(data.selector).attr(data.name, data.value); |
|
299 }; |
|
300 |
|
301 Drupal.CTools.AJAX.commands.restripe = function(data) { |
|
302 // :even and :odd are reversed because jquery counts from 0 and |
|
303 // we count from 1, so we're out of sync. |
|
304 $('tbody tr:not(:hidden)', $(data.selector)) |
|
305 .removeClass('even') |
|
306 .removeClass('odd') |
|
307 .filter(':even') |
|
308 .addClass('odd') |
|
309 .end() |
|
310 .filter(':odd') |
|
311 .addClass('even'); |
|
312 }; |
|
313 |
|
314 Drupal.CTools.AJAX.commands.redirect = function(data) { |
|
315 location.href = data.url; |
|
316 }; |
|
317 |
|
318 Drupal.CTools.AJAX.commands.reload = function(data) { |
|
319 location.reload(); |
|
320 }; |
|
321 |
|
322 Drupal.CTools.AJAX.commands.submit = function(data) { |
|
323 $(data.selector).submit(); |
|
324 } |
|
325 |
|
326 |
|
327 /** |
|
328 * Bind links that will open modals to the appropriate function. |
|
329 */ |
|
330 Drupal.behaviors.CToolsAJAX = function(context) { |
|
331 // Bind links |
|
332 $('a.ctools-use-ajax:not(.ctools-use-ajax-processed)', context) |
|
333 .addClass('ctools-use-ajax-processed') |
|
334 .click(Drupal.CTools.AJAX.clickAJAXLink); |
|
335 |
|
336 // Bind buttons |
|
337 $('input.ctools-use-ajax:not(.ctools-use-ajax-processed), button.ctools-use-ajax:not(.ctools-use-ajax-processed)', context) |
|
338 .addClass('ctools-use-ajax-processed') |
|
339 .click(Drupal.CTools.AJAX.clickAJAXButton); |
|
340 |
|
341 // Bind select |
|
342 $('select, input:text, input:radio, input:checkbox', context) |
|
343 .filter('.ctools-use-ajax-onchange:not(.ctools-use-ajax-processed)') |
|
344 .addClass('ctools-use-ajax-processed') |
|
345 .change(Drupal.CTools.AJAX.changeAJAX); |
|
346 }; |
|
347 })(jQuery); |
|