[Решено] Drupal.behaviors не работает с модулем UC Ajax Cart

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

Аватар пользователя petrowsb petrowsb 10 января 2017 в 14:40

Доброго времени всем. Столкнулся с проблемой, бьюсь третий день, застопорился на одном месте и ни в какую( В гугле скоро забанят, наверное, за чрезмерную активность.)

Суть в следующем: Есть Drupal 7 + Udercart 3 + модуль UC Ajax Cart (он же UC Driven Cart). Модифицировал форму корзины через хук pizznroll_form_uc_cart_view_form_alter, с целью добавить кнопки + и - в строку количества, тут проблем нет, кнопки появились с нужными мне айдишниками. Для управления их поведением использую jQuery, файл скрипта checkout.js загруженный через .info файл темы. Все работает ровно до того момента, пока не нажмешь либо "обновить корзину" либо" удалить строку товара" из корзины, т.е. после выполнения ajax запроса модулем UC Ajax Cart. Нагуглил решение(эту инфу похоже блоггеры просто передирают друг у друга:)) использовать обертку Drupal.behaviors.
Что в итоге получил: никакой разницы. Скрипт отрабатывает только один раз, пробовал писать слово behaviours c ошибкой - скрипт не работает совсем, значит синтаксис верный.

Далее плюнул на страницу корзины, очистил скрипт, убрав всю логику, и сделал просто кусок кода для проверки чтобы посмотреть как он будет работать на других страницах:

(function ($, Drupal)
{Drupal.behaviors.my_theme ={
    attach:function(context, settings){      
     
      //$('#edit-continue-shopping').val('НЕВАЛЯШКА'); // для теста изменим название кнопки "Продолжить покупки"
      $('#edit-continue-shopping', context).val('НЕВАЛЯШКА'); // при загрузке страницы текст меняется, но после первой отработки ajax модуля возвращается в исходное состояние
      $('#ajaxCartToggleView').html('Мусорка'); // переименовал блок корзины, чтобы сразу видеть, что скрипт отрабатывает, эта строка работает, ajax его не обновляет, поэтому текст остается неизменным
      alert('test');   // срабатывает ТОЛЬКО ОДИН РАЗ при загрузке страницы  
    }
  }  
})(jQuery, Drupal);

И вот что обнаружил: на странице ноды, у меня это страница товара, есть радиокнопки выбора атрибутов товара(при изменении атрибута меняется цена с помощью ajax), эта штатная возможность уберкарта, так вот при выборе атрибута, вышеуказанный скрипт нормально отрабатывает, несколько раз выскакивает alert(), т.е. конструкция вполне работоспособна. Но при нажатии кнопки "Добавить в корзину" - ничего не происходит, т.е. товар то в корзину динамически добавляется, но скрипт не запускается, эта кнопка динамически добавляет в корзину посредством модуля UC Ajax Cart, т.е. получается что мой скрипт не дружит с модулем UC Ajax Cart, а с Ubercart работает нормально. Т.е. необходимо как-то заставить скрипт обновляться при изменении страницы с помощью модуля UC Ajax Cart.

Читал про attachBehavior, какие только варианты не перепробовал, никак не хочет работать, чуствую, что решение где-то рядом, но мозг уже взорван на куски,
как это использовать? Есть у кого-нибудь варианты что делать, может кто сталкивался?

Лучший ответ

Аватар пользователя petrowsb petrowsb 10 января 2017 в 18:23

Работает и так и так, я просто спросил в чем неточность, я пока еще путаюсь в понятиях jQuery.
Исправляю по вашей подсказке и помечаю как окончательное решение.

(function ($, Drupal)
{Drupal.behaviors.my_theme =
  {attach:function(context, settings)
    {
      $(document).ajaxComplete(function(event, xhr, settings) {
             // какой-то код
      });
    }
  }  
})(jQuery, Drupal);

Комментарии

Аватар пользователя petrowsb petrowsb 10 января 2017 в 16:10

Кажется заработала следующая конструкция:

(function ($, Drupal)
{Drupal.behaviors.my_theme =
  {attach:function(context, settings)
    {
      jQuery(document).ajaxComplete(function(event, xhr, settings) {
      $('#edit-continue-shopping', context).val('НЕВАЛЯШКА'); // работает
      $('#ajaxCartToggleView').html('Мусорка'); // работает
      alert('test');   // работает
      });
    }
  }  
})(jQuery, Drupal);

Подсказку нашел Здесь.

