Problem/Motivation

While working on this issue #2035643: Views ajax support for the views content display I had some minor issue with the current ajax handling.
The handling fails if there are multiple elements that match the views css selector.
This isn't really a problem with the default views handling but with the Views Content module provided by ctools it's possible to split a view into pieces.
Thus I've made some small changes to ensure the ajax handling doesn't fail in such a case.

Proposed resolution

To avoid that the pager links trigger the loading multiple times on a single click use once() instead each() when registering the event handler.
To avoid that the viewsScrollTop throws an JS error and breaks the whole ajax handling add a check if offset is really usable.

Remaining tasks

reviews needed

User interface changes

None

API changes

None

#2035643: Views ajax support for the views content display

Files: 
CommentFileSizeAuthor
#3 views-defensive-flexible-ajax-2035657-3.patch3.32 KBdas-peter
PASSED: [[SimpleTest]]: [MySQL] 1,652 pass(es).
[ View ]
#3 interdiff-2035657-1-3-do-not-test.diff1.81 KBdas-peter
#1 views-more-devensive-and-flexible-ajax-2035657-1.patch3.14 KBdas-peter
PASSED: [[SimpleTest]]: [MySQL] 1,652 pass(es).
[ View ]
views-more-devensive-and-flexible-ajax.patch858 bytesdas-peter
PASSED: [[SimpleTest]]: [MySQL] 1,636 pass(es).
[ View ]

Comments

StatusFileSize
new3.14 KB
PASSED: [[SimpleTest]]: [MySQL] 1,652 pass(es).
[ View ]

Updated patch.
The current ajax handling has some drawbacks:

  • The instance object variables exposedFormAjax, pagerAjax, refreshViewAjax are lost after an ajax request is handled.
    Thus the ajax configuration isn't accessible anymore for other scripts.
    I've added code to store the value of those variables in the jQuery data handling now. That keeps it accessible.
    The variables are still in place, but I wouldn't reccommend to rely on those.
  • If there are multiple views components split up, as done by ctools views content, the ajax handling can go nuts. The events are fired multiple times and so on.
    I've changed the code to register the events / ajaxs handling that way that it can deal with multiple elements with the views dom id.

+++ b/js/ajax_view.jsundefined
@@ -78,6 +73,27 @@ Drupal.views.ajaxView.prototype.attachExposedFormAjax = function() {
   this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings);
+  $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form).data('exposedFormAjax', this.exposedFormAjax);

The other drupal.ajax instance is stored on Drupal.views.instances, maybe we should unify that somehow? I don't know whether data attributes or actual variables are the better approach.

Finally I found some time to continue working on this.
To avoid storing the ajax configurations in the elements using e.g. $('input[type=submit], button[type=submit], input[type=image]', this.$exposed_form).data('exposedFormAjax', this.exposedFormAjax); I had to ensure that Drupal.views.instances[i] really is unique and it contains all the settings even if the handling is triggered multiple times for the same view.
This can happen if e.g. the ctools views content type is used (The patched one (#2035643: Views ajax support for the views content display) or this sandbox: https://drupal.org/sandbox/daspeter/2149085).
With the patch you can access and manipulate the ajax object before firing them:

    // Set the path including the adjusted facet.
    Drupal.views.instances['views_dom_id:' + Drupal.settings.ajax_facets.view].refreshViewAjax.options.url = ajax_path + queryString;
    // Ensure we load from the start.
    Drupal.views.instances['views_dom_id:' + Drupal.settings.ajax_facets.view].refreshViewAjax.options.data.page = 0;
    // Trigger a refresh of the view.
    $(Drupal.views.instances['views_dom_id:' + Drupal.settings.ajax_facets.view].refreshViewAjax.element).trigger('RefreshView');

Code from this sandbox: https://drupal.org/sandbox/daspeter/2165417

I just had the possibility to test this in another, very simple, setup and it works like a charm (exposed filter, sort and ajax facets).