5.5.2.1.14. FieldGroup

Компонент FieldGroup предназначен для совместного отображения и редактирования нескольких атрибутов сущностей.

gui fieldGroup

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

Компонент реализован для блоков Web Client и Desktop Client.

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

<dsContext>
    <datasource id="orderDs"
                class="com.sample.sales.entity.Order"
                view="order-with-customer">
    </datasource>
</dsContext>
<layout>
    <fieldGroup id="orderFieldGroup" datasource="orderDs" width="250px">
        <field property="date"/>
        <field property="customer"/>
        <field property="amount"/>
    </fieldGroup>
</layout>

Здесь в элементе dsContext определен источник данных datasource, который содержит один экземпляр сущности Order. Для компонента fieldGroup в атрибуте datasource указывается используемый источник данных, а в элементах field - какие атрибуты сущности, содержащейся в источнике данных, необходимо отобразить.

Элементы fieldGroup:

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

    <fieldGroup id="orderFieldGroup" datasource="orderDs" width="100%">
        <column width="250px">
            <field property="num"/>
            <field property="date"/>
            <field property="amount"/>
        </column>
        <column width="400px">
            <field property="customer"/>
            <field property="info"/>
        </column>
    </fieldGroup>

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

    Атрибуты column:

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

    • flex - число, задающее степень изменения общего размера данной колонки по горизонтали относительно других колонок при изменении ширины всего компонента fieldGroup. Например, можно задать одной колонке flex=1 а другой flex=3.

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

  • field - основной элемент компонента, описывает одно поле компонента.

    Собственные настраиваемые поля можно определить внутри элемента field:

    <fieldGroup>
        <field id="demo">
            <lookupField id="demoField" datasource="userDs" property="group"/>
        </field>
    </fieldGroup>

    Атрибуты элемента field:

    • id - обязательный атрибут в случае, если не определён атрибут property; в противном случае по умолчанию принимает то же значение, что и property. Атрибут id должен содержать произвольный уникальный идентификатор либо поля с заданным атрибутом property, либо программно определяемого поля. В последнем случае элемент field должен иметь также атрибут custom="true" (см. далее).

    • property - обязательный атрибут в случае, если не определён атрибут id; должен содержать название атрибута сущности, выводимого в поле, для связывания поля и данных.

    • caption − позволяет задать заголовок поля. Если не задан, будет отображено локализованное название атрибута сущности.

    • inputPrompt - если для компонента, представляющего данное поле, доступен атрибут inputPrompt, его значение можно установить напрямую для этого поля.

    • visible − позволяет скрыть поле вместе с заголовком.

    • datasource − позволяет задать для данного поля источник данных, отличный от заданного для всего компонента fieldGroup. Таким образом в группе полей могут отображаться атрибуты разных сущностей.

    • optionsDatasource − задает имя источника данных, используемого для формирования списка опций. Данный атрибут можно задать для поля, связанного со ссылочным атрибутом сущности. По умолчанию выбор связанной сущности производится через экран выбора, а если optionsDatasource указан, то связанную сущность можно выбирать из выпадающего списка опций. Фактически указание optionsDatasource приводит к тому, что вместо компонента PickerField в поле используется LookupPickerField.

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

    • custom - установка этого атрибута в true позволяет задать собственное представление поля, или говорит о том, что идентификатор поля не ссылается на атрибут сущности, и компонент, находящийся в поле, будет задан программно с помощью метода setComponent() компонента FieldGroup (см. ниже).

    • атрибут generator позволяет декларативно создавать собственные представления полей, указав имя метода, возвращающего компонент для данного поля:

      <fieldGroup datasource="productDs">
          <column width="250px">
              <field property="description" generator="generateDescriptionField"/>
          </column>
      </fieldGroup>
      public Component generateDescriptionField(Datasource datasource, String fieldId) {
          TextArea textArea = componentsFactory.createComponent(TextArea.class);
          textArea.setRows(5);
          textArea.setDatasource(datasource, fieldId);
          return textArea;
      }
    • linkScreen - позволяет указать идентификатор экрана, который будет открыт по нажатию на ссылку, включенную свойством link.

    • linkScreenOpenType - задает режим открытия экрана редактирования (THIS_TAB, NEW_TAB или DIALOG).

    • linkInvoke - позволяет заменить открытие окна на вызов метода контроллера.

    Следующие атрибуты элемента field можно применять в зависимости от типа атрибута сущности, отображаемого полем:

    • Если для текстового атрибута сущности задать значение атрибута mask, то в поле вместо компонента TextField будет использоваться компонент MaskedField с соответствующей маской. В этом случае можно также задать атрибут valueMode.

    • Если для текстового атрибута сущности задать значение атрибута rows, то в поле вместо компонента TextField будет использоваться компонент TextArea с соответствующим количеством строк. В этом случае можно также задать атрибут cols.

    • Для текстового атрибута сущности можно задать атрибут maxLength аналогично описанному для TextField.

    • Для атрибута сущности типа date или dateTime можно задать атрибуты dateFormat и resolution для параметризации находящегося в поле компонента DateField.

    • Для атрибута сущности типа time можно задать атрибут showSeconds для параметризации находящегося в поле компонента TimeField.