Там сказано, что ajaxComplete начиная с версии jQuery 1.8 должен навешиваться на document. Выставил в конфигурации 1.8 вместо 1.7, очистил кеш и вуаля). Потом поменял снова на 1.7 c очисткой кеша - снова работает. Потом убрал для проверки jQuery(document).ajaxComplete(function(event, xhr, settings) {...}, очистил кеш - не работает. Снова вернул jQuery(document).ajaxComplete, очистка кеша снова заработало. Сегодня еще потестирую, если все нормально, вопрос можно считать решенным. Блин, всегда нужно не забывать чистить кеш, даже если он отключен!

Аватар пользователя petrowsb petrowsb 10 января 2017 в 18:23

Работает и так и так, я просто спросил в чем неточность, я пока еще путаюсь в понятиях jQuery.
Исправляю по вашей подсказке и помечаю как окончательное решение.

(function ($, Drupal)
{Drupal.behaviors.my_theme =
  {attach:function(context, settings)
    {
      $(document).ajaxComplete(function(event, xhr, settings) {
             // какой-то код
      });
    }
  }  
})(jQuery, Drupal);
Аватар пользователя postgres postgres 10 января 2017 в 18:23

Так как вы делаете - неправильно, работать будет 1 или 2 раза - потом заглохнет.. потому что с каждым откликом вы будете навешивать обработчик еще и еще...
Сделайте так внутри вместо:

jQuery(document).ajaxComplete(function(event, xhr, settings) {
      $('#edit-continue-shopping', context).val('НЕВАЛЯШКА'); // работает
      $('#ajaxCartToggleView').html('Мусорка'); // работает
      alert('test');   // работает
      });
if (!$('#myForm').hasClass('wasInit')){
jQuery(document).ajaxComplete(function(event, xhr, settings) {
      $('#edit-continue-shopping', context).val('НЕВАЛЯШКА'); // работает
      $('#ajaxCartToggleView').html('Мусорка'); // работает
      alert('test');   // работает
      });
    $('#myForm').addClass('wasInit');
}

Суть простая - вы вешаете обработчик еще и еще раз при каждом ajax, а надо только один раз. ПОэтому либо это делать в $(document).ready() (что не Друпал типа вэй)
либо проверять, что инициализация уже была. Вешайте класс на форму и проверяйте его наличие.

Аватар пользователя Studio VIZA Studio VIZA 10 января 2017 в 18:41

petrowsb wrote:

и помечаю как окончательное решение.

Ну почему так? Антон, или вёрсткой разведите кнопочки, или всплывашку с пояснениями дайте, иначе это стодесятый промах, наводящий на мысли о изначально неверной логике.

Аватар пользователя postgres postgres 10 января 2017 в 19:20

Quote:

Скажи ка, умник, какая разница между $(document).ready() и (function ($)

зачем говорить, для этого документация есть.
Что касается глобального document - он в захват не попадает, поэтому обработчик на него повесится по любому, после каждого ajax
Понимаешь, нет? нет...

Аватар пользователя petrowsb petrowsb 10 января 2017 в 19:43

Добавил проверку на класс в рабочем варианте, не буду уже выкладывать, в вашем сообщении все достаточно понятно расписано. Сегодня сдал кровь, чувствую слабость, так что боюсь лишних скобок накопипастить) Кстати эта инфа мне попадалась, пока рылся в поисках ответа:)

Также не буду выкладывать кнопочки, ведь проблема была не в них, тем более что работа еще в процессе, хотя и сдвинулась с мертвой точки, я о них упомянул лишь в контексте проблемы, думал что uc_ajax_cart надо как-то "подключить" к моему скрипту. Наоборот постарался оставить суть.

В любом случае спасибо всем отписавшимся.

PS: надеюсь я правильно сделал, просто добавив [Решено] в заголовок темы) Специальной кнопочки не нашёл)

Аватар пользователя negociant negociant 10 января 2017 в 19:55

хулиган wrote:

Скажи ка, умник, какая разница между $(document).ready() и (function ($) ? Учи мат часть, бемби


$(document).ready(function(){}) просто эквивалентен $(function(){}) https://api.jquery.com/ready/ (обе конструкции по сути являются DOMContentLoaded event listener, но postgres их почему то считает не drupal way),
но не (function($) {})(jQuery) (анонимная самовызывающаяся функция)
Поэтому часто наблюдаю такое недопонимание среди молодежи из-за кажущейся схожести

Аватар пользователя postgres postgres 10 января 2017 в 20:04

Замечательно Lol
Причем тут этот пример, не имеющий отношения к топику?
Где тут у вас в топике применяется $(function(){}) ... мы на разные экраны смотрим? Lol

Аватар пользователя bumble bumble 10 января 2017 в 20:39
2

Немного убрался тут.
Господа! Подобные перепалки с элементами флуда - прямая дорога в бан. Напомню, что сроки удваиваются с каждым баном.

Заводите отдельные темы и обменивайтесь "любезностями" там (в рамках Drupal, естественно), ну или в ПМ...