ajax_view.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. // Add the ajax to pagers.
  54. this.$view
  55. // Don't attach to nested views. Doing so would attach multiple behaviors
  56. // to a given element.
  57. .filter(jQuery.proxy(this.filterNestedViews, this))
  58. .once(jQuery.proxy(this.attachPagerAjax, this));
  59. // Add a trigger to update this view specifically. In order to trigger a
  60. // refresh use the following code.
  61. //
  62. // @code
  63. // jQuery('.view-name').trigger('RefreshView');
  64. // @endcode
  65. // Add a trigger to update this view specifically.
  66. var self_settings = this.element_settings;
  67. self_settings.event = 'RefreshView';
  68. this.refreshViewAjax = new Drupal.ajax(this.selector, this.$view, self_settings);
  69. };
  70. Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() {
  71. var button = $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form);
  72. button = button[0];
  73. this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings);
  74. };
  75. Drupal.views.ajaxView.prototype.filterNestedViews= function() {
  76. // If there is at least one parent with a view class, this view
  77. // is nested (e.g., an attachment). Bail.
  78. return !this.$view.parents('.view').size();
  79. };
  80. /**
  81. * Attach the ajax behavior to each link.
  82. */
  83. Drupal.views.ajaxView.prototype.attachPagerAjax = function() {
  84. this.$view.find('ul.pager > li > a, th.views-field a, .attachment .views-summary a')
  85. .each(jQuery.proxy(this.attachPagerLinkAjax, this));
  86. };
  87. /**
  88. * Attach the ajax behavior to a singe link.
  89. */
  90. Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function(id, link) {
  91. var $link = $(link);
  92. var viewData = {};
  93. var href = $link.attr('href');
  94. // Construct an object using the settings defaults and then overriding
  95. // with data specific to the link.
  96. $.extend(
  97. viewData,
  98. this.settings,
  99. Drupal.Views.parseQueryString(href),
  100. // Extract argument data from the URL.
  101. Drupal.Views.parseViewArgs(href, this.settings.view_base_path)
  102. );
  103. // For anchor tags, these will go to the target of the anchor rather
  104. // than the usual location.
  105. $.extend(viewData, Drupal.Views.parseViewArgs(href, this.settings.view_base_path));
  106. this.element_settings.submit = viewData;
  107. this.pagerAjax = new Drupal.ajax(false, $link, this.element_settings);
  108. };
  109. Drupal.ajax.prototype.commands.viewsScrollTop = function (ajax, response, status) {
  110. // Scroll to the top of the view. This will allow users
  111. // to browse newly loaded content after e.g. clicking a pager
  112. // link.
  113. var offset = $(response.selector).offset();
  114. // We can't guarantee that the scrollable object should be
  115. // the body, as the view could be embedded in something
  116. // more complex such as a modal popup. Recurse up the DOM
  117. // and scroll the first element that has a non-zero top.
  118. var scrollTarget = response.selector;
  119. while ($(scrollTarget).scrollTop() == 0 && $(scrollTarget).parent()) {
  120. scrollTarget = $(scrollTarget).parent();
  121. }
  122. // Only scroll upward
  123. if (offset.top - 10 < $(scrollTarget).scrollTop()) {
  124. $(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500);
  125. }
  126. };
  127. })(jQuery);