1/** 2 * Provides the ability to fix a html block to a position on the page when the 3 * browser is scroled. 4 * 5 * This code is based on tableheader.js 6 */ 7(function ($) { 8 9Drupal.blockFloatStack = function() { 10 if( typeof Drupal.blockFloatStack.blocks == 'undefined' ) { 11 Drupal.blockFloatStack.blocks = []; 12 } 13 return Drupal.blockFloatStack.blocks; 14} 15 16/** 17 * Attaches the floating_block behavior. 18 */ 19Drupal.behaviors.blockFloat = { 20 attach: function (context) { 21 22 var settings = Drupal.settings.floating_block.settings; 23 24 // This breaks in anything less than IE 7. Prevent it from running. 25 if (navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.match(/msie 6/i)) { 26 return; 27 } 28 29 // If this behaviour is being called as part of processing an ajax callback. 30 if (jQuery.isFunction(context.parent)) { 31 context = context.parent(); 32 } 33 34 // Cycle through all of the blocks we want to float. 35 $.each(settings, function (selector, setting) { 36 // The format of a select is [float]|[container] where: 37 // [float] is the jQuery selector of thing you want to stay on screen 38 // [container] is the jQuery selector of container that defines a boundary 39 // not to float outside of. 40 $(selector.toString() + ':not(.blockFloat-processed)', context).each(function (j, block) { 41 // Store information about the block to float. 42 var blockInfo = []; 43 blockInfo.original_css = []; 44 blockInfo.original_css.left = Drupal.blockFloatCleanCSSValue($(block).css('left')); 45 blockInfo.original_css.top = Drupal.blockFloatCleanCSSValue($(block).css('top')); 46 blockInfo.original_css.position = $(block).css("position"); 47 blockInfo.original_css.height = $(block).height(); 48 blockInfo.floating = false; 49 blockInfo.reset = true; 50 blockInfo.original_identifier = 'blockFloat-' + Drupal.blockFloatStack().length; 51 52 // Store the selector for the container if it exists. 53 if (setting.container && $(setting.container.toString()).length > 0) { 54 blockInfo.container = setting.container; 55 } 56 57 if (setting.padding_top) { 58 blockInfo.padding_top = setting.padding_top; 59 } 60 else { 61 blockInfo.padding_top = 0; 62 } 63 64 if (setting.padding_bottom) { 65 blockInfo.padding_bottom = setting.padding_bottom; 66 } 67 else { 68 blockInfo.padding_bottom = 0; 69 } 70 71 // Fix the width of the block as often a block will be 100% of it's 72 // container. This ensures that when it's floated it will keep it's 73 // original width. There is no point using .css('width') as this will 74 // return the computed value so we might as well just set it. 75 $(block).width($(block).width()); 76 77 // Add class to block to indicate that we're done and give 78 // Drupal.blockFloatTracker a certain way to identify the block. 79 $(block).addClass('blockFloat-processed ' + blockInfo.original_identifier); 80 81 // If the page loaded has already been scrolled calling 82 // Drupal.blockFloatTracker will float the block if necessary. 83 Drupal.blockFloatTracker(blockInfo); 84 85 // Store the block in the floating_blocks array. 86 Drupal.blockFloatStack().push(blockInfo); 87 }); 88 }); 89 } 90} 91 92/** 93 * Function that calculates whether or not the block should be floated. 94 */ 95Drupal.blockFloatTracker = function (blockInfo) { 96 // Check for min-width requirement. 97 var minWidth = Drupal.settings.floating_block.minWidth; 98 if (minWidth && window.matchMedia) { 99 if (!window.matchMedia('(min-width: ' + minWidth + ')').matches) { 100 return; 101 } 102 } 103 104 // If the browser height is less than the floating block height, don't 105 // float the block. 106 var windowHeight = $(window).height(); 107 var blockHeight = blockInfo.original_css.height; 108 if (blockHeight > windowHeight) { 109 if (blockInfo.floating == true) { 110 } else { 111 // The floating block is larger than the window. Reset and don't float. 112 Drupal.blockFloatResetPosition(block, blockInfo); 113 return; 114 } 115 } 116 // Save positioning data. 117 var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight; 118 var block = $('.' + blockInfo.original_identifier); 119 if (block.length == 0) { 120 // The floated block must have been removed from the page - do nothing. 121 return; 122 } 123 124 // (Re)calculate some values if necessary. 125 if (blockInfo.scrollHeight != scrollHeight || blockInfo.reset) { 126 if (blockInfo.reset) { 127 // Reset block so we can calculate new offset. 128 Drupal.blockFloatResetPosition(block, blockInfo); 129 blockInfo.original_offset = $(block).offset(); 130 131 // Reset completed - set value so we don't do unnecessary resets. 132 blockInfo.reset = false;
133 } 134 135 // Save the scrollHeight - if this changes we will need to recalculate. 136 blockInfo.scrollHeight = scrollHeight; 137 // The minimum offset is always defined by the blocks starting position. 138 blockInfo.minOffset = blockInfo.original_offset.top - blockInfo.padding_top; 139 140 // Calculate the maxOffset which depends on whether or not a container is 141 // defined. Otherwise use the scrollHeight. 142 if (blockInfo.container) { 143 blockInfo.maxOffset = $(blockInfo.container).height() + $(blockInfo.container).offset().top - blockInfo.padding_bottom; 144 } 145 else { 146 blockInfo.maxOffset = scrollHeight; 147 } 148 } 149 150 // Track positioning relative to the viewport and set position. 151 var vScroll = (document.documentElement.scrollTop || document.body.scrollTop); 152 if (vScroll > blockInfo.minOffset) { 153 var topPosition = blockInfo.padding_top; 154 // Block height can change if there a collapsible fields etc... inside the 155 // block so recalculate every time we are floating the block. 156 var blockHeight = block.height(); 157 // Don't let the bottom of the block go beneath maxOffset. 158 if ((vScroll + blockHeight) > blockInfo.maxOffset) { 159 // At this point topPosition will become a negative number to keep the 160 // block from going out of the defined container. 161 topPosition = blockInfo.maxOffset - vScroll - blockHeight; 162 } 163 164 block.css({ 165 left: blockInfo.original_offset.left + 'px', 166 position: 'fixed', 167 top: topPosition + 'px' 168 }).addClass('floating-block-active'); 169 170 blockInfo.floating = true; 171 } 172 else { 173 // Put the block back in it's original position. 174 Drupal.blockFloatResetPosition(block, blockInfo); 175 } 176} 177 178/** 179 * Resets the position of a floated block back to non floated position. 180 */ 181Drupal.blockFloatResetPosition = function (block, blockInfo) { 182 if (blockInfo.floating) { 183 block.css({ 184 left: blockInfo.original_css.left, 185 position: blockInfo.original_css.position, 186 top: blockInfo.original_css.top 187 }).removeClass('floating-block-active'); 188 blockInfo.floating = false; 189 } 190} 191 192/** 193 * If the css value is 0px for top and left then it is not actually set using 194 * CSS - this will be the computed value. Setting to a blank string will ensure 195 * that when Drupal.blockFloatResetPosition is called these css value will be 196 * unset. 197 */ 198Drupal.blockFloatCleanCSSValue = function (cssvalue) { 199 if (cssvalue == '0px') { 200 cssvalue = ''; 201 } 202 return cssvalue; 203} 204 205/** 206 * Callback to be added to the scroll event. Each time the user scrolls this 207 * function will be called. 208 */ 209Drupal.blockFloatOnScroll = function() { 210 $(Drupal.blockFloatStack()).each(function () { 211 Drupal.blockFloatTracker(this); 212 }); 213}; 214 215/** 216 * Callback to be added to the resize event. Each time the user resizes the 217 * this window this function will be called. A timeout is used to prevent 218 * this function from causing a slow down during resizing. 219 */ 220Drupal.blockFloatWindowResize = function() { 221 if( typeof Drupal.blockFloatWindowResize.timer == 'undefined' ) { 222 Drupal.blockFloatWindowResize.timer = false; 223 } 224 // Ensure minimum time between adjustments. 225 if (Drupal.blockFloatWindowResize.timer) { 226 return; 227 } 228 Drupal.blockFloatWindowResize.timer = setTimeout(function () { 229 $(Drupal.blockFloatStack()).each(function () { 230 this.reset = true; 231 Drupal.blockFloatTracker(this); 232 }); 233 // Reset timer 234 Drupal.blockFloatWindowResize.timer = false; 235 }, 250); 236}; 237 238/** 239 * Attach callbacks to resize and scroll events. Add a class to the body to 240 * prevent doing this multiple times. 241 */ 242if (!$('body').hasClass('blockFloat-processed')) { 243 $('body').addClass('blockFloat-processed'); 244 $(window).scroll(Drupal.blockFloatOnScroll); 245 $(document.documentElement).scroll(Drupal.blockFloatOnScroll); 246 $(window).resize(Drupal.blockFloatWindowResize); 247} 248 249})(jQuery); 250; 251/** 252 * @file views_load_more.js 253 * 254 * Handles the AJAX pager for the view_load_more plugin. 255 */ 256(function ($) { 257 258 /** 259 * Provide a series of commands that the server can request the client perform. 260 */ 261 Drupal.ajax.prototype.commands.viewsLoadMoreAppend = function (ajax, response, status) { 262 // Get information from the response. If it is not there, default to 263 // our presets. 264 var wrapper = response.selector ? $(response.selector) : $(ajax.wrapper); 265 var method = response.method || ajax.method; 266 var targetList = response.targetList || ''; 267 var effect = ajax.getEffect(response); 268 var pager_selector = response.options.pager_selector ? response.options.pager_selector : '.pager-load-more'; 269
270 // We don't know what response.data contains: it might be a string of text 271 // without HTML, so don't rely on jQuery correctly iterpreting 272 // $(response.data) as new HTML rather than a CSS selector. Also, if 273 // response.data contains top-level text nodes, they get lost with either 274 // $(response.data) or $('<div></div>').replaceWith(response.data). 275 var new_content_wrapped = $('<div></div>').html(response.data); 276 var new_content = new_content_wrapped.contents(); 277 278 // For legacy reasons, the effects processing code assumes that new_content 279 // consists of a single top-level element. Also, it has not been 280 // sufficiently tested whether attachBehaviors() can be successfully called 281 // with a context object that includes top-level text nodes. However, to 282 // give developers full control of the HTML appearing in the page, and to 283 // enable Ajax content to be inserted in places where DIV elements are not 284 // allowed (e.g., within TABLE, TR, and SPAN parents), we check if the new 285 // content satisfies the requirement of a single top-level element, and 286 // only use the container DIV created above when it doesn't. For more 287 // information, please see http://drupal.org/node/736066. 288 if (new_content.length != 1 || new_content.get(0).nodeType != 1) { 289 new_content = new_content_wrapped; 290 } 291 // If removing content from the wrapper, detach behaviors first. 292 var settings = response.settings || ajax.settings || Drupal.settings; 293 Drupal.detachBehaviors(wrapper, settings); 294 if ($.waypoints != undefined) { 295 $.waypoints('refresh'); 296 } 297 298 // Set up our default query options. This is for advance users that might 299 // change there views layout classes. This allows them to write there own 300 // jquery selector to replace the content with. 301 // Provide sensible defaults for unordered list, ordered list and table 302 // view styles. 303 var content_query = targetList && !response.options.content ? '> .view-content ' + targetList : response.options.content || '> .view-content'; 304 305 // If we're using any effects. Hide the new content before adding it to the DOM. 306 if (effect.showEffect != 'show') { 307 new_content.find(content_query).children().hide(); 308 } 309 310 // Update the pager 311 // Find both for the wrapper as the newly loaded content the direct child 312 // .item-list in case of nested pagers 313 wrapper.find(pager_selector).replaceWith(new_content.find(pager_selector)); 314 315 // Add the new content to the page. 316 wrapper.find(content_query)[method](new_content.find(content_query).children()); 317 318 // Re-class the loaded content. 319 // @todo this is faulty in many ways. first of which is that user may have configured view to not have these classes at all. 320 wrapper.find(content_query).children() 321 .removeClass('views-row-first views-row-last views-row-odd views-row-even') 322 .filter(':first') 323 .addClass('views-row-first') 324 .end() 325 .filter(':last') 326 .addClass('views-row-last') 327 .end() 328 .filter(':even') 329 .addClass('views-row-odd') 330 .end() 331 .filter(':odd') 332 .addClass('views-row-even') 333 .end(); 334 335 if (effect.showEffect != 'show') { 336 wrapper.find(content_query).children(':not(:visible)')[effect.showEffect](effect.showSpeed); 337 } 338 339 // Additional processing over new content 340 wrapper.trigger('views_load_more.new_content', new_content.clone()); 341 342 // Attach all JavaScript behaviors to the new content 343 // Remove the Jquery once Class, TODO: There needs to be a better 344 // way of doing this, look at .removeOnce() :-/ 345 var classes = wrapper.attr('class'); 346 var onceClass = classes.match(/jquery-once-[0-9]*-[a-z]*/); 347 wrapper.removeClass(onceClass[0]); 348 settings = response.settings || ajax.settings || Drupal.settings; 349 Drupal.attachBehaviors(wrapper, settings); 350 }; 351 352 /** 353 * Attaches the AJAX behavior to Views Load More waypoint support. 354 */ 355 Drupal.behaviors.ViewsLoadMore = { 356 attach: function (context, settings) { 357 var default_opts = { 358 offset: '100%' 359 }; 360 361 if (settings && settings.viewsLoadMore && settings.views && settings.views.ajaxViews) { 362 $.each(settings.viewsLoadMore, function(i, setting) { 363 var view = '.view-id-' + setting.view_name + '.view-display-id-' + setting.view_display_id + ' .pager-next a', 364 opts = {}; 365 366 $.extend(opts, default_opts, settings.viewsLoadMore[i].opts); 367 368 $(view).waypoint('destroy'); 369 $(view).waypoint(function(event, direction) { 370 $(view).click(); 371 }, opts); 372 }); 373 } 374 }, 375 detach: function (context, settings, trigger) { 376 if (settings && settings.viewsLoadMore && settings.views && settings.views.ajaxViews) { 377 $.each(settings.viewsLoadMore, function(i, setting) { 378 var view = '.view-id-' + setting.view_name + '.view-display-id-' + setting.view_display_id; 379 if ($(context).is(view)) { 380 $('.pager-next a', view).waypoint('destroy'); 381 } 382 else { 383 $(view, context).waypoint('destroy'); 384 } 385 }); 386 } 387 } 388 }; 389})(jQuery); 390; 391/** 392 * @file 393 * Some basic behaviors and utility functions for Views. 394 */ 395(function ($) { 396 397 Drupal.Views = {}; 398 399 /** 400 * JQuery UI tabs, Views integration component. 401 */ 402 Drupal.behaviors.viewsTabs = { 403 attach: function (context) { 404 if ($.viewsUi && $.viewsUi.tabs) { 405 $('#views-tabset').once('views-processed').viewsTabs({ 406 selectedClass: 'active' 407 }); 408 } 409 410 $('a.views-remove-link').once('views-processed').click(function(event) { 411 var id = $(this).attr('id').replace('views-remove-link-', ''); 412 $('#views-row-' + id).hide(); 413 $('#views-removed-' + id).get(0).checked = true; 414 event.preventDefault(); 415 }); 416 // Here is to handle display deletion 417 // (checking in the hidden checkbox and hiding out the row). 418 $('a.display-remove-link') 419 .addClass('display-processed') 420 .click(function() { 421 var id = $(this).attr('id').replace('display-remove-link-', ''); 422 $('#display-row-' + id).hide(); 423 $('#display-removed-' + id).get(0).checked = true; 424 return false;
425 }); 426 } 427 }; 428 429 /** 430 * Helper function to parse a querystring. 431 */ 432 Drupal.Views.parseQueryString = function (query) { 433 var args = {}; 434 var pos = query.indexOf('?'); 435 if (pos != -1) { 436 query = query.substring(pos + 1); 437 } 438 var pairs = query.split('&'); 439 for (var i in pairs) { 440 if (typeof(pairs[i]) == 'string') { 441 var pair = pairs[i].split('='); 442 // Ignore the 'q' path argument, if present. 443 if (pair[0] != 'q' && pair[1]) { 444 args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); 445 } 446 } 447 } 448 return args; 449 }; 450 451 /** 452 * Helper function to return a view's arguments based on a path. 453 */ 454 Drupal.Views.parseViewArgs = function (href, viewPath) { 455 // Provide language prefix. 456 if (Drupal.settings.pathPrefix) { 457 var viewPath = Drupal.settings.pathPrefix + viewPath; 458 } 459 var returnObj = {}; 460 var path = Drupal.Views.getPath(href); 461 // Ensure there is a correct path. 462 if (viewPath && path.substring(0, viewPath.length + 1) == viewPath + '/') { 463 var args = decodeURIComponent(path.substring(viewPath.length + 1, path.length)); 464 returnObj.view_args = args; 465 returnObj.view_path = path; 466 } 467 return returnObj; 468 }; 469 470 /** 471 * Strip off the protocol plus domain from an href. 472 */ 473 Drupal.Views.pathPortion = function (href) { 474 // Remove e.g. http://example.com if present. 475 var protocol = window.location.protocol; 476 if (href.substring(0, protocol.length) == protocol) { 477 // 2 is the length of the '//' that normally follows the protocol. 478 href = href.substring(href.indexOf('/', protocol.length + 2)); 479 } 480 return href; 481 }; 482 483 /** 484 * Return the Drupal path portion of an href. 485 */ 486 Drupal.Views.getPath = function (href) { 487 href = Drupal.Views.pathPortion(href); 488 href = href.substring(Drupal.settings.basePath.length, href.length); 489 // 3 is the length of the '?q=' added to the URL without clean URLs. 490 if (href.substring(0, 3) == '?q=') { 491 href = href.substring(3, href.length); 492 } 493 var chars = ['#', '?', '&']; 494 for (var i in chars) { 495 if (href.indexOf(chars[i]) > -1) { 496 href = href.substr(0, href.indexOf(chars[i])); 497 } 498 } 499 return href; 500 }; 501 502})(jQuery); 503; 504(function ($) { 505 506/** 507 * A progressbar object. Initialized with the given id. Must be inserted into 508 * the DOM afterwards through progressBar.element. 509 * 510 * method is the function which will perform the HTTP request to get the 511 * progress bar state. Either "GET" or "POST". 512 * 513 * e.g. pb = new progressBar('myProgressBar'); 514 * some_element.appendChild(pb.element); 515 */ 516Drupal.progressBar = function (id, updateCallback, method, errorCallback) { 517 var pb = this; 518 this.id = id; 519 this.method = method || 'GET'; 520 this.updateCallback = updateCallback; 521 this.errorCallback = errorCallback; 522 523 // The WAI-ARIA setting aria-live="polite" will announce changes after users 524 // have completed their current activity and not interrupt the screen reader. 525 this.element = $('<div class="progress-wrapper" aria-live="polite"></div>'); 526 this.element.html('<div id ="' + id + '" class="progress progress-striped active">' + 527 '<div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">' + 528 '<div class="percentage sr-only"></div>' + 529 '</div></div>' + 530 '</div><div class="percentage pull-right"></div>' + 531 '<div class="message"> </div>'); 532}; 533 534/** 535 * Set the percentage and status message for the progressbar. 536 */ 537Drupal.progressBar.prototype.setProgress = function (percentage, message) { 538 if (percentage >= 0 && percentage <= 100) { 539 $('div.progress-bar', this.element).css('width', percentage + '%'); 540 $('div.progress-bar', this.element).attr('aria-valuenow', percentage); 541 $('div.percentage', this.element).html(percentage + '%'); 542 } 543 $('div.message', this.element).html(message); 544 if (this.updateCallback) { 545 this.updateCallback(percentage, message, this); 546 } 547}; 548 549/** 550 * Start monitoring progress via Ajax. 551 */ 552Drupal.progressBar.prototype.startMonitoring = function (uri, delay) { 553 this.delay = delay; 554 this.uri = uri; 555 this.sendPing(); 556}; 557 558/** 559 * Stop monitoring progress via Ajax. 560 */ 561Drupal.progressBar.prototype.stopMonitoring = function () { 562 clearTimeout(this.timer); 563 // This allows monitoring to be stopped from within the callback. 564 this.uri = null; 565}; 566 567/** 568 * Request progress data from server. 569 */ 570Drupal.progressBar.prototype.sendPing = function () { 571 if (this.timer) { 572 clearTimeout(this.timer); 573 } 574 if (this.uri) { 575 var pb = this; 576 // When doing a post request, you need non-null data. Otherwise a 577 // HTTP 411 or HTTP 406 (with Apache mod_security) error may result. 578 $.ajax({ 579 type: this.method, 580 url: this.uri, 581 data: '', 582 dataType: 'json', 583 success: function (progress) { 584 // Display errors. 585 if (progress.status == 0) { 586 pb.displayError(progress.data); 587 return; 588 } 589 // Update display. 590 pb.setProgress(progress.percentage, progress.message); 591 // Schedule next timer.
592 pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay); 593 }, 594 error: function (xmlhttp) { 595 pb.displayError(Drupal.ajaxError(xmlhttp, pb.uri)); 596 } 597 }); 598 } 599}; 600 601/** 602 * Display errors on the page. 603 */ 604Drupal.progressBar.prototype.displayError = function (string) { 605 var error = $('<div class="alert alert-block alert-error"><a class="close" data-dismiss="alert" href="#">×</a><h4>Error message</h4></div>').append(string); 606 $(this.element).before(error).hide(); 607 608 if (this.errorCallback) { 609 this.errorCallback(this); 610 } 611}; 612 613})(jQuery); 614; 615/** 616 * @file 617 * Handles AJAX fetching of views, including filter submission and response. 618 */ 619(function ($) { 620 621 /** 622 * Attaches the AJAX behavior to exposed filter forms and key views links. 623 */ 624 Drupal.behaviors.ViewsAjaxView = {}; 625 Drupal.behaviors.ViewsAjaxView.attach = function() { 626 if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) { 627 $.each(Drupal.settings.views.ajaxViews, function(i, settings) { 628 Drupal.views.instances[i] = new Drupal.views.ajaxView(settings); 629 }); 630 } 631 }; 632 633 Drupal.views = {}; 634 Drupal.views.instances = {}; 635 636 /** 637 * JavaScript object for a certain view. 638 */ 639 Drupal.views.ajaxView = function(settings) { 640 var selector = '.view-dom-id-' + settings.view_dom_id; 641 this.$view = $(selector); 642 643 // If view is not present return to prevent errors. 644 if (!this.$view.length) { 645 return; 646 } 647 648 // Retrieve the path to use for views' ajax. 649 var ajax_path = Drupal.settings.views.ajax_path; 650 651 // If there are multiple views this might've ended up showing up multiple 652 // times. 653 if (ajax_path.constructor.toString().indexOf("Array") != -1) { 654 ajax_path = ajax_path[0]; 655 } 656 657 // Check if there are any GET parameters to send to views. 658 var queryString = window.location.search || ''; 659 if (queryString !== '') { 660 // Remove the question mark and Drupal path component if any. 661 var queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, ''); 662 if (queryString !== '') { 663 // If there is a '?' in ajax_path, clean url are on and & should be 664 // used to add parameters. 665 queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString; 666 } 667 } 668 669 this.element_settings = { 670 url: ajax_path + queryString, 671 submit: settings, 672 setClick: true, 673 event: 'click', 674 selector: selector, 675 progress: { 676 type: 'throbber' 677 } 678 }; 679 680 this.settings = settings; 681 682 // Add the ajax to exposed forms. 683 this.$exposed_form = $('#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-')); 684 this.$exposed_form.once(jQuery.proxy(this.attachExposedFormAjax, this)); 685 686 // Store Drupal.ajax objects here for all pager links. 687 this.links = []; 688 689 // Add the ajax to pagers. 690 this.$view 691 .once(jQuery.proxy(this.attachPagerAjax, this)); 692 693 // Add a trigger to update this view specifically. In order to trigger a 694 // refresh use the following code. 695 // 696 // @code 697 // jQuery('.view-name').trigger('RefreshView'); 698 // @endcode 699 // Add a trigger to update this view specifically. 700 var self_settings = this.element_settings; 701 self_settings.event = 'RefreshView'; 702 var self = this; 703 this.$view.once('refresh', function () { 704 self.refreshViewAjax = new Drupal.ajax(self.selector, self.$view, self_settings); 705 }); 706 }; 707 708 Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() { 709 var button = $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form); 710 button = button[0]; 711 712 // Call the autocomplete submit before doing AJAX. 713 $(button).click(function () { 714 if (Drupal.autocompleteSubmit) { 715 Drupal.autocompleteSubmit(); 716 } 717 }); 718 719 this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings); 720 }; 721 722 /** 723 * Attach the ajax behavior to each link. 724 */ 725 Drupal.views.ajaxView.prototype.attachPagerAjax = function() { 726 this.$view.find('ul.pager > li > a, ol.pager > li > a, th.views-field a, .attachment .views-summary a') 727 .each(jQuery.proxy(this.attachPagerLinkAjax, this)); 728 }; 729 730 /**
731 * Attach the ajax behavior to a single link. 732 */ 733 Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function(id, link) { 734 var $link = $(link); 735 var viewData = {}; 736 var href = $link.attr('href'); 737 // Don't attach to pagers inside nested views. 738 if ($link.closest('.view')[0] !== this.$view[0] && 739 $link.closest('.view').parent().hasClass('attachment') === false) { 740 return; 741 } 742 743 // Provide a default page if none has been set. This must be done 744 // prior to merging with settings to avoid accidentally using the 745 // page landed on instead of page 1. 746 if (typeof(viewData.page) === 'undefined') { 747 viewData.page = 0; 748 } 749 750 // Construct an object using the settings defaults and then overriding 751 // with data specific to the link. 752 $.extend( 753 viewData, 754 this.settings, 755 Drupal.Views.parseQueryString(href), 756 // Extract argument data from the URL. 757 Drupal.Views.parseViewArgs(href, this.settings.view_base_path) 758 ); 759 760 // For anchor tags, these will go to the target of the anchor rather 761 // than the usual location. 762 $.extend(viewData, Drupal.Views.parseViewArgs(href, this.settings.view_base_path)); 763 764 // Construct an object using the element settings defaults, 765 // then overriding submit with viewData. 766 var pager_settings = $.extend({}, this.element_settings); 767 pager_settings.submit = viewData; 768 this.pagerAjax = new Drupal.ajax(false, $link, pager_settings); 769 this.links.push(this.pagerAjax); 770 }; 771 772 Drupal.ajax.prototype.commands.viewsScrollTop = function (ajax, response, status) { 773 // Scroll to the top of the view. This will allow users 774 // to browse newly loaded content after e.g. clicking a pager 775 // link. 776 var offset = $(response.selector).offset(); 777 // We can't guarantee that the scrollable object should be 778 // the body, as the view could be embedded in something 779 // more complex such as a modal popup. Recurse up the DOM 780 // and scroll the first element that has a non-zero top. 781 var scrollTarget = response.selector; 782 while ($(scrollTarget).scrollTop() == 0 && $(scrollTarget).parent()) { 783 scrollTarget = $(scrollTarget).parent(); 784 } 785 // Only scroll upward. 786 if (offset.top - 10 < $(scrollTarget).scrollTop()) { 787 $(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500); 788 } 789 }; 790 791})(jQuery); 792;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.