5.5.2.1.42. TextField

Поле для редактирования текста. Может использоваться как для работы с атрибутами сущностей, так и для ввода и отображения произвольной текстовой информации.

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

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

  • Пример текстового поля с заголовком, взятым из пакета локализованных сообщений:

    <textField id="nameField" caption="msg://name"/>

    На рисунке ниже показан вид простого текстового поля.

    gui textField data
  • В веб-клиенте с темой, основанной на Halo, к компоненту TextField можно применить предопределенные стили. Стили задаются в XML-дексрипторе или контроллере экрана с помощью атрибута stylename:

    <textField id="textField"
               stylename="borderless"/>

    Чтобы применить стиль программно, выберите одну из констант класса HaloTheme с префиксом компонента TEXTFIELD_:

    textField.setStyleName(HaloTheme.TEXTFIELD_INLINE_ICON);

    Стили компонента TextField:

    • align-center - выравние текста по центру поля.

    • align-right - выравнивание текста по правому краю поля.

    • borderless - удаляет рамку и фон текстового поля.

    • inline-icon - расположение значка внутри текстового поля.

    Компонент TextField поддерживает автоматическую конвертацию регистра. Атрибут caseConvertion может принимать следующие значения:

    • UPPER - верхний регистр,

    • LOWER - нижний регистр,

    • NONE - конвертация отключена (значение по умолчанию). Используйте это значение для поддержки клавиатурного ввода с использованием IME, к примеру, для японского, корейского и китайского языков.

  • Для создания текстового поля, связанного с данными, необходимо использовать атрибуты datasource и property.

    <dsContext>
        <datasource id="customerDs" class="com.sample.sales.entity.Customer" view="_local"/>
    </dsContext>
    <layout>
        <textField datasource="customerDs" property="name" caption="msg://name"/>

    Как видно из примера, в экране описывается источник данных customerDs для некоторой сущности Покупатель (Customer), имеющей атрибут name. В компоненте текстового поля в атрибуте datasource указывается ссылка на источник данных, а в атрибуте property − название атрибута сущности, значение которого должно быть отображено в текстовом поле.

  • Если поле не связано с атрибутом сущности (то есть не указан источник данных и название атрибута), то можно указать тип данных с помощью атрибута datatype. Тип данных используется для форматирования значения поля. В качестве значения атрибута может быть указано любое имя типа данных, зарегистрированного в метаданных приложения - см. Datatype. Как правило, в TextField используются следующие типы данных:

    • decimal

    • double

    • int

    • long

      В качестве примера рассмотрим текстовое поле с типом данных Integer.

      <textField id="integerField" datatype="int" caption="msg://integerFieldName"/>

      Если в таком поле ввести значение, которое невозможно интерпретировать как целое число, то при потере фокуса полем будет выведено сообщение об ошибке и значение поля вернется на предыдущее.

  • Текстовому полю может быть назначен валидатор - класс, реализующий интерфейс Field.Validator. Валидатор позволяет дополнительно к datatype ограничить вводимую пользователем информацию. Например, для создания поля ввода положительных целых чисел нужно создать класс валидатора:

    public class PositiveIntegerValidator implements Field.Validator {
        @Override
        public void validate(Object value) throws ValidationException {
            Integer i = (Integer) value;
            if (i <= 0)
                throw new ValidationException("Value must be positive");
        }
    }

    и задать его для текстового поля с типом данных int в элементе validator:

    <textField id="integerField" datatype="int">
        <validator class="com.sample.sales.gui.PositiveIntegerValidator"/>
    </textField>

    В отличие от проверки вводимой строки на соответствие типу данных, валидация срабатывает не сразу при потере полем фокуса, а только при вызове у поля метода validate(). Это означает, что поле (и связанный с ним атрибут сущности) может некоторое время содержать значение, не удовлетворяющее условиям валидации (в приведенном примере неположительное число). Это не является проблемой, так как обычно поля редактирования с валидацией располагаются в экране редактирования, а он автоматически вызывает валидацию всех своих полей перед коммитом. Если же поле находится не в экране редактирования, то необходимо вызывать метод validate() поля в контроллере явно.

  • Компонент TextField поддерживает слушатель TextChangeListener, определённый в родительском интерфейсе TextInputField. События изменения текста обрабатываются асинхронно после ввода, не блокируя сам ввод.

    textField.addTextChangeListener(event -> {
        int length = event.getText().length();
        textFieldLabel.setValue(length + " of " + textField.getMaxLength());
    });
    textField.setTextChangeEventMode(TextInputField.TextChangeEventMode.LAZY);
    gui textfield 2
  • Параметром TextChangeEventMode задаётся режим передачи изменений на сервер для вызова события на серверной стороне. В платформе реализовано 3 режима передачи:

    • LAZY (по умолчанию) - событие вызывается во время паузы в наборе текста. Продолжительность паузы можно задать с помощью метода setInputEventTimeout(). Событие изменения текста обрабатывается принудительно перед возможным событием ValueChangeEvent, даже если пользователь не выдержал паузу в наборе текста.

    • TIMEOUT - событие вызывается после периода ожидания. В случае ввода нескольких изменений за один период, на сервер отсылается событие со всеми изменениями, включая последнее. Продолжительность периода ожидания можно задать с помощью метода setInputEventTimeout().

      В случае, если ValueChangeEvent может случиться до истечения периода ожидания, событие TextChangeEvent обрабатывается до его истечения, при условии, что набранный текст был изменён после предыдущего TextChangeEvent.

    • EAGER - событие вызывается незамедлительно после каждого изменения текста, то есть после каждого нажатия клавиш. Запросы отправляются по отдельности и обрабатываются последовательно один за другим. Тем не менее, асинхронная передача событий изменения на сервер позволяет не блокировать дальнейший ввод текста.

  • EnterPressListener позволяет указать действие, которое должно быть выполнено по нажатию клавиши Enter:

    textField.addEnterPressListener(e -> showNotification("Enter pressed"));
  • ValueChangeListener позволяет обрабатывать изменения значения в текстовом поле, когда пользователь уже закончил ввод, т.е. после нажатия клавиши Enter или при потере компонентом фокуса. В слушатель передается объект события типа ValueChangeEvent, который имеет следующие методы:

    • getPrevValue() возвращает значение компонента до изменения.

    • getValue() возвращает текущее значение компонента.

      textField.addValueChangeListener(e ->
              showNotification("Before: " + e.getPrevValue() + ". After: " + e.getValue()));
  • Если текстовое поле связано с атрибутом сущности (через datasource и property), и если для атрибута сущности в JPA-аннотации @Column указан параметр length, то TextField будет соответственно ограничивать максимальную длину вводимого текста.

    Если текстовое поле не связано с атрибутом, либо для него не определено значение length, либо это значение нужно переопределить, то для ограничения максимальной длины вводимого текста можно использовать атрибут maxLength. Значение "-1" означает отсутствие ограничения. Например:

    <textField id="shortTextField" maxLength="10"/>
  • По умолчанию текстовое поле отсекает пробелы в начале и конце введенной строки. То есть если пользователь ввел строку " aaa bbb " то значением поля, возвращаемым методом getValue() и сохраняемым в связанный атрибут сущности, будет строка "aaa bbb". Для того, чтобы отключить отсечение пробелов, используйте атрибут trim со значением false.

    Следует иметь в виду, что отсечение пробелов работает только при вводе нового значения. Если в значении связанного атрибута уже присутствуют пробелы, они будут отображаться, пока пользователь не изменит значение поля.

  • Текстовое поле всегда вместо введенной пустой строки возвращает null. Соответственно, при включенном атрибуте trim строка, состоящая из одних пробелов также превратится в null.

  • Метод setCursorPosition() используется для установки позиции курсора в указанный индекс (начинается с 0). После вызова метода поле принимает фокус ввода.