Статьи

Динамичные формы, мир JSF давно ждал

В новой версии PrimeFaces Extensions 0.5.0 появился новый компонент DynaForm. Обычно мы можем построить форму довольно просто с помощью h: panelGrid или p: panelGrid, если известно количество строк / столбцов, позиции элементов и т. Д. Это верно для статических форм. Но невозможно использовать h: panelGrid oder p: panelGrid, если форма описывается динамически во время выполнения. Например, если определение всей формы помещено в базу данных или файл XML. DynaForm позволяет создавать динамические формы с метками, входами, выборками и любыми другими элементами по модели. Там нет ограничений. Изучите все его возможности в витрине . Давайте покажем, как построить простую динамическую форму.

Основные шаги:
Создать экземпляр модели: DynaFormModel model = new DynaFormModel ();
Добавить строку в обычную сетку: DynaFormRow row = model.createRegularRow ();
Добавить метку: DynaFormLabel label = row.addLabel (значение, colspan, rowspan);
Добавить редактируемый элемент управления: DynaFormControl control = row.addControl (data, type, colspan, rowspan);
Установить связь между меткой и элементом управления (необязательно): label.setForControl (control);

Повторите четыре последних шага столько раз, сколько необходимо. Как это может выглядеть с точки зрения пользовательского интерфейса? Снимок экрана после неудачной проверки формы:

Основным тегом является pe: dynaForm. Дочерний тег pe: dynaFormControl соответствует созданному в элементах управления Java атрибуту «type». Обычно это отношение «один ко многим». Код XHTML / Java (контроллерный компонент и модель) в приведенной выше динамической форме приведен ниже.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<h:panelGroup id="dynaFormGroup">
    <p:messages id="messages" showSummary="true"/>
 
    <pe:dynaForm id="dynaForm" value="#{dynaFormController.model}" var="data">
        <pe:dynaFormControl type="input" for="txt">
            <p:inputText id="txt" value="#{data.value}" required="#{data.required}"/>
        </pe:dynaFormControl>
        <pe:dynaFormControl type="calendar" for="cal" styleClass="calendar">
            <p:calendar id="cal" value="#{data.value}" required="#{data.required}" showOn="button"/>
        </pe:dynaFormControl>
        <pe:dynaFormControl type="select" for="sel" styleClass="select">
            <p:selectOneMenu id="sel" value="#{data.value}" required="#{data.required}">
                <f:selectItems value="#{dynaFormController.languages}"/>
            </p:selectOneMenu>
        </pe:dynaFormControl>
        <pe:dynaFormControl type="textarea" for="tarea">
            <p:inputTextarea id="tarea" value="#{data.value}" required="#{data.required}" autoResize="false"/>
        </pe:dynaFormControl>
        <pe:dynaFormControl type="rating" for="rat">
            <p:rating id="rat" value="#{data.value}" required="#{data.required}"/>
        </pe:dynaFormControl>
 
        <f:facet name="buttonBar">
            <p:commandButton value="Submit" action="#{dynaFormController.submitForm}"
                             process="dynaForm" update="_mainForm_dynaFormGroup"/>
            <p:commandButton type="reset" value="Reset" style="margin-left: 5px;"/>
        </f:facet>
    </pe:dynaForm>
</h:panelGroup>
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
@ManagedBean
@ViewScoped
public class DynaFormController implements Serializable {
 
   private DynaFormModel model;
 
   private static List<SelectItem> LANGUAGES = new ArrayList<SelectItem>();
 
   public DynaFormController() {
      model = new DynaFormModel();
 
      // add rows, labels and editable controls
      // set relationship between label and editable controls to support outputLabel with "for" attribute
 
      // 1. row
      DynaFormRow row = model.createRegularRow();
 
      DynaFormLabel label11 = row.addLabel("Author", 1, 1);
      DynaFormControl control12 = row.addControl(new BookProperty("Author", true), "input", 1, 1);
      label11.setForControl(control12);
 
      DynaFormLabel label13 = row.addLabel("ISBN", 1, 1);
      DynaFormControl control14 = row.addControl(new BookProperty("ISBN", true), "input", 1, 1);
      label13.setForControl(control14);
 
      // 2. row
      row = model.createRegularRow();
 
      DynaFormLabel label21 = row.addLabel("Title", 1, 1);
      DynaFormControl control22 = row.addControl(new BookProperty("Title", false), "input", 3, 1);
      label21.setForControl(control22);
 
      // 3. row
      row = model.createRegularRow();
 
      DynaFormLabel label31 = row.addLabel("Publisher", 1, 1);
      DynaFormControl control32 = row.addControl(new BookProperty("Publisher", false), "input", 1, 1);
      label31.setForControl(control32);
 
      DynaFormLabel label33 = row.addLabel("Published on", 1, 1);
      DynaFormControl control34 = row.addControl(new BookProperty("Published on", false), "calendar", 1, 1);
      label33.setForControl(control34);
 
      // 4. row
      row = model.createRegularRow();
 
      DynaFormLabel label41 = row.addLabel("Language", 1, 1);
      DynaFormControl control42 = row.addControl(new BookProperty("Language", false), "select", 1, 1);
      label41.setForControl(control42);
 
      DynaFormLabel label43 = row.addLabel("Description", 1, 2);
      DynaFormControl control44 = row.addControl(new BookProperty("Description", false), "textarea", 1, 2);
      label43.setForControl(control44);
 
      // 5. row
      row = model.createRegularRow();
 
      DynaFormLabel label51 = row.addLabel("Rating", 1, 1);
      DynaFormControl control52 = row.addControl(new BookProperty("Rating", 3, true), "rating", 1, 1);
      label51.setForControl(control52);
    }
 
    public DynaFormModel getModel() {
        return model;
    }
 
    public String submitForm() {
        ... // do something
    }
 
    public List<SelectItem> getLanguages() {
        if (LANGUAGES.isEmpty()) {
            LANGUAGES.add(new SelectItem("en", "English"));
            LANGUAGES.add(new SelectItem("de", "German"));
            LANGUAGES.add(new SelectItem("ru", "Russian"));
            LANGUAGES.add(new SelectItem("tr", "Turkish"));
        }
 
        return LANGUAGES;
    }
}
 
public class BookProperty implements Serializable {
 
    private String name;
    private Object value;
    private boolean required;
 
    public BookProperty(String name, boolean required) {
        this.name = name;
        this.required = required;
    }
 
    public BookProperty(String name, Object value, boolean required) {
        this.name = name;
        this.value = value;
        this.required = required;
    }
 
    // getter // setter
}
Вы видите, что одной из важных функций является встроенная поддержка меток. DynaForm отображает метки автоматически — не нужно писать p: outputLabel. Еще одна функция — флаг автоматической отправки. Это позволяет передавать параметры формы в URL, создавать форму при загрузке страницы и автоматически отправлять ее. Дополнительные возможности: расширяемая расширенная область просмотра (сетка), сохранение состояния открытия / закрытия, клиентский API виджета, различные аспекты. На следующих снимках экрана показано, как создавать динамические формы с метками над полями и различными элементами, такими как разделитель PrimeFaces. Две формы в этом примере переключаются нажатием на ссылку «Переключить модель». Обратите внимание, код XHTML с pe: dynaForm остается прежним, изменяется только модель Java.

Изучите соответствующий код в сценарии использования еще одной формы .

Справка: Динамические формы, мир JSF долго ждали от нашего партнера по JCG Олега Вараксина в блоге Мысли о разработке программного обеспечения .