I'm trying to refresh my View in Drupal 8 without reloading the page with this code :
(function ($, Drupal) {
'use strict';
setInterval(function() {
$('.view-message-activity-stream-timeline-public').trigger('RefreshView');
}, 10000);
})(jQuery, Drupal);
It works.
My problem :
Each time the view is refreshed, that page scolls back to the top of the view.
There is another problem with the refresh of the page. When I click the "Afficher plus" link at the bottom of the home page, page 2 appears below page 1, but it automatically closes when the page is refreshed.
Your issue is caused by the ViewAjaxController
adding up the ScrollTopCommand
to the ajax response every time it loads/reloads a view. You can find the involved lines in the method ajaxView
:
if (isset($pager_element)) {
$response->addCommand(new ScrollTopCommand(".js-view-dom-id-$dom_id"));
$view->displayHandlers->get($display_id)->setOption('pager_element', $pager_element);
}
Fortunately, it is possible to alter the command data that is sent to the client by implementing the hook_ajax_render_alter
, just remove the viewsScrollTop
command so that it is no longer triggered:
function <MODULE>_ajax_render_alter(array &$data) {
$view_name = '<view_name>';
$view_dom_id = '<view_dom_id>';
$selector = '.js-view-dom-id-' . $view_dom_id;
foreach ($data as $key => $value) {
if ($value['command'] === 'viewsScrollTop' && $value['selector'] === $selector) {
unset ($data[$key]);
break;
}
}
}
If you need to match the view_dom_id
with the view_name
, you can search for the settings
command in the $data array, eg. $cmd['settings']['views']['ajaxViews']
has a structure that looks like the following, note the array key precisely being built up from the views_dom_id :
[ajaxViews] => Array
(
[views_dom_id:<views_dom_id>] => Array
(
[view_name] => <view_name>
[view_display_id] => <view_display_id>
[view_dom_id] => <views_dom_id>
)
)