Установить значение SHS из JS

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

Аватар пользователя OldWarrior OldWarrior 10 декабря 2020 в 12:02

Не совсем тривиальная задача выпала вашему покорному слуге.

Имеем 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 со схожими проблемами.

В настоящий момент я уже исчерпался и больше не вижу каких-либо потенциальных решений. Перепиливание всей формы - занятие слишком длительное и в рамках текущего задания вряд ли целесообразно.

Возможно, у кого-то есть какие-то мысли/соображения или даже решения приведённой задачи. Буду признателен.

Комментарии

Аватар пользователя adano adano 15 декабря 2020 в 14:31
.val(TERM_ID).trigger('change');

P.S. С chosen и select2, всегда все адекватно отрабатывает, даже на jquey-1.4.4.
Если это не катит, значит дело в shs.

Аватар пользователя OldWarrior OldWarrior 16 декабря 2020 в 6:57

adano wrote: .val(TERM_ID).trigger('change');

Было, как и различные вариации с .triggerHandler('change') и $.Deferred-конструкции вида $.when() - $.done(), применяемые и к основному элементу (term select) и вышележащим (SHS, Chosen). Не работает.

Дело в SHS, разумеется. Но как решать вопрос - пока непонятно.

PS. Я повторюсь: важно, чтобы SHS визуально отобразил выбор, установив соответствующие значения в обоих селектах. Если не отображать выбор (т.е. отправлять .val(TID).change()) только корневому элементу, то всё работает как должно - и валидация на сабмите и коллбек по событию 'change' и сохранение ноды с правильно установленным значением термина. Но пользователь при этом не видит текущий выбор в SHS. Если же отправлять change()/trigger('change') помимо основного элемента ещё и дочерним надстройкам (SHS), то начинаются проблемы.

Аватар пользователя OldWarrior OldWarrior 17 декабря 2020 в 10:35

adano wrote: А выкинуть shs вообще никак, сильно большая иерархия?

Выкинуть нельзя, это как бы условие ТЗ. Иерархия всего два уровня - родители и дочерние термины.

PS. Костыли просмотрел, ничего не подходит.

Аватар пользователя voviko voviko 23 декабря 2020 в 10:57

Костыли типа ставить значения из input при сохранении и кастомной валидацией? пользователь видит что требуется, а дальше вроде можно и придумать что нибдь.

Аватар пользователя OldWarrior OldWarrior 25 декабря 2020 в 10:24

Не совсем понял, что именно тут имеется в виду.

Если читать $form_state['input'], то (не забываем, что SHS - всего лишь плагин-надстройка) имеется только значение корневого/основного элемента, который суть обычный селект выбора термина, но визуально скрытый. Значения селектов плагина SHS (родитель + дочка) отсутствуют.