This question is being asked to check if it is POSSIBLE to do what I’d like it to do, not so much as a HOW to do it question (although if someone wants to pen something up is always good too). As I am more in the infancy of my web-dev learning I figured it prudent to determine if the hopeful result is even possible before investing the substantial time into it to achieve it. I have read conflicting things from various references on the web and figured this is the place to ask others' opinions to be sure one way or the other.
I’m running Drupal 8 (8.9.13 at time of writing). The page uses Views. To keep it simple the page has 3 sections; a top, middle, and bottom (this is the page/content itself, this is NOT a header, body, footer). The bottom section/View consists of multiple div’s/sections. The content of all 3 sections is primarily links.
I’m using/trying the module ‘Views Auto-Refresh D8’. After install and setup it updates the page perfectly EXCEPT that not only after a content update, but ALSO after each Ajax check/interval the page returns to the top of the page, causing the user experience to be unacceptable. In other words, if reading the bottom of the page, once the page automatically checks for updates via Ajax the page suddenly returns to top of page.
Researching this I got the impression that is normal behavior for Ajax. I also got the impression that this behavior can be overridden, however, other sources made it sound as though it can’t. Hence the purpose of this question here.
The Javascript for the ‘Views Auto-Refresh D8’ module looks like this:
(function ($, Drupal, drupalSettings) {
// START jQuery
Drupal.behaviors.views_autorefresh = {
attach: function(context, settings) {
for(var view_name in settings.views_autorefresh) {
for(var view_display in settings.views_autorefresh[view_name]) {
var interval = settings.views_autorefresh[view_name][view_display];
var execution_setting = '.view-'+view_name.replace(new RegExp('_','g'),'-')+'.view-display-id-'+view_display;
if($(context).find(execution_setting).once(execution_setting).length > 0) {
// Delete timeOut before reset it
if(settings.views_autorefresh[view_name][view_display].timer) {
clearTimeout(settings.views_autorefresh[view_name][view_display].timer);
}
settings.views_autorefresh[view_name][view_display].timer = setInterval(
function() {
Drupal.behaviors.views_autorefresh.refresh(execution_setting)
}, interval
);
}
}
}
},
refresh: function(execution_setting) {
$(execution_setting).trigger('RefreshView');
}
}
Through researching this question I found closely related questions saying the page refresh can be bypassed/prevented by adding a javascript function such as:
preventDefault() / event.preventDefault()
However I’m not entirely sure if this event method can be used to achieve the result I’m pursuing? Or if the following is a better avenue to explore?
The other possible workaround/idea I came up with and am curious about is that I use a module called ‘Geysir’ that allows me to update my content directly on the page from the front-end. The content can be moved, deleted directly on the page, or even modified within a modal overlay that then updates the content without the page refresh/scroll back to top that the ‘Views Auto-Refresh D8’ is doing. I’m wondering if the logic from the Geysir module can be applied to the Views Auto-Refresh D8 module? With my moderate javascript knowledge it looks like the relevant js/Ajax logic in the Geysir module is:
$.each(Drupal.ajax.instances, function (index, event) {
var element = $(event.element);
if (element.hasClass('geysir-paste')) {
if (href === event.element_settings.url) {
event.options.url = event.options.url.replace('/' + paragraph_id + '/', '/' + parent_id + '/');
}
}
});
});
});
return false;
});
}
};
Drupal.AjaxCommands.prototype.geysirReattachBehaviors = function() {
Drupal.ajax.instances = Drupal.ajax.instances.filter(function(el) {
return el;
});
Drupal.attachBehaviors();
};
})(jQuery, Drupal, drupalSettings);
(lines 40-64)
That’s pretty much where I’m at before moving forward. So:
- Is it even possible to maintain end-users scroll/page position while the Ajax call is being made and when content is updated via Ajax?
and if so,
- Which avenue above is best to pursue, OR, is there yet another avenue I haven’t yet run across yet?