64557ccfc28cc0998d351fb945524d707c339742
[project/views.git] / js / ajax.js
1 // $Id$
2 /**
3  * @file ajax_admin.js
4  *
5  * Handles AJAX submission and response in Views UI.
6  */
7
8 Drupal.Views.Ajax = Drupal.Views.Ajax || {};
9
10 /**
11  * Handles the simple process of setting the ajax form area with new data.
12  */
13 Drupal.Views.Ajax.setForm = function(title, output) {
14   $(Drupal.settings.views.ajax.title).html(title);
15   $(Drupal.settings.views.ajax.id).html(output);
16 }
17
18 /**
19  * An ajax responder that accepts a packet of JSON data and acts appropriately.
20  *
21  * The following fields control behavior.
22  * - 'display': Display the associated data in the form area; bind the new
23  *   form to 'url' if appropriate. The 'title' field may also be used.
24  * - 'add': This is a keyed array of HTML output to add via append. The key is
25  *   the id to append via $(key).append(value)
26  * - 'replace': This is a keyed array of HTML output to add via replace. The key is
27  *   the id to append via $(key).html(value)
28  * 
29  */
30 Drupal.Views.Ajax.ajaxResponse = function(data) {
31   $('a.views-throbbing').removeClass('views-throbbing');
32   $('span.views-throbbing').remove();
33
34   if (data.debug) {
35     alert(data.debug);
36   }
37
38   // See if we have any settings to extend. Do this first so that behaviors
39   // can access the new settings easily.
40
41   if (Drupal.settings.viewsAjax) {
42     Drupal.settings.viewsAjax = {};
43   }
44   if (data.js) {
45     $.extend(Drupal.settings, data.js);
46   }
47
48   // Check the 'display' for data.
49   if (data.display) {
50     Drupal.Views.Ajax.setForm(data.title, data.display);
51
52     // if a URL was supplied, bind the form to it.
53     if (data.url) {
54       var ajax_area = Drupal.settings.views.ajax.id;
55       var ajax_title = Drupal.settings.views.ajax.title;
56     
57       // Bind a click to the button to set the value for the button.
58       $('input[type=submit]', ajax_area).unbind('click');
59       $('input[type=submit]', ajax_area).click(function() {
60         $('form', ajax_area).append('<input type="hidden" name="' 
61           + $(this).attr('name') + '" value="' + $(this).val() + '">');
62         $(this).after('<span class="views-throbbing">&nbsp</span>');
63       });
64
65       // Bind forms to ajax submit.
66       $('form', ajax_area).unbind('submit'); // be safe here.
67       $('form', ajax_area).submit(function(arg) {
68         $(this).ajaxSubmit({
69           url: data.url,
70           data: '',
71           type: 'POST',
72           success: Drupal.Views.Ajax.ajaxResponse,
73           error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': data.url})); },
74           dataType: 'json'
75         });
76         return false;
77       });
78     }
79
80     Drupal.attachBehaviors(ajax_area);
81   }
82   else {
83     // If no display, reset the form.
84     Drupal.Views.Ajax.setForm('', Drupal.settings.views.ajax.defaultForm);
85     //Enable the save button.
86     $('#edit-save').removeAttr('disabled');
87     // Trigger an update for the live preview when we reach this state:
88     $('#views-ui-preview-form').trigger('submit');
89   } 
90
91   // Go through the 'add' array and add any new content we're instructed to add.
92   if (data.add) {
93     for (id in data.add) {
94       var newContent = $(id).append(data.add[id]);
95       Drupal.attachBehaviors(newContent);
96     }
97   }
98
99   // Go through the 'replace' array and replace any content we're instructed to.
100   if (data.replace) {
101     for (id in data.replace) {
102       $(id).html(data.replace[id]);
103       Drupal.attachBehaviors(id);
104     }
105   }
106
107   // Go through and add any requested tabs
108   if (data.tab) {
109     for (id in data.tab) {
110       $('#views-tabset').addTab(id, data.tab[id]['title'], 0);
111       $(id).html(data.tab[id]['body']);
112       $(id).addClass('views-tab');
113       Drupal.attachBehaviors(id);
114
115       // This is kind of annoying, but we have to actually to find where the new
116       // tab is.
117       var instance = $.ui.tabs.instances[$('#views-tabset').get(0).UI_TABS_UUID];
118       $('#views-tabset').clickTab(instance.$tabs.length);
119     }
120   }
121   
122   if (data.hilite) {
123     $('.hilited').removeClass('hilited');
124     $(data.hilite).addClass('hilited');
125   }
126
127   if (data.changed) {
128     $('div.views-basic-info').addClass('changed');
129   }
130 }
131
132 /**
133  * An ajax responder that accepts a packet of JSON data and acts appropriately.
134  * This one specifically responds to the Views live preview area, so it's
135  * hardcoded and specialized.
136  */
137 Drupal.Views.Ajax.previewResponse = function(data) {
138   $('a.views-throbbing').removeClass('views-throbbing');
139   $('span.views-throbbing').remove();
140
141   if (data.debug) {
142     alert(data.debug);
143   }
144
145   // See if we have any settings to extend. Do this first so that behaviors
146   // can access the new settings easily.
147
148   // Clear any previous viewsAjax settings.
149   if (Drupal.settings.viewsAjax) {
150     Drupal.settings.viewsAjax = {};
151   }
152   if (data.js) {
153     $.extend(Drupal.settings, data.js);
154   }
155
156   // Check the 'display' for data.
157   if (data.display) {
158     var ajax_area = 'div#views-live-preview';
159     $(ajax_area).html(data.display);
160
161     var url = $(ajax_area, 'form').attr('action');
162
163     // if a URL was supplied, bind the form to it.
164     if (url) {   
165       // Bind a click to the button to set the value for the button.
166       $('input[type=submit]', ajax_area).unbind('click');
167       $('input[type=submit]', ajax_area).click(function() {
168         $('form', ajax_area).append('<input type="hidden" name="' 
169           + $(this).attr('name') + '" value="' + $(this).val() + '">');
170         $(this).after('<span class="views-throbbing">&nbsp</span>');
171       });
172
173       // Bind forms to ajax submit.
174       $('form', ajax_area).unbind('submit'); // be safe here.
175       $('form', ajax_area).submit(function() {
176         $(this).ajaxSubmit({
177           url: url,
178           data: '',
179           type: 'POST',
180           success: Drupal.Views.Ajax.previewResponse,
181           error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
182           dataType: 'json'
183         });
184         return false;
185       });
186     }
187
188     Drupal.attachBehaviors(ajax_area);
189   }
190 }
191
192 Drupal.Views.updatePreviewForm = function() {
193   var url = $(this).attr('action');
194   url = url.replace('nojs', 'ajax');
195
196   $('input[type=submit]', this).after('<span class="views-throbbing">&nbsp</span>');
197   $(this).ajaxSubmit({
198     url: url,
199     data: '',
200     type: 'POST',
201     success: Drupal.Views.Ajax.previewResponse,
202     error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
203     dataType: 'json'
204   });
205
206   return false;
207 }
208
209 Drupal.Views.updatePreviewFilterForm = function() {
210   var url = $(this).attr('action');
211   url = url.replace('nojs', 'ajax');
212
213   $('input[type=submit]', this).after('<span class="views-throbbing">&nbsp</span>');
214   $('input[name=q]', this).remove(); // remove 'q' for live preview.
215   $(this).ajaxSubmit({
216     url: url,
217     data: '',
218     type: 'GET',
219     success: Drupal.Views.Ajax.previewResponse,
220     error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
221     dataType: 'json'
222   });
223
224   return false;
225 }
226
227 Drupal.Views.updatePreviewLink = function() {
228   var url = $(this).attr('href');
229   url = url.replace('nojs', 'ajax');
230   if (url.substring(0, 18) != '/admin/build/views') {
231     return true;
232   }
233
234   $(this).addClass('views-throbbing');
235   $.ajax({
236     url: url,
237     data: '',
238     type: 'POST',
239     success: Drupal.Views.Ajax.previewResponse,
240     error: function() { $(this).removeClass('views-throbbing'); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
241     dataType: 'json'
242   });
243
244   return false;   
245 }
246
247 Drupal.behaviors.ViewsAjaxLinks = function() {
248   // Make specified links ajaxy.
249   $('a.views-ajax-link:not(.views-processed)').addClass('views-processed').click(function() {
250     // Translate the href on the link to the ajax href. That way this degrades
251     // into a nice, normal link.
252     var url = $(this).attr('href');
253     url = url.replace('nojs', 'ajax');
254
255     // Turn on the hilite to indicate this is in use.
256     $(this).addClass('hilite');
257
258     // Disable the save button.
259     $('#edit-save').attr('disabled', 'true');
260     
261     $(this).addClass('views-throbbing');
262     $.ajax({
263       type: "POST",
264       url: url,
265       data: '',
266       success: Drupal.Views.Ajax.ajaxResponse,
267       error: function() { $(this).removeClass('views-throbbing'); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
268       dataType: 'json'
269     });
270     
271     return false;
272   });  
273
274   $('form.views-ajax-form:not(.views-processed)').addClass('views-processed').submit(function(arg) {
275     // Translate the href on the link to the ajax href. That way this degrades
276     // into a nice, normal link.
277     var url = $(this).attr('action');
278     url = url.replace('nojs', 'ajax');
279
280 //    $('input[@type=submit]', this).after('<span class="views-throbbing">&nbsp</span>');
281     $(this).ajaxSubmit({
282       url: url,
283       data: '',
284       type: 'POST',
285       success: Drupal.Views.Ajax.ajaxResponse,
286       error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
287       dataType: 'json'
288     });
289
290     return false;   
291   });
292
293   // Bind the live preview to where it's supposed to go.
294
295   $('form#views-ui-preview-form:not(.views-processed)')
296     .addClass('views-processed')
297     .submit(Drupal.Views.updatePreviewForm);
298
299   $('div#views-live-preview form:not(.views-processed)')
300     .addClass('views-processed')
301     .submit(Drupal.Views.updatePreviewFilterForm);
302
303   $('div#views-live-preview a:not(.views-processed)')
304     .addClass('views-processed')
305     .click(Drupal.Views.updatePreviewLink);
306 }
307
308 /**
309  * Get rid of irritating tabledrag messages
310  */
311 Drupal.theme.tableDragChangedWarning = function () { 
312   return ' '; 
313 }