2 вопроса по AJAX

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

Аватар пользователя zheka2 zheka2 26 апреля 2015 в 16:30

Приветствую

Пишу модуль, выводит страницу с таблицей и параметрами фильтрации, возникло 2 вопроса

1. На странице группа чекбоксов, при нажатии на обновить сейчас я создаю new Drupal.ajax(...). Но не пойму как мне туда передать отмеченные галки. Или нужно выводить форму с чекбоксами, а уже форму отправлять ajax'ом? Если так то эту форму правильно выводить через хук или просто добавить тег form в шаблон страницы?

2. Сейчас вся страница которую выводит модуль темизируется одним шаблоном mymodule.tpl.php. В ответ мне надо отдать только таблицу. Предполагаю что шаблон нужно разбить на 2 части: mymodule_page.tpl.php и mymodule_table.tpl.php. При ajax вызове отдавать вторую, а если пользователь запрашивает всю страницу целиком как правильно сделать, получить
$html_table= theme('mymodule_table');
и результат отдать в
echo theme('mymodule_page', array('table' => $html_table));
Или это по другому делается?

Просветите пожалуйста Smile

Комментарии

Аватар пользователя zheka2 zheka2 26 апреля 2015 в 23:14

Я пересмотрел это "море". Во всех примерах рассматривается вариант с хуком form или form_alter. У меня же модуль не связан с нодами.
Посмотрел примеры из examples.
По ajax, почти везде используется drupal_get_form, получается описание формы надо формировать в модуле, я же хотел весь вывод оставить в шаблоне, передав туда переменные, но для этого нужно понять как через "new Drupal.ajax" отправить запрос, документации по нему я не нашёл
По темизации, в одном из примеров как я и предположил для формирования страницы сначала вызываются функции темизации отдельных частей, а потом полученные html передаются параметрами в шаблон страницы

Аватар пользователя sg85 sg85 27 апреля 2015 в 0:50

"zheka2" wrote:
Я пересмотрел это "море". Во всех примерах рассматривается вариант с хуком form или form_alter. У меня же модуль не связан с нодами.

wtf? Что за хук form? и при чем тут вообще ноды?

"zheka2" wrote:
По ajax, почти везде используется drupal_get_form, получается описание формы надо формировать в модуле, я же хотел весь вывод оставить в шаблоне, передав туда переменные, но для этого нужно понять как через "new Drupal.ajax" отправить запрос, документации по нему я не нашёл

по умолчанию drupal ajax как раз только в формах и используется, но ничего не мешает использовать его отдельно от Form API, как это делает, например, CTools

Я так понимаю, аякс Вам понадобился для тех самых фильтров, тогда и выводите фильтры через drupal_get_form, в чем проблема то?

По поводу new Drupal.ajax() - тут все достаточно просто - передаете ID элемента, сам элемент(DOM, не jquery), и параметры запроса(url, event и т.д.), указанный урл должен возвращать массив Drupal Ajax Commands, процесс формирования этого массива обязательно должен альтериться, иначе вся эта конструкция не будет иметь никакого смысла, то есть - если Вы не пишете модуль для drupal.org - вся эта хрень Вам даром не сдалась и прекрасно можно обойтись с обычным $.get()

а про второй вопрос я ничего не понял, если он связан с первым - и Вам ну прям ппц как нужен именно Drupal.ajax - то ответ должен быть завернут в аякс комманды. В случае с каким-нибудь $.get() - можно целиком отдать страницу и выдернуть с неё нужный кусок, например, $('#table-id').html($('#table-id',response).html()); а в случае с $.load() эта конструкция будет встроена в сам метод.

Аватар пользователя Orion76 Orion76 27 апреля 2015 в 12:08

Почитайте какие-нибудь руководства по Drupal Form API.
И в 95% случаев js-код писать вообще не придется.

Ваша задачка решается просто, но у Вас не достаточно базовых знаний, чтобы понять разъяснения по ее решению.

Аватар пользователя zheka2 zheka2 27 апреля 2015 в 19:43

"sg85" wrote:
wtf? Что за хук form? и при чем тут вообще ноды?

hook_form "This is a node-type-specific hook" . Я написал что примеры с ajax в основном на примере этого хука
"sg85" wrote:
Я так понимаю, аякс Вам понадобился для тех самых фильтров, тогда и выводите фильтры через drupal_get_form, в чем проблема то?

в случае с drupal_get_form "описание формы надо формировать в модуле, я же хотел весь вывод оставить в шаблоне, передав туда переменные" . Я разок попробовал описать массивом, получился немаленький листинг, поэтому и хочу вынести форму в шаблон и забыть про неё.
"sg85" wrote:
По поводу new Drupal.ajax() - тут все достаточно просто - передаете ID элемента, сам элемент(DOM, не jquery), и параметры запроса(url, event и т.д.), указанный урл должен возвращать массив Drupal Ajax Commands, процесс формирования этого массива обязательно должен альтериться, иначе вся эта конструкция не будет иметь никакого смысла, то есть - если Вы не пишете модуль для drupal.org - вся эта хрень Вам даром не сдалась и прекрасно можно обойтись с обычным $.get()

