ajax_view.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /**
  2. * @file
  3. * Handles AJAX fetching of views, including filter submission and response.
  4. */
  5. (function ($) {
  6. /**
  7. * Attaches the AJAX behavior to exposed filter forms and key views links.
  8. */
  9. Drupal.behaviors.ViewsAjaxView = {};
  10. Drupal.behaviors.ViewsAjaxView.attach = function() {
  11. if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) {
  12. $.each(Drupal.settings.views.ajaxViews, function(i, settings) {
  13. Drupal.views.instances[i] = new Drupal.views.ajaxView(settings);
  14. });
  15. }
  16. };
  17. Drupal.views = {};
  18. Drupal.views.instances = {};
  19. /**
  20. * JavaScript object for a certain view.
  21. */
  22. Drupal.views.ajaxView = function(settings) {
  23. var selector = '.view-dom-id-' + settings.view_dom_id;
  24. this.$view = $(selector);
  25. // Retrieve the path to use for views' ajax.
  26. var ajax_path = Drupal.settings.views.ajax_path;
  27. // If there are multiple views this might've ended up showing up multiple
  28. // times.
  29. if (ajax_path.constructor.toString().indexOf("Array") != -1) {
  30. ajax_path = ajax_path[0];
  31. }
  32. // Check if there are any GET parameters to send to views.
  33. var queryString = window.location.search || '';
  34. if (queryString !== '') {
  35. // Remove the question mark and Drupal path component if any.
  36. var queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, '');
  37. if (queryString !== '') {
  38. // If there is a '?' in ajax_path, clean url are on and & should be
  39. // used to add parameters.
  40. queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString;
  41. }
  42. }
  43. this.element_settings = {
  44. url: ajax_path + queryString,
  45. submit: settings,
  46. setClick: true,
  47. event: 'click',
  48. selector: selector,
  49. progress: {
  50. type: 'throbber'
  51. }
  52. };
  53. this.settings = settings;
  54. // Add the ajax to exposed forms.
  55. this.$exposed_form = $('#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-'));
  56. this.$exposed_form.once(jQuery.proxy(this.attachExposedFormAjax, this));
  57. // Store Drupal.ajax objects here for all pager links.
  58. this.links = [];
  59. // Add the ajax to pagers.
  60. this.$view
  61. .once(jQuery.proxy(this.attachPagerAjax, this));
  62. // Add a trigger to update this view specifically. In order to trigger a
  63. // refresh use the following code.
  64. //
  65. // @code
  66. // jQuery('.view-name').trigger('RefreshView');
  67. // @endcode
  68. // Add a trigger to update this view specifically.
  69. var self_settings = this.element_settings;
  70. self_settings.event = 'RefreshView';
  71. this.refreshViewAjax = new Drupal.ajax(this.selector, this.$view, self_settings);
  72. };
  73. Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() {
  74. var button = $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form);
  75. button = button[0];
  76. // Call the autocomplete submit before doing AJAX.
  77. $(button).click(function () {
  78. if (Drupal.autocompleteSubmit) {
  79. Drupal.autocompleteSubmit();
  80. }
  81. });
  82. this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings);
  83. };
  84. /**
  85. * Attach the ajax behavior to each link.
  86. */
  87. Drupal.views.ajaxView.prototype.attachPagerAjax = function() {
  88. this.$view.find('ul.pager > li > a, th.views-field a, .attachment .views-summary a')
  89. .each(jQuery.proxy(this.attachPagerLinkAjax, this));
  90. };
  91. /**
  92. * Attach the ajax behavior to a singe link.
  93. */
  94. Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function(id, link) {
  95. var $link = $(link);
  96. // Don't attach to pagers inside nested views.
  97. if ($link.closest('.view')[0] !== this.$view[0]) {
  98. return;
  99. }
  100. var viewData = {};
  101. var href = $link.attr('href');
  102. // Provide a default page if none has been set. This must be done
  103. // prior to merging with settings to avoid accidentally using the
  104. // page landed on instead of page 1.
  105. if (typeof(viewData.page) === 'undefined') {
  106. viewData.page = 0;
  107. }
  108. // Construct an object using the settings defaults and then overriding
  109. // with data specific to the link.
  110. $.extend(
  111. viewData,
  112. this.settings,
  113. Drupal.Views.parseQueryString(href),
  114. // Extract argument data from the URL.
  115. Drupal.Views.parseViewArgs(href, this.settings.view_base_path)
  116. );
  117. // For anchor tags, these will go to the target of the anchor rather
  118. // than the usual location.
  119. $.extend(viewData, Drupal.Views.parseViewArgs(href, this.settings.view_base_path));
  120. this.element_settings.submit = viewData;
  121. this.pagerAjax = new Drupal.ajax(false, $link, this.element_settings);
  122. this.links.push(this.pagerAjax);
  123. };
  124. Drupal.ajax.prototype.commands.viewsScrollTop = function (ajax, response, status) {
  125. // Scroll to the top of the view. This will allow users
  126. // to browse newly loaded content after e.g. clicking a pager
  127. // link.
  128. var offset = $(response.selector).offset();
  129. // We can't guarantee that the scrollable object should be
  130. // the body, as the view could be embedded in something
  131. // more complex such as a modal popup. Recurse up the DOM
  132. // and scroll the first element that has a non-zero top.
  133. var scrollTarget = response.selector;
  134. while ($(scrollTarget).scrollTop() == 0 && $(scrollTarget).parent()) {
  135. scrollTarget = $(scrollTarget).parent();
  136. }
  137. // Only scroll upward.
  138. if (offset.top - 10 < $(scrollTarget).scrollTop()) {
  139. $(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500);
  140. }
  141. };
  142. })(jQuery);