Проблема:
Перезагружается страница вьюшки при клике на кнопки даже после добавления RefreshView:
Drupal.behaviors.switchContentViewMode = {
attach: function attach(context) {
$('.product-list-wrapper .wrapper-buttons button', context).each(function () {
$(this).on('click', function () {
let $exposedForm = $('#views-exposed-form-list-of-products-page-1');
$exposedForm.find('.view_mode_changer').attr('value', $(this).attr('value'));
$exposedForm.submit();
// Добавил RefreshView чтобы страница не перезагружалась после клика:
$.each(Drupal.views.instances, function (index, element) {
if (element.settings.view_name == 'list_of_products') {
element.settings.view_args = $(this).attr('value');
$('.js-view-dom-id-' + element.settings.view_dom_id).trigger('RefreshView');
}
});
})
});
}
};
Я где-то допустил ошибку в коде после комментария? Или RefreshView не поможет мне в данном случае предотвратить перезагрузку страницы и нужно сделать как-то по другому?
Больше деталей:
Задача:
Нужно было сделать на странице вьюшки две кнопки которые меняют view mode в вьюшке.
1. Кнопка Grid меняет view_mode на product_card_frontpage и отображается три карточки товаров на всю ширину (в настройках по дефолту в вьюшке данный view mode)
2. Кнопка List меняет view_mode на product_card_full_width и и отображается одна карточка товара на всю ширину плюс дополнительное поле появляется в карточке.
Реализовал вот так:
1. В настройках вьюшки задал Use Ajax
2. Создал две кнопки в твиге вьюшки:
<button value="product_card_full_width" class="list-view">List</button>
3. Добавил hidden поле view_mode_changer к экспознутой форме вьюшки:
<?php
if ($form_id == 'views_exposed_form' && $form_state->getStorage('view')['view']->id() == 'list_of_products') {
$form['view_mode_changer'] = [
'#type' => 'hidden',
'#value' => 'product_card_frontpage',
'#attributes' => [
'class' => ['view_mode_changer'],
],
];
}
?>
4. При клике на кнопки меняю значение поля view_mode_changer
Drupal.behaviors.switchContentViewMode = {
attach: function attach(context) {
$('.product-list-wrapper .wrapper-buttons button', context).each(function () {
$(this).on('click', function () {
let $exposedForm = $('#views-exposed-form-list-of-products-page-1');
$exposedForm.find('.view_mode_changer').attr('value', $(this).attr('value'));
$exposedForm.submit();
// Добавил RefreshView чтобы страница не перезагружалась после клика:
$.each(Drupal.views.instances, function (index, element) {
if (element.settings.view_name == 'list_of_products') {
element.settings.view_args = $(this).attr('value');
$('.js-view-dom-id-' + element.settings.view_dom_id).trigger('RefreshView');
}
});
})
});
}
};
5. С помощью хука hook_views_pre_view() меняю view mode:
<?php
function entity_product_admin_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
if ($view->id() == 'list_of_products') {
$row_options = $view->display_handler->getOption('row');
$row_options['options']['view_mode'] = $view->getExposedInput()['view_mode_changer'] ?? 'product_card_frontpage';
$view->display_handler->overrideOption('row', $row_options);
}
}?>
Комментарии
А зачем рефрешить вьюху самому, если у вас там в коде $exposedForm.submit() и ajax включен
Что происходит если вручную применить фильтры, вьюха обновляется по аяксу?
VERF фильтры (в виде линков) со стрелочками также перезагружают страницу (так не должно быть). А другие (чекбоксы) не перезагружают страницу(по аяксу). Я пробовал для теста убрать VERF фильтры из View чтобы проверить будет ли дальше перезагружаться страница на кнопках смены view mode, но это ничего не изменило.
Думал может как-то влияет better exposed filter и также для теста поставил базовый, но также без изменений.
Потому что в коллбэк обработки клика нужно в качестве аргумента передавать event и вызывать event.preventDefault()
добавил e.preventDefault();
Drupal.behaviors.switchContentViewMode = {
attach: function attach(context) {
$('.product-list-wrapper .wrapper-buttons button', context).each(function () {
$(this).on('click', function (e) {
e.preventDefault();
let $exposedForm = $('#views-exposed-form-list-of-products-page-1');
$exposedForm.find('.view_mode_changer').attr('value', $(this).attr('value'));
$exposedForm.submit();
})
});
}
};
Но все равно страница перезагружается. И что интересно при перезагрузке к стандартному пути:
http://website/list
добавляется:
http://website/list?view_mode_changer=product_card_full_width
Я вот думаю а может причина перезагрузки связана с этой строчкой в хуке hook_views_pre_view():
<?php
$row_options['options']['view_mode'] = $view->getExposedInput()['view_mode_changer'] ?? 'product_card_frontpage';
?>
И может нужно что-то другое ложить в
<?php
$row_options['options']['view_mode']
?>
?