Не совсем тривиальная задача выпала вашему покорному слуге.
Имеем Drupal 7, в нём форму (по сути node/add, но через Panels), в этой форме - выбор термина из иерархии 2-х уровней. Стандартный виджет выбора термина заменён на Simple hierarchical select (SHS), да ещё и поверх него установлен плагин Chosen.
Задача: по некоторому событию jQuery принудительно установить значение выбранного термина в SHS так, чтобы SHS отобразил текущий выбор и далее форма по сабмиту корректно прошла валидацию. Кроме того, по событию изменения значения этого поля необходимо генерировать вызов AJAX-колбека, который в свою очередь отображает либо прячет дополнительное поле в форме.То есть:
- должно быть установлено значение основного элемента (базовый скрытый селект для выбора термина).
- должно быть установлено значение родителя и дочки в SHS (оба скрыты плагином Chosen)
- должно быть установлено значение родителя и дочки в Chosen (это верхний отображаемый уровень).
- должен быть вызов AJAX-колбека, который проверяет значение основного элемента (по сути один term_id) и на основании проверки отображает другой элемент формы.
Теоретически всё вроде бы должно решаться одним .val(TERM_ID).change() применяемым к базовому/основному элементу. Частично так и есть, поскольку в этом случае колбек отрабатывает правильно и при сабмите форма проходит валидацию. Но текущие значения SHS (и Chosen) до сабмита остаются прежними, что сбивает с толку пользователей.
Пробовал массу всяких способов, из основного:
1. Помимо установки значения базового селекта устанавливать значения полей родителя и дочки SHS. Провал. Визуально в SHS может быть всё правильно, но поскольку SHS использует асинхронный AJAX для отображения поля дочки - основной элемент устанавливается в значение первого родительского элемента, далее начинается кавардак и валидацию поле уже не проходит.
2. К п.1 пробовал добавлять цепной вызов событий val().change() для родителя и дочки используя $.Deferred. Провал. Всё равно в $form_state SHS устанавливается только в значение родителя в лучшем случае. Хотя визуально выглядит как должно.
3. Пробовал устанавливать значение основного элемента и AJAX-релоадить SHS с помощью дополнительного колбека через специально введённый элемент-кнопку. Провал. В этом случае визуально SHS выглядит как должно, но а) не обрабатывается событие 'change' (видимо, после AJAX'а отваливаются handler'ы) и б) значение в поле обнуляется.
Повторюсь, это всё из основных вариантов - даже можно сказать из очевидных. В течении недели нагуглил и перепробовал в разных комбинациях ряд различных сакральных и нюансовых решений как на jQuery, так и на уровне Form API Друпала. Кстати, обнаружил, что у SHS есть незакрытые issues со схожими проблемами.
В настоящий момент я уже исчерпался и больше не вижу каких-либо потенциальных решений. Перепиливание всей формы - занятие слишком длительное и в рамках текущего задания вряд ли целесообразно.
Возможно, у кого-то есть какие-то мысли/соображения или даже решения приведённой задачи. Буду признателен.
Комментарии
Актуально.
Актуально.
P.S. С chosen и select2, всегда все адекватно отрабатывает, даже на jquey-1.4.4.
Если это не катит, значит дело в shs.
Было, как и различные вариации с
.triggerHandler('change')
и$.Deferred
-конструкции вида$.when()
-$.done()
, применяемые и к основному элементу (term select) и вышележащим (SHS, Chosen). Не работает.Дело в SHS, разумеется. Но как решать вопрос - пока непонятно.
PS. Я повторюсь: важно, чтобы SHS визуально отобразил выбор, установив соответствующие значения в обоих селектах. Если не отображать выбор (т.е. отправлять
.val(TID).change()
) только корневому элементу, то всё работает как должно - и валидация на сабмите и коллбек по событию 'change' и сохранение ноды с правильно установленным значением термина. Но пользователь при этом не видит текущий выбор в SHS. Если же отправлятьchange()/trigger('change')
помимо основного элемента ещё и дочерним надстройкам (SHS), то начинаются проблемы.имхо, отсюда какой-нибудь костыль можно попробовать - https://www.drupal.org/project/shs/issues/2144869
А выкинуть shs вообще никак, сильно большая иерархия?
Выкинуть нельзя, это как бы условие ТЗ. Иерархия всего два уровня - родители и дочерние термины.
PS. Костыли просмотрел, ничего не подходит.
Актуально.
Костыли типа ставить значения из input при сохранении и кастомной валидацией? пользователь видит что требуется, а дальше вроде можно и придумать что нибдь.
Не совсем понял, что именно тут имеется в виду.
Если читать
$form_state['input']
, то (не забываем, что SHS - всего лишь плагин-надстройка) имеется только значение корневого/основного элемента, который суть обычный селект выбора термина, но визуально скрытый. Значения селектов плагина SHS (родитель + дочка) отсутствуют.