| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 // $Id: ajax-responder.js,v 1.18.2.24 2010/08/27 22:09:48 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 Drupal.CTools.AJAX.commandCache = Drupal.CTools.AJAX.comandCache || {} ; 13 Drupal.CTools.AJAX.scripts = {}; 14 Drupal.CTools.AJAX.css = {}; 15 16 /** 17 * Success callback for an ajax request. 18 * 19 * This function expects to receive a packet of data from a JSON object 20 * which is essentially a list of commands. Each commands must have a 21 * 'command' setting and this setting must resolve to a function in the 22 * Drupal.CTools.AJAX.commands space. 23 */ 24 Drupal.CTools.AJAX.respond = function(data) { 25 for (i in data) { 26 if (data[i]['command'] && Drupal.CTools.AJAX.commands[data[i]['command']]) { 27 Drupal.CTools.AJAX.commands[data[i]['command']](data[i]); 28 } 29 } 30 }; 31 32 /** 33 * Grab the response from the server and store it. 34 */ 35 Drupal.CTools.AJAX.warmCache = function () { 36 // Store this expression for a minor speed improvement. 37 $this = $(this); 38 var old_url = $this.attr('href'); 39 // If we are currently fetching, or if we have fetched this already which is 40 // ideal for things like pagers, where the previous page might already have 41 // been seen in the cache. 42 if ($this.hasClass('ctools-fetching') || Drupal.CTools.AJAX.commandCache[old_url]) { 43 return false; 44 } 45 46 // Grab all the links that match this url and add the fetching class. 47 // This allows the caching system to grab each url once and only once 48 // instead of grabbing the url once per <a>. 49 var $objects = $('a[href=' + old_url + ']') 50 $objects.addClass('ctools-fetching'); 51 try { 52 url = old_url.replace(/\/nojs(\/|$)/g, '/ajax$1'); 53 $.ajax({ 54 type: "POST", 55 url: url, 56 data: { 'js': 1, 'ctools_ajax': 1}, 57 global: true, 58 success: function (data) { 59 Drupal.CTools.AJAX.commandCache[old_url] = data; 60 $objects.addClass('ctools-cache-warmed').trigger('ctools-cache-warm', [data]); 61 }, 62 complete: function() { 63 $objects.removeClass('ctools-fetching'); 64 }, 65 dataType: 'json' 66 }); 67 } 68 catch (err) { 69 $objects.removeClass('ctools-fetching'); 70 return false; 71 } 72 73 return false; 74 }; 75 76 /** 77 * Cachable click handler to fetch the commands out of the cache or from url. 78 */ 79 Drupal.CTools.AJAX.clickAJAXCacheLink = function () { 80 $this = $(this); 81 if ($this.hasClass('ctools-fetching')) { 82 $this.bind('ctools-cache-warm', function (event, data) { 83 Drupal.CTools.AJAX.respond(data); 84 }); 85 return false; 86 } 87 else { 88 if ($this.hasClass('ctools-cache-warmed') && Drupal.CTools.AJAX.commandCache[$this.attr('href')]) { 89 Drupal.CTools.AJAX.respond(Drupal.CTools.AJAX.commandCache[$this.attr('href')]); 90 return false; 91 } 92 else { 93 return Drupal.CTools.AJAX.clickAJAXLink.apply(this); 94 } 95 } 96 }; 97 98 /** 99 * Generic replacement click handler to open the modal with the destination 100 * specified by the href of the link. 101 */ 102 Drupal.CTools.AJAX.clickAJAXLink = function() { 103 if ($(this).hasClass('ctools-ajaxing')) { 104 return false; 105 } 106 107 var url = $(this).attr('href'); 108 var object = $(this); 109 $(this).addClass('ctools-ajaxing'); 110 try { 111 url = url.replace(/\/nojs(\/|$)/g, '/ajax$1'); 112 $.ajax({ 113 type: "POST", 114 url: url, 115 data: { 'js': 1, 'ctools_ajax': 1}, 116 global: true, 117 success: Drupal.CTools.AJAX.respond, 118 error: function(xhr) { 119 Drupal.CTools.AJAX.handleErrors(xhr, url); 120 }, 121 complete: function() { 122 $('.ctools-ajaxing').removeClass('ctools-ajaxing'); 123 }, 124 dataType: 'json' 125 }); 126 } 127 catch (err) { 128 alert("An error occurred while attempting to process " + url); 129 $('.ctools-ajaxing').removeClass('ctools-ajaxing'); 130 return false; 131 } 132 133 return false; 134 }; 135 136 /** 137 * Generic replacement click handler to open the modal with the destination 138 * specified by the href of the link. 139 */ 140 Drupal.CTools.AJAX.clickAJAXButton = function() { 141 if ($(this).hasClass('ctools-ajaxing')) { 142 return false; 143 } 144 145 // Put our button in. 146 this.form.clk = this; 147 148 var url = Drupal.CTools.AJAX.findURL(this); 149 $(this).addClass('ctools-ajaxing'); 150 var object = $(this); 151 try { 152 if (url) { 153 url = url.replace(/\/nojs(\/|$)/g, '/ajax$1'); 154 $.ajax({ 155 type: "POST", 156 url: url, 157 data: { 'js': 1, 'ctools_ajax': 1}, 158 global: true, 159 success: Drupal.CTools.AJAX.respond, 160 error: function(xhr) { 161 Drupal.CTools.AJAX.handleErrors(xhr, url); 162 }, 163 complete: function() { 164 $('.ctools-ajaxing').removeClass('ctools-ajaxing'); 165 }, 166 dataType: 'json' 167 }); 168 } 169 else { 170 var form = this.form; 171 url = $(form).attr('action'); 172 setTimeout(function() { Drupal.CTools.AJAX.ajaxSubmit(form, url); }, 1); 173 } 174 } 175 catch (err) { 176 alert("An error occurred while attempting to process " + url); 177 $(this).removeClass('ctools-ajaxing'); 178 return false; 179 } 180 return false; 181 }; 182 183 /** 184 * Event handler to submit an AJAX form. 185 * 186 * Using a secondary event ensures that our form submission is last, which 187 * is needed when submitting wysiwyg controlled forms, for example. 188 */ 189 Drupal.CTools.AJAX.ajaxSubmit = function (form, url) { 190 $form = $(form); 191 192 if ($form.hasClass('ctools-ajaxing')) { 193 return false; 194 } 195 196 $form.addClass('ctools-ajaxing'); 197 198 try { 199 url = url.replace(/\/nojs(\/|$)/g, '/ajax$1'); 200 201 var ajaxOptions = { 202 type: 'POST', 203 url: url, 204 data: { 'js': 1, 'ctools_ajax': 1}, 205 global: true, 206 success: Drupal.CTools.AJAX.respond, 207 error: function(xhr) { 208 Drupal.CTools.AJAX.handleErrors(xhr, url); 209 }, 210 complete: function() { 211 $('.ctools-ajaxing').removeClass('ctools-ajaxing'); 212 $('div.ctools-ajaxing-temporary').remove(); 213 }, 214 dataType: 'json' 215 }; 216 217 // If the form requires uploads, use an iframe instead and add data to 218 // the submit to support this and use the proper response. 219 if ($form.attr('enctype') == 'multipart/form-data') { 220 $form.append('<input type="hidden" name="ctools_multipart" value="1">'); 221 ajaxIframeOptions = { 222 success: Drupal.CTools.AJAX.iFrameJsonRespond, 223 iframe: true 224 }; 225 ajaxOptions = $.extend(ajaxOptions, ajaxIframeOptions); 226 } 227 228 $form.ajaxSubmit(ajaxOptions); 229 } 230 catch (err) { 231 alert("An error occurred while attempting to process " + url); 232 $('.ctools-ajaxing').removeClass('ctools-ajaxing'); 233 $('div.ctools-ajaxing-temporary').remove(); 234 return false; 235 } 236 }; 237 238 /** 239 * Wrapper for handling JSON responses from an iframe submission 240 */ 241 Drupal.CTools.AJAX.iFrameJsonRespond = function(data) { 242 var myJson = eval(data); 243 Drupal.CTools.AJAX.respond(myJson); 244 } 245 246 /** 247 * Display error in a more fashion way 248 */ 249 Drupal.CTools.AJAX.handleErrors = function(xhr, path) { 250 var error_text = ''; 251 252 if ((xhr.status == 500 && xhr.responseText) || xhr.status == 200) { 253 error_text = xhr.responseText; 254 255 // Replace all < and > by < and > 256 error_text = error_text.replace("/&(lt|gt);/g", function (m, p) { 257 return (p == "lt")? "<" : ">"; 258 }); 259 260 // Now, replace all html tags by empty spaces 261 error_text = error_text.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi,""); 262 263 // Fix end lines 264 error_text = error_text.replace(/[\n]+\s+/g,"\n"); 265 } 266 else if (xhr.status == 500) { 267 error_text = xhr.status + ': ' + Drupal.t("Internal server error. Please see server or PHP logs for error information."); 268 } 269 else { 270 error_text = xhr.status + ': ' + xhr.statusText; 271 } 272 273 alert(Drupal.t("An error occurred at @path.\n\nError Description: @error", {'@path': path, '@error': error_text})); 274 } 275 276 /** 277 * Generic replacement for change handler to execute ajax method. 278 */ 279 Drupal.CTools.AJAX.changeAJAX = function () { 280 if ($(this).hasClass('ctools-ajaxing')) { 281 return false; 282 } 283 284 var url = Drupal.CTools.AJAX.findURL(this); 285 $(this).addClass('ctools-ajaxing'); 286 var object = $(this); 287 var form_id = $(object).parents('form').get(0).id; 288 try { 289 if (url) { 290 url = url.replace(/\/nojs(\/|$)/g, '/ajax$1'); 291 $.ajax({ 292 type: "POST", 293 url: url, 294 data: {'ctools_changed': $(this).val(), 'js': 1, 'ctools_ajax': 1 }, 295 global: true, 296 success: Drupal.CTools.AJAX.respond, 297 error: function(xhr) { 298 Drupal.CTools.AJAX.handleErrors(xhr, url); 299 }, 300 complete: function() { 301 $('.ctools-ajaxing').removeClass('ctools-ajaxing'); 302 if ($(object).hasClass('ctools-ajax-submit-onchange')) { 303 $('form#' + form_id).submit(); 304 } 305 }, 306 dataType: 'json' 307 }); 308 } 309 else { 310 if ($(object).hasClass('ctools-ajax-submit-onchange')) { 311 $('form#' + form_id).submit(); 312 } 313 return false; 314 } 315 } 316 catch (err) { 317 alert("An error occurred while attempting to process " + url); 318 $('.ctools-ajaxing').removeClass('ctools-ajaxing'); 319 return false; 320 } 321 return false; 322 }; 323 324 /** 325 * Find a URL for an AJAX button. 326 * 327 * The URL for this gadget will be composed of the values of items by 328 * taking the ID of this item and adding -url and looking for that 329 * class. They need to be in the form in order since we will 330 * concat them all together using '/'. 331 */ 332 Drupal.CTools.AJAX.findURL = function(item) { 333 var url = ''; 334 var url_class = '.' + $(item).attr('id') + '-url'; 335 $(url_class).each( 336 function() { 337 if (url && $(this).val()) { 338 url += '/'; 339 } 340 url += $(this).val(); 341 }); 342 return url; 343 }; 344 345 Drupal.CTools.AJAX.getPath = function (link) { 346 if (!link) { 347 return; 348 } 349 350 var index = link.indexOf('?'); 351 if (index != -1) { 352 link = link.substr(0, index); 353 } 354 355 return link; 356 } 357 358 Drupal.CTools.AJAX.commands.prepend = function(data) { 359 $(data.selector).prepend(data.data); 360 Drupal.attachBehaviors($(data.selector)); 361 }; 362 363 Drupal.CTools.AJAX.commands.append = function(data) { 364 $(data.selector).append(data.data); 365 Drupal.attachBehaviors($(data.selector)); 366 }; 367 368 Drupal.CTools.AJAX.commands.replace = function(data) { 369 $(data.selector).replaceWith(data.data); 370 Drupal.attachBehaviors($(data.selector)); 371 }; 372 373 Drupal.CTools.AJAX.commands.after = function(data) { 374 var object = $(data.data); 375 $(data.selector).after(object); 376 Drupal.attachBehaviors(object); 377 }; 378 379 Drupal.CTools.AJAX.commands.before = function(data) { 380 var object = $(data.data); 381 $(data.selector).before(object); 382 Drupal.attachBehaviors(object); 383 }; 384 385 Drupal.CTools.AJAX.commands.html = function(data) { 386 $(data.selector).html(data.data); 387 Drupal.attachBehaviors($(data.selector)); 388 }; 389 390 Drupal.CTools.AJAX.commands.remove = function(data) { 391 $(data.selector).remove(); 392 }; 393 394 Drupal.CTools.AJAX.commands.changed = function(data) { 395 if (!$(data.selector).hasClass('changed')) { 396 $(data.selector).addClass('changed'); 397 if (data.star) { 398 $(data.selector).find(data.star).append(' <span class="star">*</span> '); 399 } 400 } 401 }; 402 403 Drupal.CTools.AJAX.commands.alert = function(data) { 404 alert(data.text, data.title); 405 }; 406 407 Drupal.CTools.AJAX.commands.css = function(data) { 408 /* 409 if (data.selector && data.selector.contains('* html ')) { 410 // This indicates an IE hack and we should only do it if we are IE. 411 if (!jQuery.browser.msie) { 412 return; 413 } 414 data.selector = data.selector.replace('* html ', ''); 415 } 416 */ 417 $(data.selector).css(data.argument); 418 }; 419 420 Drupal.CTools.AJAX.commands.css_files = function(data) { 421 // Build a list of css files already loaded: 422 $('link:not(.ctools-temporary-css)').each(function () { 423 if ($(this).attr('type') == 'text/css') { 424 var link = Drupal.CTools.AJAX.getPath($(this).attr('href')); 425 if (link) { 426 Drupal.CTools.AJAX.css[link] = $(this).attr('href'); 427 } 428 } 429 }); 430 431 var html = ''; 432 for (i in data.argument) { 433 var link = Drupal.CTools.AJAX.getPath(data.argument[i].file); 434 if (!Drupal.CTools.AJAX.css[link]) { 435 html += '<link class="ctools-temporary-css" type="text/css" rel="stylesheet" media="' + data.argument[i].media + 436 '" href="' + data.argument[i].file + '" />'; 437 } 438 } 439 440 if (html) { 441 $('link.ctools-temporary-css').remove(); 442 $('body').append($(html)); 443 } 444 }; 445 446 Drupal.CTools.AJAX.commands.settings = function(data) { 447 $.extend(Drupal.settings, data.argument); 448 }; 449 450 Drupal.CTools.AJAX.commands.scripts = function(data) { 451 // Build a list of scripts already loaded: 452 var scripts = {}; 453 $('script').each(function () { 454 var link = Drupal.CTools.AJAX.getPath($(this).attr('src')); 455 if (link) { 456 Drupal.CTools.AJAX.scripts[link] = $(this).attr('src'); 457 } 458 }); 459 460 var html = ''; 461 var head = document.getElementsByTagName('head')[0]; 462 for (i in data.argument) { 463 var link = Drupal.CTools.AJAX.getPath(data.argument[i]); 464 if (!Drupal.CTools.AJAX.scripts[link]) { 465 Drupal.CTools.AJAX.scripts[link] = link; 466 // Use this to actually get the script tag into the dom, which is 467 // needed for scripts that self-reference to determine paths. 468 var script = document.createElement('script'); 469 script.type = 'text/javascript'; 470 script.src = data.argument[i]; 471 head.appendChild(script); 472 html += '<script type="text/javascript" src="' + data.argument[i] + '"></script>'; 473 } 474 } 475 476 if (html) { 477 $('body').append($(html)); 478 } 479 }; 480 481 Drupal.CTools.AJAX.commands.data = function(data) { 482 $(data.selector).data(data.name, data.value); 483 }; 484 485 Drupal.CTools.AJAX.commands.attr = function(data) { 486 $(data.selector).attr(data.name, data.value); 487 }; 488 489 Drupal.CTools.AJAX.commands.restripe = function(data) { 490 // :even and :odd are reversed because jquery counts from 0 and 491 // we count from 1, so we're out of sync. 492 $('tbody tr:not(:hidden)', $(data.selector)) 493 .removeClass('even') 494 .removeClass('odd') 495 .filter(':even') 496 .addClass('odd') 497 .end() 498 .filter(':odd') 499 .addClass('even'); 500 }; 501 502 Drupal.CTools.AJAX.commands.redirect = function(data) { 503 if (data.delay > 0) { 504 setTimeout(function () { 505 location.href = data.url; 506 }, data.delay); 507 } 508 else { 509 location.href = data.url; 510 } 511 }; 512 513 Drupal.CTools.AJAX.commands.reload = function(data) { 514 location.reload(); 515 }; 516 517 Drupal.CTools.AJAX.commands.submit = function(data) { 518 $(data.selector).submit(); 519 } 520 521 522 /** 523 * Bind links that will open modals to the appropriate function. 524 */ 525 Drupal.behaviors.CToolsAJAX = function(context) { 526 // Bind links 527 528 // Note that doing so in this order means that the two classes can be 529 // used together safely. 530 $('a.ctools-use-ajax-cache:not(.ctools-use-ajax-processed)', context) 531 .addClass('ctools-use-ajax-processed') 532 .click(Drupal.CTools.AJAX.clickAJAXCacheLink) 533 .each(function () { 534 Drupal.CTools.AJAX.warmCache.apply(this); 535 }); 536 537 $('a.ctools-use-ajax:not(.ctools-use-ajax-processed)', context) 538 .addClass('ctools-use-ajax-processed') 539 .click(Drupal.CTools.AJAX.clickAJAXLink); 540 541 542 // Bind buttons 543 $('input.ctools-use-ajax:not(.ctools-use-ajax-processed), button.ctools-use-ajax:not(.ctools-use-ajax-processed)', context) 544 .addClass('ctools-use-ajax-processed') 545 .click(Drupal.CTools.AJAX.clickAJAXButton); 546 547 // Bind select 548 $('select, input:text, input:radio, input:checkbox', context) 549 .filter('.ctools-use-ajax-onchange:not(.ctools-use-ajax-processed)') 550 .addClass('ctools-use-ajax-processed') 551 .change(Drupal.CTools.AJAX.changeAJAX); 552 553 // Add information about loaded CSS and JS files. 554 if (Drupal.settings.CToolsAJAX && Drupal.settings.CToolsAJAX.css) { 555 $.extend(Drupal.CTools.AJAX.css, Drupal.settings.CToolsAJAX.css); 556 } 557 if (Drupal.settings.CToolsAJAX && Drupal.settings.CToolsAJAX.scripts) { 558 $.extend(Drupal.CTools.AJAX.scripts, Drupal.settings.CToolsAJAX.scripts); 559 } 560 }; 561 })(jQuery);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |