3.5.2.1.19. Form

Компонент Form предназначен для совместного отображения и редактирования нескольких атрибутов сущности. Он представляет собой простой контейнер, схожий с GridLayout, и может содержать любое количество колонок с полями. Тип полей задаётся декларативно в XML-дескрипторе экрана, заголовки полей располагаются слева от поля. Главное отличие от GridLayout состоит в том, что Form позволяет привязать все вложенные поля к единому data container.

Form используется вместо FieldGroup по умолчанию в стандартных экранах редактирования сущности начиная с версии фреймворка 7.0.

gui Form 1

XML-имя компонента: form

Пример описания группы полей в XML-дескрипторе экрана:

<data>
    <instance id="orderDc" class="com.company.sales.entity.Order" view="order-edit">
        <loader/>
    </instance>
</data>
<layout>
    <form id="form" dataContainer="orderDc">
        <dateField property="date"/>
        <textField property="amount" description="Total amount"/>
        <pickerField property="customer"/>

        <field id="statusField" property="status"/>
    </form>
</layout>

В данном примере компонент form отображает атрибуты сущности Order, загруженной в контейнер данных orderDc. Вложенные в form элементы определяют визуальные компоненты, связанные с атрибутами сущности. Заголовки полей будут созданы автоматически на основе локализованных имен атрибутов сущности. Вложенные компоненты могут иметь любые собственные атрибуты, такие как description, показанный в примере.

Кроме конкретных визуальных компонентов, в форме можно объявлять обобщенные поля с помощью элемента field. Фреймворк выберет подходящий визуальный компонент на основе соответствующего полю атрибута сущности и имеющихся стратегий генерации компонентов. Элемент field может иметь общие атрибуты, такие как description, contextHelpText и т.д.

Для того, чтобы инжектировать некоторый вложенный компонент в контроллер экрана, у него должен быть указан атрибут id. Компонент будет инжектирован с его конкретным типом, например TextField. Если же инжектируется обобщенное поле, заданное элементом field, то его типом будет интерфейс Field, который является суперклассом всех визуальных компонентов, которые могут быть отображены в форме.

Компонент form поддерживает атрибуты colspan и rowspan. Эти атрибуты задают, сколько колонок и строк будет занимать данный вложенный компонент. Например, так можно растянуть поле Field 1 на две колонки:

<form>
    <column width="250px">
        <textField caption="Field 1" colspan="2" width="100%"/>
        <textField caption="Field 2"/>
    </column>
    <column width="250px">
        <textField caption="Field 3"/>
    </column>
</form>

В результате компоненты будут располагаться следующим образом:

gui Form 2

Аналогично, поле Field 1 можно растянуть на две строки:

<form>
    <column width="250px">
        <textField caption="Field 1" rowspan="2" height="100%"/>
    </column>
    <column width="250px">
        <textField caption="Field 2"/>
        <textField caption="Field 3"/>
    </column>
</form>

В результате компоненты будут располагаться следующим образом:

gui Form 3

Атрибуты form:

  • childrenCaptionWidth – позволяет задать фиксированную ширину заголовков всех вложенных колонок и их дочерних полей. Значение -1 устанавливает ширину по содержимому (AUTO), то есть по суммарной ширине вложенных компонентов.

  • childrenCaptionAlignment – определяет выравнивание заголовков дочерних компонентов во всех вложенных колонках. Принимает два значения: LEFT и RIGHT. Значение по умолчанию – LEFT. Применяется только в том случае, если атрибут captionPosition имеет значение LEFT.

  • captionPosition - задаёт положение заголовков полей: TOP или LEFT.

  • dataContainer - указывает data container для вложенных полей.

Элементы form:

  • column – необязательный элемент, позволяющий располагать поля в несколько колонок. Для этого вложенные элементы должны находиться не непосредственно внутри form, а внутри своего column. Например:

    <form id="form" dataContainer="orderDc">
        <column width="250px">
            <dateField property="date"/>
            <textField property="amount"/>
        </column>
        <column width="400px">
            <pickerField property="customer"/>
            <textArea property="info"/>
        </column>
    </form>

    В данном случае поля будут расположены в две колонки, причём в первой колонке все поля будут шириной 250px, а во второй - 400px.

    Атрибуты column:

    • id – необязательный идентификатор колонки, позволяющий ссылаться на нее в случае расширении экрана.

    • width – задает ширину полей данной колонки. По умолчанию ширина полей - 200px. В данном атрибуте ширина может быть задана как в пикселах, так и в процентах от общего размера колонки по горизонтали.

    • childrenCaptionWidth – позволяет задать фиксированную ширину заголовков всех дочерних полей. Значение -1 устанавливает ширину по содержимому (AUTO).

    • childrenCaptionAlignment – определяет выравнивание заголовков вложенных полей. Принимает два значения: LEFT и RIGHT. Значение по умолчанию – LEFT. Применяется только в том случае, если атрибут captionPosition имеет значение LEFT.

Методы интерфейса Form:

  • add() - позволяет добавлять одно или несколько полей в Form программно. В качестве параметра принимает экземпляр Component, также можно указать позицию поля, передав индексы колонки и строки с помощью атрибутов column и row. Кроме того, перегруженный метод принимает параметры rowspan и colspan.

    Компоненты, добавляемые программно, не привязываются к контейнеру данных Form автоматически, поэтому для связывания с данными нужно использовать метод setValueSource() добавляемого компонента.

    Например, если в XML задана форма с полем name:

    <data>
        <instance id="customerDc" class="com.company.demo.entity.Customer">
            <loader/>
        </instance>
    </data>
    <layout>
        <form id="form" dataContainer="customerDc">
            <column>
                <textField id="nameField" property="name"/>
            </column>
        </form>
    </layout>

    То можно добавить поле email программно в контроллере экрана следующим образом:

    @Inject
    private UiComponents uiComponents;
    @Inject
    private InstanceContainer<Customer> customerDc;
    @Inject
    private Form form;
    
    @Subscribe
    private void onInit(InitEvent event) {
        TextField<String> emailField = uiComponents.create(TextField.TYPE_STRING);
        emailField.setCaption("Email");
        emailField.setWidthFull();
        emailField.setValueSource(new ContainerValueSource<>(customerDc, "email"));
        form.add(emailField);
    }
  • setChildrenCaptionAlignment(CaptionAlignment alignment) – задаёт выравнивание заголовков дочерних компонентов во всех столбцах.

  • setChildrenCaptionAlignment(int column, CaptionAlignment alignment) – задаёт выравнивание заголовков дочерних компонентов для заданного столбца.