Alterator/Master Class: различия между версиями
Dkr (обсуждение | вклад) м (Новая страница: «Пошаговые примеры создания и использования различных виджетов Alterator для форм html, и, может ...») |
м (→Поле ввода: мелкая вычитка) |
||
(не показана 21 промежуточная версия 3 участников) | |||
Строка 1: | Строка 1: | ||
Пошаговые примеры создания и использования различных виджетов Alterator | == Пошаговые примеры == | ||
создания и использования различных виджетов Alterator | |||
для форм html, и, может быть, Qt версий. | для форм html, и, может быть, Qt версий. | ||
=== Текстовые поля и надписи === | |||
==== Поле ввода ==== | |||
Самым первым и самым простым применением может быть редактирование конфигурационного файла | |||
в формате Param: value | |||
[[ | Предположим, на экране мы хотим получить такую форму: | ||
[[Файл:Label_and_textinput.png]] | |||
В файле index.html нашего модуля пишем: | |||
<source lang="html4strict"> | |||
<span translate="_">Server name:</span> | |||
<input type="text" class="text" name="your_server" style="width:120px;"/> | |||
</source> | |||
Если строка '''Server name:''' определена в файле переводов, то она будет переведена. | |||
Ни изменять значение, ни читать его мы больше не будем. | |||
Поле ввода имеет имя ''your_server'', по которому можно обращаться к данному полю. | |||
Писать или читать его значение. | |||
Для того, чтобы записать значение '''127.0.0.1''' в это поле, в файле ajax.scm пишем: | |||
<source lang="lisp"> | |||
(form-update-value "your_server" "127.0.0.1") | |||
</source> | |||
Для того, чтобы прочитать значение из поля, в файле ajax.scm пишем | |||
<source lang="lisp"> | |||
(form-value "your_server" ) | |||
</source> | |||
В более сложном виде для передачи значения в backend по имени ''backend_name'' пишем, например, так: | |||
<source lang="lisp"> | |||
(catch/message | |||
(lambda() | |||
(woo "new" "/backend_name/" 'server (form-value "your_server") 'language (form-value "language")))) | |||
</source> | |||
В этом случае в backend передаются параметр server и значение form-value "your_server", | |||
а также language и form-value "language" для возможности правильного перевода. | |||
Более удобным является использование | |||
<source lang="lisp"> | |||
(form-value-list '("field1" "field2" "field3" "field4") | |||
</source> | |||
В этом случае передаются пары значений ''имя_поля'' ''значение_поля'' | |||
Каким образом мы получим значение нашего параметра в backend, в данной статье рассматриваться не будет. Предположим, что значение мы получили и нам осталось выполнить вызов | |||
<source lang="bash"> write_string_param param_name param_value</source> | |||
В нашем случае | |||
<source lang="bash"> write_string_param your_server your.domain.com</source> | |||
Теперь обратимся к backend-у, иначе он нам сам ничего отдавать не будет. | |||
В ajax.scm пишем функцию | |||
<source lang="lisp"> (form-update-value "your_server" (woo-read "/backend_name"))</source> | |||
Или более универсальный вариант | |||
<source lang="lisp"> (form-update-value-list (woo-read-first "/backend_name"))</source> | |||
В этом случае имена параметров должны иметь такие же имена, как и имена в формах. | |||
==== Именованные метки ==== | |||
В рассмотренном выше примере мы не могли изменить надпись возле поля ввода. | |||
Если нам такая функциональность нужна, то можно использовать | |||
''<span class="alterator-label" name="label_name"/>'' | |||
Разместим в файле index.html такой фрагмент | |||
<source lang="html4strict"> | |||
<span translate="_">Used base:</span> | |||
<u><span class="alterator-label" name="base_"/></u> | |||
<span translate="_">on host</span> | |||
<u><span class="alterator-label" name="host_"/></u> | |||
</source> | |||
В файле ajax.scm создадим функцию | |||
<source lang="lisp"> (define (constr_string) | |||
(let* ((data (woo-read "/backend_name/string" )) | |||
(cur_base (and (pair? data) (woo-get-option (car data) 'base))) | |||
(cur_host (and (pair? data) (woo-get-option (car data) 'host))) | |||
) | |||
(form-update-value "base_" cur_base) | |||
(form-update-value "host_" cur_host) )) | |||
</source> | |||
Которая установит нам нужные значения, при условии, что backend вернет нам пары значений. | |||
В результате у нас получилась такая строка | |||
[[Файл:Constructed_string.png]] | |||
=== Кнопки, радиокнопки и переключатели === | |||
==== Кнопки ==== | |||
==== Группа радиокнопок (radio) (переключатель с единственным выбором, '''"ИЛИ"''') ==== | |||
Чтобы наши радиокнопки переключались, они все должны иметь одинаковое имя. | |||
Разместим в форме набор радиокнопок. | |||
Все они имеют одинаковое имя (''use_src''), но разные ''"value"''. | |||
Рядом с кнопками разместим надписи, для выравнивания используем таблицу (в примере не показано). | |||
<source lang="html4strict"> | |||
<input type="radio" name="use_src" value="system" checked="#f"/> | |||
<input type="radio" name="use_src" value="local" checked="#t"/> | |||
<input type="radio" name="use_src" value="localldap" checked="#f"/> | |||
<input type="radio" name="use_src" value="remoteldap" checked="#f"/> | |||
</source> | |||
Одна из кнопок включена по умолчанию. | |||
Это выглядит так: | |||
[[Файл:Radiobutton_group.png]] | |||
Вызов ''(form-value "use_src")'' в ajax.scm вернет вам значение той радиокнопки, которая в данный момент выбрана, а ''(form-update-value "use_src" "system")'' установит радиокнопку с value="system" в включенное состояние. | |||
Нам остается только узнать, какую из радиокнопок включать у backend-а. | |||
<source lang="lisp"> | |||
(form-update-value "use_src" (woo-read "/backend" )) | |||
</source> | |||
Полезным бывает обработать изменение состояния группы переключателей без обращения к backend-у. | |||
Для этого в удобном нам месте напишем | |||
<source lang="lisp"> | |||
(form-bind "use_src" "change" set_src) | |||
</source> | |||
а в функции set_src - нужные действия. | |||
====Группа чекбоксов (checkbox). (Переключатель с множественным выбором '''"И"''').==== | |||
Есть два варианта реализации данного механизма: | |||
* Таблица класса '''alterator-checklistbox''' | |||
* Набор переключателей, формируемый вручную. | |||
Для создания таблицы в index.html пишем | |||
<source lang="html4strict"> | |||
<table class="alterator-checklistbox" name="checklistbox"/><br/> | |||
</source> | |||
Для заполнения таблицы в файле ajax.scm пишем функцию | |||
<source lang="lisp"> | |||
(form-update-enum "checklistbox" | |||
(woo-list "/backend/checklistbox" 'language (form-value "language"))) | |||
</source> | |||
Можно для чтения списка передать набор параметров, так же, как и '''language (form-value "language")'' | |||
При этом, в backend результат возвращается при помощи вызова | |||
<source lang="bash"> | |||
write_enum_item "$name" "$label" | |||
</source> | |||
Если "$label" не передается, то в качестве значения используется "$name" | |||
После того, как список заполнен, необходимо установить некоторые чекбоксы в состояние "включено". | |||
Для этого используется | |||
<source lang="lisp"> | |||
(form-update-value "checklistbox" '("список_имен_которые_нужно_включить")) | |||
</source> | |||
В результате, на экране, мы получим примерно такой набор: | |||
[[Файл:CheckBox_group.png]] | |||
Создание набора, формируемого вручную несколько сложнее, в плане дизайна и размещения элементов в форме. | |||
В файле index.html, в таблице, или как будет удобно, размещаем набор переключателей | |||
(Как разместить метки рядом с переключателем, надеюсь, понятно.) | |||
<source lang="html4strict"> | |||
<input type="checkbox" name="local" value="#t"/> | |||
<input type="checkbox" name="enable_tls" value="#t"/> | |||
<input type="checkbox" name="local_and_tls" value="#t"/> | |||
</source> | |||
Включаем (если нужно) состояние по умолчанию. | |||
В файле ajax.scm определяем функцию | |||
<source lang="lisp"> | |||
(define (read_ports) | |||
(form-update-value-list | |||
'("local" "enable_tls" "local_and_tls") (woo-read-first "/openldap/config"))) | |||
</source> | |||
которая установит нам все переключатели в нужное состояние, если backend нам правильно ответит. | |||
Правильный ответ backend-а определяется вызовом ''write_bool_param'' | |||
Например: | |||
<source lang="bash"> | |||
if [ "${url/ldap:\/\/localhost\/[[:space:]]ldaps:\/\/\//}" != "$url" ];then | |||
write_bool_param 'local_and_tls' 'yes' | |||
write_bool_param 'local' 'no' | |||
write_bool_param 'enable_tls' 'no' | |||
fi | |||
</source> | |||
В результате, на экране получится | |||
[[Файл:CheckBox_group_main.png]] | |||
=== Списки === | |||
==== Выпадающий список (select)==== | |||
Набор значений для выпадающего списка можно задать непосредственно в форме, | |||
равно как и получить от backend-а. | |||
В случае, если набор значений заранее не определен, то только из backend-а. | |||
Разместим в форме такой код: | |||
<source lang="html4strict"> | |||
<span translate="_">Shell:</span> | |||
<select name="loginshell"/> | |||
</source> | |||
Список пуст. Надпись будет переведена. | |||
В файле ''ajax.scm'' определим функцию заполнения списка значениями, получаемыми от backend-а. | |||
<source lang="lisp"> | |||
(form-update-enum "loginshell" (woo-list "/backend_name/shell")) | |||
</source> | |||
В backend-е пишем, к примеру, так: | |||
<source lang="bash"> | |||
#!/bin/sh | |||
po_domain="alterator-test" | |||
alterator_api_version=1 | |||
. alterator-sh-functions | |||
list_shell(){ | |||
write_enum_item "/sbin/nologin" | |||
while read sh; do | |||
[ -x "$sh" ] || continue | |||
write_enum_item "$sh" | |||
done </etc/shells | |||
} | |||
on_message() { | |||
case "$in_action" in | |||
read) | |||
;; | |||
write) | |||
;; | |||
list) | |||
case "$in__objects" in | |||
shell) | |||
list_shell | |||
;; | |||
esac | |||
;; | |||
esac | |||
} | |||
message_loop | |||
</source> | |||
Проверяем наш backend, | |||
# alterator-cmdline /backend_name/shell action list | |||
name:/sbin/nologin | |||
label:/sbin/nologin | |||
name:/bin/sh | |||
label:/bin/sh | |||
name:/bin/bash | |||
label:/bin/bash | |||
name:/bin/ash | |||
label:/bin/ash | |||
name:/bin/bsh | |||
label:/bin/bsh | |||
Проверяем работу формы. Видим [[Файл:Select.png]] | |||
=== Таблицы === | |||
=== Изображения === | |||
Для добавления изображения в форму достаточно добавить | |||
<source lang="html4strict"> | |||
<img class="alterator-img" name="image_name"/> | |||
</source> | |||
Каким-либо способом получить путь к файлу изображения относительно каталога | |||
{{path|/usr/share/alterator/design/images/}} | |||
и вызвать (form-update-value «image_name» «image_path») | |||
Пример использования есть в разделе '''Изменяющиеся иконки''' | |||
=== Динамические формы === | |||
==== Видимость элементов ==== | |||
Предположим, часть элементов формы имеет отношение к некоторому состоянию переключателя. | |||
Создадим форму следующего содержания | |||
<source lang="html4strict"> | |||
<html wf="none"> | |||
<body> | |||
<form method="POST"> | |||
<input type="checkbox" name="mode" checked="#t"/> | |||
<b><span translate="_">Show area</span></b> | |||
<hr/> | |||
<p>Этот текст будет отображаться постоянно</p> | |||
<div name="hidden_area" style="display:inline"> | |||
<b>После выключения опции текст в этой области будет скрыт</b> | |||
</div> | |||
<p>И этот текст будет отображаться постоянно</p> | |||
</form> | |||
</body> | |||
</html> | |||
</soutce> | |||
При старте формы область"hidden_area" будет видна. Теперь, после переключения режима, | |||
эта область должна скрыться. | |||
Для этого, в ajax.scm включим обработчик события | |||
<source lang="html4strict"> | |||
(form-bind "mode" "change" change_mode) | |||
</source> | |||
и напишем функцию ''change_mode'' | |||
<source lang="html4strict"> | |||
(define (change_mode) | |||
(form-update-visibility '("hidden_area") (form-value "mode"))) | |||
</source> | |||
Чекбокс включен: [[Файл:Din_area1.png]] | |||
Чекбокс выключен: [[Файл:Din_area2.png]] | |||
Естественно, вместо одной строки текста можно скрывать много всяких элементов формы. | |||
==== Доступность элементов ==== | |||
==== Изменяющиеся иконки ==== | |||
Наша задача отобразить некоторое состояние системы пикрограммой. | |||
Состояние системы можно получить от backend-а или от элементов управления. | |||
Приведем минимальный пример index.html | |||
<source lang="html4strict"> | |||
<html wf="none"> | |||
<body> | |||
<form method="POST"> | |||
<input type="radio" name="set_status" value="locked" checked="#t"/> | |||
<span translate="_">Lock this</span><br/> | |||
<input type="radio" name="set_status" value="unlocked" checked="#f"/> | |||
<span translate="_">UnLock this</span><br/> | |||
<img class="alterator-img" name="status"/> | |||
</form> | |||
</body> | |||
</html> | |||
</source> | |||
Изменение состояния радиокнопок должно отобразиться иконкой, но ее src не указан. | |||
В файле ajax.scm пишем | |||
<source lang="lisp"> | |||
(define-module (ui test ajax) | |||
:use-module (alterator ajax) | |||
:use-module (alterator str) ;; Нужно для работы string-append | |||
:use-module (alterator woo) | |||
:export (init)) | |||
(define (set_status) | |||
(form-update-value "status" (string-append "test/" | |||
(car (string-cut-repeated (or (form-value "set_status") "unlocked") #\,)) | |||
".png"))) | |||
(define (init) | |||
(set_status) | |||
(form-bind "set_status" "change" set_status) | |||
) | |||
</source> | |||
Функция | |||
(string-append "test/" (car (string-cut-repeated (or (form-value "set_status") "unlocked") #\,)) ".png") | |||
соберет нам строку вида ''"test/locked.png"'' и передаст ее в качестве аргумента для '''form-update-value''' | |||
И вот результат | |||
[[Файл:Locked.png]] <--> [[Файл:Unlocked.png]] | |||
== См. также == | |||
* <DPL> | |||
namespace = | |||
titlematch = Alterator | |||
nottitlematch = Alterator/% | |||
mode = inline | |||
inlinetext= •  | |||
</DPL> | |||
* <DPL> | |||
namespace = | |||
titlematch = Scheme/Tutorial | |||
mode = inline | |||
inlinetext= •  | |||
</DPL> | |||
{{Category navigation|title=Alterator|category=Alterator|sortkey=*}} |
Текущая версия от 15:44, 17 марта 2015
Пошаговые примеры
создания и использования различных виджетов Alterator для форм html, и, может быть, Qt версий.
Текстовые поля и надписи
Поле ввода
Самым первым и самым простым применением может быть редактирование конфигурационного файла в формате Param: value
Предположим, на экране мы хотим получить такую форму:
В файле index.html нашего модуля пишем:
<span translate="_">Server name:</span>
<input type="text" class="text" name="your_server" style="width:120px;"/>
Если строка Server name: определена в файле переводов, то она будет переведена. Ни изменять значение, ни читать его мы больше не будем.
Поле ввода имеет имя your_server, по которому можно обращаться к данному полю. Писать или читать его значение. Для того, чтобы записать значение 127.0.0.1 в это поле, в файле ajax.scm пишем:
(form-update-value "your_server" "127.0.0.1")
Для того, чтобы прочитать значение из поля, в файле ajax.scm пишем
(form-value "your_server" )
В более сложном виде для передачи значения в backend по имени backend_name пишем, например, так:
(catch/message
(lambda()
(woo "new" "/backend_name/" 'server (form-value "your_server") 'language (form-value "language"))))
В этом случае в backend передаются параметр server и значение form-value "your_server", а также language и form-value "language" для возможности правильного перевода.
Более удобным является использование
(form-value-list '("field1" "field2" "field3" "field4")
В этом случае передаются пары значений имя_поля значение_поля
Каким образом мы получим значение нашего параметра в backend, в данной статье рассматриваться не будет. Предположим, что значение мы получили и нам осталось выполнить вызов
write_string_param param_name param_value
В нашем случае
write_string_param your_server your.domain.com
Теперь обратимся к backend-у, иначе он нам сам ничего отдавать не будет. В ajax.scm пишем функцию
(form-update-value "your_server" (woo-read "/backend_name"))
Или более универсальный вариант
(form-update-value-list (woo-read-first "/backend_name"))
В этом случае имена параметров должны иметь такие же имена, как и имена в формах.
Именованные метки
В рассмотренном выше примере мы не могли изменить надпись возле поля ввода. Если нам такая функциональность нужна, то можно использовать
Разместим в файле index.html такой фрагмент
<span translate="_">Used base:</span>
<u><span class="alterator-label" name="base_"/></u>
<span translate="_">on host</span>
<u><span class="alterator-label" name="host_"/></u>
В файле ajax.scm создадим функцию
(define (constr_string)
(let* ((data (woo-read "/backend_name/string" ))
(cur_base (and (pair? data) (woo-get-option (car data) 'base)))
(cur_host (and (pair? data) (woo-get-option (car data) 'host)))
)
(form-update-value "base_" cur_base)
(form-update-value "host_" cur_host) ))
Которая установит нам нужные значения, при условии, что backend вернет нам пары значений.
В результате у нас получилась такая строка
Кнопки, радиокнопки и переключатели
Кнопки
Группа радиокнопок (radio) (переключатель с единственным выбором, "ИЛИ")
Чтобы наши радиокнопки переключались, они все должны иметь одинаковое имя. Разместим в форме набор радиокнопок. Все они имеют одинаковое имя (use_src), но разные "value". Рядом с кнопками разместим надписи, для выравнивания используем таблицу (в примере не показано).
<input type="radio" name="use_src" value="system" checked="#f"/>
<input type="radio" name="use_src" value="local" checked="#t"/>
<input type="radio" name="use_src" value="localldap" checked="#f"/>
<input type="radio" name="use_src" value="remoteldap" checked="#f"/>
Одна из кнопок включена по умолчанию. Это выглядит так:
Вызов (form-value "use_src") в ajax.scm вернет вам значение той радиокнопки, которая в данный момент выбрана, а (form-update-value "use_src" "system") установит радиокнопку с value="system" в включенное состояние. Нам остается только узнать, какую из радиокнопок включать у backend-а.
(form-update-value "use_src" (woo-read "/backend" ))
Полезным бывает обработать изменение состояния группы переключателей без обращения к backend-у. Для этого в удобном нам месте напишем
(form-bind "use_src" "change" set_src)
а в функции set_src - нужные действия.
Группа чекбоксов (checkbox). (Переключатель с множественным выбором "И").
Есть два варианта реализации данного механизма:
- Таблица класса alterator-checklistbox
- Набор переключателей, формируемый вручную.
Для создания таблицы в index.html пишем
<table class="alterator-checklistbox" name="checklistbox"/><br/>
Для заполнения таблицы в файле ajax.scm пишем функцию
(form-update-enum "checklistbox"
(woo-list "/backend/checklistbox" 'language (form-value "language")))
Можно для чтения списка передать набор параметров, так же, как и 'language (form-value "language") При этом, в backend результат возвращается при помощи вызова
write_enum_item "$name" "$label"
Если "$label" не передается, то в качестве значения используется "$name"
После того, как список заполнен, необходимо установить некоторые чекбоксы в состояние "включено".
Для этого используется
(form-update-value "checklistbox" '("список_имен_которые_нужно_включить"))
В результате, на экране, мы получим примерно такой набор:
Создание набора, формируемого вручную несколько сложнее, в плане дизайна и размещения элементов в форме. В файле index.html, в таблице, или как будет удобно, размещаем набор переключателей (Как разместить метки рядом с переключателем, надеюсь, понятно.)
<input type="checkbox" name="local" value="#t"/>
<input type="checkbox" name="enable_tls" value="#t"/>
<input type="checkbox" name="local_and_tls" value="#t"/>
Включаем (если нужно) состояние по умолчанию.
В файле ajax.scm определяем функцию
(define (read_ports)
(form-update-value-list
'("local" "enable_tls" "local_and_tls") (woo-read-first "/openldap/config")))
которая установит нам все переключатели в нужное состояние, если backend нам правильно ответит. Правильный ответ backend-а определяется вызовом write_bool_param Например:
if [ "${url/ldap:\/\/localhost\/[[:space:]]ldaps:\/\/\//}" != "$url" ];then
write_bool_param 'local_and_tls' 'yes'
write_bool_param 'local' 'no'
write_bool_param 'enable_tls' 'no'
fi
В результате, на экране получится
Списки
Выпадающий список (select)
Набор значений для выпадающего списка можно задать непосредственно в форме, равно как и получить от backend-а. В случае, если набор значений заранее не определен, то только из backend-а. Разместим в форме такой код:
<span translate="_">Shell:</span>
<select name="loginshell"/>
Список пуст. Надпись будет переведена. В файле ajax.scm определим функцию заполнения списка значениями, получаемыми от backend-а.
(form-update-enum "loginshell" (woo-list "/backend_name/shell"))
В backend-е пишем, к примеру, так:
#!/bin/sh
po_domain="alterator-test"
alterator_api_version=1
. alterator-sh-functions
list_shell(){
write_enum_item "/sbin/nologin"
while read sh; do
[ -x "$sh" ] || continue
write_enum_item "$sh"
done </etc/shells
}
on_message() {
case "$in_action" in
read)
;;
write)
;;
list)
case "$in__objects" in
shell)
list_shell
;;
esac
;;
esac
}
message_loop
Проверяем наш backend,
# alterator-cmdline /backend_name/shell action list name:/sbin/nologin label:/sbin/nologin name:/bin/sh label:/bin/sh name:/bin/bash label:/bin/bash name:/bin/ash label:/bin/ash name:/bin/bsh label:/bin/bsh
Таблицы
Изображения
Для добавления изображения в форму достаточно добавить
<img class="alterator-img" name="image_name"/>
Каким-либо способом получить путь к файлу изображения относительно каталога /usr/share/alterator/design/images/
и вызвать (form-update-value «image_name» «image_path») Пример использования есть в разделе Изменяющиеся иконки
Динамические формы
Видимость элементов
Предположим, часть элементов формы имеет отношение к некоторому состоянию переключателя. Создадим форму следующего содержания
<html wf="none">
<body>
<form method="POST">
<input type="checkbox" name="mode" checked="#t"/>
<b><span translate="_">Show area</span></b>
<hr/>
<p>Этот текст будет отображаться постоянно</p>
<div name="hidden_area" style="display:inline">
<b>После выключения опции текст в этой области будет скрыт</b>
</div>
<p>И этот текст будет отображаться постоянно</p>
</form>
</body>
</html>
</soutce>
При старте формы область"hidden_area" будет видна. Теперь, после переключения режима,
эта область должна скрыться.
Для этого, в ajax.scm включим обработчик события
<source lang="html4strict">
(form-bind "mode" "change" change_mode)
и напишем функцию change_mode
(define (change_mode)
(form-update-visibility '("hidden_area") (form-value "mode")))
Естественно, вместо одной строки текста можно скрывать много всяких элементов формы.
Доступность элементов
Изменяющиеся иконки
Наша задача отобразить некоторое состояние системы пикрограммой. Состояние системы можно получить от backend-а или от элементов управления.
Приведем минимальный пример index.html
<html wf="none">
<body>
<form method="POST">
<input type="radio" name="set_status" value="locked" checked="#t"/>
<span translate="_">Lock this</span><br/>
<input type="radio" name="set_status" value="unlocked" checked="#f"/>
<span translate="_">UnLock this</span><br/>
<img class="alterator-img" name="status"/>
</form>
</body>
</html>
Изменение состояния радиокнопок должно отобразиться иконкой, но ее src не указан. В файле ajax.scm пишем
(define-module (ui test ajax)
:use-module (alterator ajax)
:use-module (alterator str) ;; Нужно для работы string-append
:use-module (alterator woo)
:export (init))
(define (set_status)
(form-update-value "status" (string-append "test/"
(car (string-cut-repeated (or (form-value "set_status") "unlocked") #\,))
".png")))
(define (init)
(set_status)
(form-bind "set_status" "change" set_status)
)
Функция (string-append "test/" (car (string-cut-repeated (or (form-value "set_status") "unlocked") #\,)) ".png") соберет нам строку вида "test/locked.png" и передаст ее в качестве аргумента для form-update-value