ajax_view.js 5.1 KB

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