Здрасти.
Может кто сталкивался, поскажите, пожалуйста.
Установлен коммерц, каталог вывожу через въюху. Хочу чтоб товары подгужались динамически. Ставлю инфинити скролл - вид приобретает как раз такой как хотел, но кнопка добавления товара в корзину у тех товаров, что подгружаются после, при помощи скролла не работает. А именно, при нажатии на нее, на белой страничке показывает мне
ну это ответ от views/ajax
Делаю альтер на форму добавления в корзину(или меняю жаваскриптом. результат один), чтоб экшен в форме был корректный - в результате сабмит не срабатывает, а кнопочка просто перезагружает страничку.
Сразу оговорюсь, аждакс к форме пока не прикручивал.
Кто нибудь скрещивал их или может есть более разумное решение??
Комментарии
Смотрели console на предмет js ошибок? jquery_update стоит?
Views Load More нормально работает с Drupal.settings.
Infinite Scroll - нет. Подробности внутри views-infinite-scroll.js
jquery_update установлен
в консоле никаких ошибок нет
В чистом виде Views Load More ведет себя так же.
может нужно что то дописать в форму? ну там пересобрать сеттингс, например?
судя по тому что показывает фаербаг при успешном отправлении товара в корзину посылается пост запрос и принимается гет ответ. а то что подгружается динамически, запрос отпраляет, но ответа никакого нет..
В настройках вьюса включно Использовать AJAX ?
канешн, без него не пашет Views Load More..
Странная ситуация. Тут, однако, дебажить надо (с).
Но вместо траты времени на отладку форм, я бы посоветовал потратить его на отказ от форм добавления в корзину.
Дело вот в чем:
В друпале каждая форма имеет токен, сгенерённый на основании id сессии юзера. При сабмите формы токен сравнивается с данными из кеша форм, и в случае несовпадения - сабмит не обрабатывается.
Это, в общем-то, логично: надо добавить товар в корзину именно того юзера, который кликнул на кнопку добавления, при этом этот юзер может быть (и скорее всего - будет) анонимом, т.е. его uid=0, поэтому юзеры различаются по id их сессий.
При этом, показывая юзеру каталог из, допустим, 100 товаров - в кеш форм помещается 100 форм (и 100 форм стейтов) для одного юзера. При посещаемости 100 уников в сутки, кеш форм растёт со скоростью 100х100х2 (форма + её состояние) = 20000 записей в сутки.
При этом, невозможно кешировать страницы каталога - т.к. закешированая страница будет содержать формы с токенами на основании id сессии определённого юзера, и сабмит этих форм другими юзерами работать не станет.
В общем, моё мнение - формы добавления в корзину это плохо.
Чем тратить время на разбор полётов с формами, лучше сделать контейнер, содержащий id товара / id дисплея, при клике на который - дёргать аяксом коллбек на сервере, который будет добавлять товар в корзину.
Я делал такой коллбек как отдельный ресурс для Services, но можно и через hook_menu().
Код коллбека - чуть менеее, чем полностью был позаимствован из commerce_cart_add_to_cart_form_submit()
http://xandeadx.ru/blog/drupal/751
Штука, безусловно, хорошая, но она не сделает то что мне нужно, т.к. заставляет срабатывать тот же самый сабмит, но через аджакс, а как я уже писал, сабмит не срабатывает для вновь подгруженых товаров.
Спасибо, за разъяснение.
С формами разобраться всетаки стоит, ну или обработчик вешать именно на кнопку, чтоб при отключенном жаваскрипте все продолжало работать...
Если че придумаю, отпишусь..
не прикручивается обрабочик = 100%, решение лежит в плоскости .on , но там есть тонкости правильного использования, если не хотите заворачиватся, то используйте событие .on("DOMNodeInserted"
Не удалось вообще никак до сабмита достучаться, пришла в голову такая мысль...
Если сделать так, какие проблемы могут быть?
я понимаю что выглядит странно, зато работает везде, включая инфинитискролл, можно добавлять аджаксовые команды и вроде с кешем все ок должно быть.
<?php
function commerce_custom_ajax_add_to_cart_menu() {
return array(
'add_to_cart' => array(
'page callback' => 'add_to_cart',
'type' => MENU_NORMAL_ITEM,
'access callback'=>true,
),
);
}
function
commerce_custom_ajax_add_to_cart_form_alter(&$form, &$form_state, $form_id) {if (strpos($form_id, 'commerce_cart_add_to_cart_form') !== FALSE) {
$form['submit']['#attributes']['class'][] = 'use-ajax-submit';
$form['submit']['#id'] = 'sub_'.$form['#id'];
$form['#attached']['library'][] = array('system', 'jquery.form');
$form['#attached']['library'][] = array('system', 'drupal.ajax');
$form['#action'] = url('add_to_cart');
}
}
function
add_to_cart(){global $user;
$product = commerce_product_load($_POST['product_id']);
$line_item = commerce_product_line_item_new($product, $_POST['quantity']);
$product_nid = db_select('field_data_field_product', 'f')
->fields('f', array('entity_id'))
->condition('f.bundle', 'product_display')
->condition('f.field_product_product_id', $_POST['product_id'])
->range(0, 1)
->execute()
->fetchField();
$line_item->commerce_display_path['und'][0]['value'] = drupal_get_path_alias('node/'.$product_nid);
commerce_cart_product_add($user->uid, $line_item);
if (strpos($headers['Accept'], 'javascript') !== FALSE){
$result = array(
'#type' => 'ajax',
'#commands' => array(),
);
drupal_get_messages();
ajax_deliver($result);
drupal_exit();
}
else{
drupal_goto($_SERVER['HTTP_REFERER']);
}
}
?>
Осталось выбросить форму - и будет совсем хорошо.
Несколько замечаний:
'type' => MENU_NORMAL_ITEM,
надо
'type' => MENU_CALLBACK,
$product_nid = db_select
красивее через EntityFieldQuery
$line_item->commerce_display_path['und'][0]['value'] = drupal_get_path_alias('node/'.$product_nid);
я бы хранил системный путь вместо алиаса: он может измениться и ссылка на дисплей станет битой. Алиас лучше генерить "на лету" при каждом обращении к line item.
Держите https://www.drupal.org/files/issues/views_load_more-ajax-forms.patch
views выводит с load more вылечил этим патчем, теперь при подгрузке товаров, они добавляются в корзину без проблем