"и параметры запроса" куда их присваивать и в каком формате, я не силён в js. Мне нужно перебрать все чекбоксы вручную или как-то иначе?
"sg85" wrote:
а про второй вопрос я ничего не понял, если он связан с первым - и Вам ну прям ппц как нужен именно Drupal.ajax - то ответ должен быть завернут в аякс комманды. В случае с каким-нибудь $.get() - можно целиком отдать страницу и выдернуть с неё нужный кусок, например, $('#table-id').html($('#table-id',response).html()); а в случае с $.load() эта конструкция будет встроена в сам метод.

"и Вам ну прям ппц как нужен именно Drupal.ajax" вовсе нет, я просто хочу по-возможности использовать друпальные инструменты.
В итоге я разбил шаблон на 2 части, в случае ajax отдаю только таблицу, в случае обычного запроса, получаю html таблицы, и отдаю его в качестве параметра шаблону всей страницы, которая просто выводит его. Правильно это или нет я не знаю, об этом я и спрашивал.
"orion76" wrote:
Почитайте какие-нибудь руководства по Drupal Form API.

И в 95% случаев js-код писать вообще не придется.
Ваша задачка решается просто, но у Вас не достаточно базовых знаний, чтобы понять разъяснения по ее решению.


Спасибо, читаю, с наскоку всё не могу охватить. 95% это, как я понимаю, в случае ajax только при использовании Form API. Почему я не хотел их использовать я написал выше. Если не принципиально с точки зрения drupal way использовать $.load()/$.get() вместо Drupal.ajax, пусть так, мне проще, просто в друпале не всё что проще - правильно

P.S. сори за большой листинг

Аватар пользователя sg85 sg85 28 апреля 2015 в 4:43

"zheka2" wrote:
hook_form "This is a node-type-specific hook" . Я написал что примеры с ajax в основном на примере этого хука

это частный случай, значит попросту не там копаете.

по всему остальному - если Вы отказываетесь от Form API, то и Drupal.ajax Вам будет бесполезен, ибо там вся задумка в том, чтобы во первых сделать процесс вывода формы и работу аякса более или менее атомарным, во вторых, дать возможность на разных этапах вмешиваться в этот процесс, например, у Вас есть 2 темы оформления - одна обычная, другая для мобильных устройств и поведение одной и той же формы у них разное, а как только Вы выводите форму как обычный HTML - все это дело накрывается медным тазом, потому, раз уж осознанно решили отойти от Drupal API в самом "фундаменте" формы, городить довольно сложный забор не имеет никакого смысла.

Как уже писал орион, тут прекрасно можно было бы обойтись без единой строчки JS. Однако, если уже решились использовать обычный html - придется использовать и JS, но лучше не Drupal.ajax, а обычный jQuery, ибо писать придется несколько меньше(смотрите в сторону $.load, судя по тексту, Вам его за глаза), при том, что разницы во всем остальном уже не будет, должно получиться что-то вроде:

(function($, Drupal){
  Drupal.behaviors.MyForm = {
    attach: function(context, settings){
      $('#form_id', context).once('myform',function(){
        $(this).submit(function(e){
          e.preventDefault();
          $('#content-wrapper').load('/my/url #content',$(this).serialize());
          Drupal.attachBehaviors($('#content-wrapper').get(0), settings);
        });
        $('select,input',this).change(function(){
          $(this).parents('form').submit();
        });
      });
    }
  };
})(jQuery, Drupal);

То есть, при вызове attachBehaviors(которое вызывается, например, при загрузке документа, открытии попапа, аякс загрузке чего-то там и т.д.), ищем форму #form_id в заданном контексте, на всякий случай делаем проверку на уже выполнявшуюся работу с этой формой через Once (чтобы случайно 2 раза подряд её не обработать, ибо мало ли...), для самой формы задаем событие submit, в котором блокируем стандартное поведение сабмита формы, вместо него вызываем аякс загрузку данных по адресу /my/url, передавая состояние всех элементов формы в качестве гет параметров, выбираем из ответа только элемент с классом #content со всем его содержимым и кладем его внутрь #content-wrapper, заменяя все его содержимое, после чего вызываем тот самый attachBehaviors для всего, что внутри свежеподгруженного #content-wrapper, ибо там может оказаться какой-нибудь аякс или типа того. Ну и напоследок, при изменении любого инпута или селекта в этой форме делаем так, что бы форма сразу же сабмитилась. Для полного счастья не хватает только индикатора аякс загрузки - при желании тоже 2 строчки - перед загрузкой показываем, после загрузки прячем.

Пример тут только для примера, не гарантирую его работосопособность и так далее.

Аватар пользователя sg85 sg85 29 апреля 2015 в 17:31

Там кстати ошибка есть, Drupal.attachBehaviors надо вызывать в success колбеке $.load, иначе выполнится до аякс загрузки а не после.

Аватар пользователя zheka2 zheka2 29 апреля 2015 в 19:45

Спасибо, понятно

Ещё один нубский вопрос если можно, иногда при использовании Form API контролы формы нужно разбросать по форме вперемешку с контентом не имеющем отношение к форме, как правильно выводить? Сейчас вывожу через #markup, это правильно ?

Аватар пользователя sg85 sg85 30 апреля 2015 в 3:54

Это ничему не мешает, так что вполне годный способ, но кроме #markup есть еще #prefix и #suffix - выводят html контент до и после элемента, все это годится для простых случаев, а в сложных случаях, например, список кол-ва товаров в корзине(самодельной), можно вывести как таблицу со всеми полями, аякс кнопками и т.д, путем создания своей функции темизации элемента формы и вывода нужного элемента формы через эту функцию, но это уже по сложнее