Alterator/form
Модуль (alterator lookout form)
Адресация виджетов по атрибуту name. Автоматическое заполнение диалога из бакенда и отправка значений в бакенд.
В этом модуле сделана попытка упростить работу со стандартными диалогами, практически убрав необходимость адресовать виджеты с помощью document:id.
Кроме того, этот модуль используется при работе с эффектами в модуле (alterator loоkout effects).
Описание относится к alterator-lookout-1.4-alt3. Интерфейс библиотеки, вероятно, еще не застабилизировался, поэтому массово применять ее пока не рекомендуется.
Примеры использования - в модулях alterator-{xinetd,datetime}
...
Пусть в диалоге поля ввода имеют атрибуты "name", значение которых совпадает с названиями соответствующих параметров при общении с бакендом. Также, эти имена могут иметь подписи к этим полям ввода (важно для работы с эффетами и для вывода сообщений об ошибках при несоответствии типов). В этом случае можно использовать следующие функции:
Работа с виджетами
- (form-get-elements-by-name document name) -- Получить список виджетов с указанным именем
- (form-element-apply document name . args) -- Применить args ко всем виджетам с именем name и вернуть список результатов
- (form-get-label document name) -- Получить первый виджет типа "label" с указанным именем. Сейчас используется только при выводе сообщений об ошибках несоответствия типа.
- (form-get-input document name) -- Получить поле ввода с указанным именем. "Поля ввода" -- это виджеты одного из типов (checkbox edit listbox spinbox slider timeedit dateedit combobox listbox textbox radiolistbox multilistbox checklistbox), значения которых мы хотим получать из бакенда и передавать обратно. Функция вываливается с исключением form-error, если таких полей больше одного.
- (form-input-get-value document name) -- получить значение поля с именем name
- (form-input-set-value! document name val) -- записать значение в поле с именем name
Работа с бакендом:
- (form-read document url . args) -- прочитать данные из бакенда (action read) и заполнть все соответствующие поля
- (form-write document url . args) -- отправить в бакенд (action write) значения всех полей
- (form-read-names document names url . args) -- прочитать из бакенда (action read) указанные параметры и заполнить соответствующие поля
- (form-write-names document names url . args) -- отправить в бакенд (action write) значения полей с указанными именами
Здесь document - документ в рамках которого происходит поиск виджетов. url и args -- аргументы для общения с бакендом...
Кроме того, в /std/base определены обертки, устанавливающие document в document:root, а также выводящие окно предупреждения при ошибках в общении с бакендом:
- (form-read/message url . args)
- (form-write/message url . args)
- (form-read-names/message names url . args)
- (form-write-names/message names url . args)
Пример использования
Было:
(document:surround "/std/base") (define (write-to-backend) (catch/message (lambda() (woo-write "/test" 'par1 (mypar1-id value) 'par2 (mypar2-id value) 'par3 (mypar3-id value) 'par4 (mypar4-id value) )))) (define (read-from-backend) (catch/message (lambda() (let ((data (woo-read-first "/test"))) (mypar1-id value (woo-get-option data 'par1)) (mypar2-id value (woo-get-option data 'par2)) (mypar3-id value (woo-get-option data 'par3)) (mypar4-id value (woo-get-option data 'par4)) )))) (gridbox columns "0;100" (spacer) (document:id mypar1-id (checkbox text (_ "my parameter - 1"))) (label text (_ "my parameter - 2:") align "right") (document:id mypar2-id (edit)) (label text (_ "m.p. - 3:") align "right") (document:id mypar3-id (edit)) (label text (_ "m.p. - 4:") align "right") (document:id mypar4-id (combobox enumref "/test/par4values")) (spacer) (gridbox columns "0;100" (button text (_ "Apply") (when clicked (write-to-backend))) (button text (_ "Reset") (when clicked (read-from-backend))) ) ) (document:root (when loaded (read-from-backend)))
Стало:
(document:surround "/std/base") (gridbox columns "0;100" (spacer) (checkbox text (_ "my parameter - 1") name "par1")) (label text (_ "my parameter - 2:") align "right") (edit name "par2") (label text (_ "m.p. - 3:") align "right") (edit name "par3") (label text (_ "m.p. - 4:") align "right") (combobox enumref "/test/par4values" name "par4") (spacer) (gridbox columns "0;100" (button text (_ "Apply") (when clicked (form-write/message "/test"))) (button text (_ "Reset") (when clicked (form-read/message "/test"))) ) ) (document:root (when loaded (read-from-backend)))
Неочевидное + TODO
- Если хочется заполянить параметр неинтерактивного виджета (например, label) из бакенда - можно, например, сделать скрытый виджет типа edit, заполнять его, а затем вручную переносить значение:
(label name "label2") (edit name "label" visibility #f) ... (form-read "/url") (form-element-apply "label2" (form-input-get-value "label"))
TODO: сделать бы специальный алиас для label, который бы при общении с бакендом трактовался как поле ввода (и имел атрибут value)...