Атрибуты fieldGroup:

  • Атрибут border может принимать значение hidden или visible. По умолчанию - hidden. При установке в значение visible компонент fieldGroup выделяется рамкой. В веб-реализации компонента отображение рамки осуществляется добавлением CSS-класса cuba-fieldgroup-border.

  • captionAlignment определяет расположение заголовков относительно полей компонента FieldGroup. Принимает два значения: LEFT и TOP.

  • fieldFactoryBean: декларативные поля, объявленные в XML-дескрипторе, создаются с помощью интерфейса FieldGroupFieldFactory. Чтобы переопределить эту фабрику, используйте атрибут fieldFactoryBean с именем вашей реализации FieldGroupFieldFactory.

    Для элемента FieldGroup, полностью созданного программно, для этой цели используется метод setFieldFactory().

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

  • addField позволяет добавлять поля в FieldGroup на лету. В качестве параметра принимает экземпляр FieldConfig, также можно указать положение нового поля в FieldGroup с помощью параметров colIndex и rowIndex.

  • метод bind() необходимо применить к полю после вызова метода setDatasource(), чтобы вызвать создание компонентов поля.

  • createField() используется для создания элементов FieldGroup, реализующих интерфейс FieldConfig:

    fieldGroup.addField(fieldGroup.createField("newField"));
  • Метод getComponent() возвращает визуальный компонент, находящийся в поле с указанным идентификатором. Это может потребоваться для дополнительной параметризации компонента, недоступной через атрибуты XML-элемента field, описанные выше.

    Вместо явного вызова getFieldNN("id").getComponentNN() для получения ссылки на компонент поля в контроллере экрана можно использовать инжекцию. Для этого следует использовать аннотацию @Named с указанием идентификатора самого fieldGroup, и через точку - идентификатора поля.

    Например, следующим образом в поле выбора связанной сущности можно добавить действие открытия экземпляра и убрать действие очистки поля:

    <fieldGroup id="orderFieldGroup" datasource="orderDs">
        <field property="date"/>
        <field property="customer"/>
        <field property="amount"/>
    </fieldGroup>
    @Named("orderFieldGroup.customer")
    protected PickerField customerField;
    
    @Override
    public void init(Map<String, Object> params) {
        customerField.addOpenAction();
        customerField.removeAction(customerField.getAction(PickerField.ClearAction.NAME));
    }

    Для использования метода getComponent() или инжекции компонентов полей необходимо знать тип компонента, находящегося в поле. В следующей таблице приведено соответствие типов атрибутов сущностей и создаваемых для них компонентов:

    Тип атрибута сущности Дополнительные условия Тип компонента поля

    Связанная сущность

    Задан атрибут optionsDatasource

    LookupPickerField

    PickerField

    Перечисление (enum)

    LookupField

    string

    Задан атрибут mask

    MaskedField

    Задан атрибут rows

    TextArea

    TextField

    boolean

    CheckBox

    date, dateTime

    DateField

    time

    TimeField

    int, long, double, decimal

    Задан атрибут mask

    MaskedField

    TextField

    UUID

    MaskedField с hex-маской

  • removeField() позволяет удалять поля на лету по id.

  • Метод setComponent() задаёт собственное представление поля. Он может быть использован вместе с атрибутом custom="true" элемента field или с полем, созданным программно методом createField() (см. выше). При использовании с custom="true" необходимо вручную указать источник данных и свойство.

    Экземпляр FieldConfig можно получить с помощью методов getField() или getFieldNN(), и затем вызвать метод setComponent(), как показано в следующем примере:

    @Inject
    protected FieldGroup fieldGroup;
    @Inject
    protected ComponentsFactory componentsFactory;
    @Inject
    private Datasource<User> userDs;
    
    @Override
    public void init(Map<String, Object> params) {
        PasswordField passwordField = componentsFactory.createComponent(PasswordField.class);
        passwordField.setDatasource(userDs, "password");
        fieldGroup.getFieldNN("password").setComponent(passwordField);
    }