Почему при клике на кнопку страница вьюшки перезагружается при том что использую RefreshView? Как решить данную проблему?

Главные вкладки

Аватар пользователя nathan158 nathan158 17 сентября 2022 в 22:28

Проблема:

Перезагружается страница вьюшки при клике на кнопки даже после добавления RefreshView:

 (function($, Drupal) {
  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_frontpage" class="grid-view">Grid</button>
<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

 (function($, Drupal) {
  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);
  }
}
?>

Комментарии

Аватар пользователя ivnish ivnish 18 сентября 2022 в 8:02

А зачем рефрешить вьюху самому, если у вас там в коде $exposedForm.submit() и ajax включен

Что происходит если вручную применить фильтры, вьюха обновляется по аяксу?

Аватар пользователя nathan158 nathan158 18 сентября 2022 в 14:35

VERF фильтры (в виде линков) со стрелочками также перезагружают страницу (так не должно быть). А другие (чекбоксы) не перезагружают страницу(по аяксу). Я пробовал для теста убрать VERF фильтры из View чтобы проверить будет ли дальше перезагружаться страница на кнопках смены view mode, но это ничего не изменило.

Думал может как-то влияет better exposed filter и также для теста поставил базовый, но также без изменений.

Аватар пользователя gun_dose gun_dose 18 сентября 2022 в 10:20

Потому что в коллбэк обработки клика нужно в качестве аргумента передавать event и вызывать event.preventDefault()

Аватар пользователя nathan158 nathan158 18 сентября 2022 в 14:09

добавил e.preventDefault();

(function($, Drupal) {
  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']
?>

?