Ваадин 14 Формат текстового поля с тысячами разделителей при наборе текста - PullRequest
1 голос
/ 15 апреля 2020

Я использую Vaadin 14 + Java и хочу при вводе текста отображать текстовое поле с денежными значениями, включая разделители тысяч.

Разделители отображаются, если я загружаю объект в форму и текстовое поле, но всякий раз, когда я набираю новое значение или изменяю существующее, разделители тысяч не отображаются / не обновляются, пока я сохранил объект в базе данных и получил объект снова.

Я установил ValueChangeMode уже EAGER, но я полагаю, что конвертер применяется только при записи / загрузке из базы данных.

Как я могу вставить / обновить тысячу разделителей на лету при вводе?

Пример: когда я набираю "1000000", я хочу, чтобы текстовое поле обновлялось до "1.000" после того, как я набрал третий ноль и «10.000» после следующего, затем «100.000» и, наконец, «1.000.000» после шестого и последнего ноля.

Текстовое поле:

money_tf = new TextField("Money in €");
money_tf.setSuffixComponent(new Span("€"));
money_tf.addThemeVariants(TextFieldVariant.LUMO_ALIGN_RIGHT);
money_tf.setValueChangeMode(ValueChangeMode.EAGER);

Binder

binder = new BeanValidationBinder<>(MyClass.class);
binder.forField(money_tf).withConverter(new PriceConverter()).bind("money");

my PriceConverter:

private static class PriceConverter extends StringToBigDecimalConverter {

    public PriceConverter() {
        super(BigDecimal.ZERO, "Cannot convert to decimal value.");
    }

    @Override
    protected NumberFormat getFormat(Locale locale) {

        final NumberFormat format = super.getFormat(locale);
        format.setGroupingUsed(true); // enabled thousand separators
        if (format instanceof DecimalFormat) {
            // Always display currency with two decimals
            format.setMaximumFractionDigits(2); 
            format.setMinimumFractionDigits(2);
        }
        return format;
    }
}

1 Ответ

0 голосов
/ 16 апреля 2020

Я уже установил ValueChangeMode в EAGER, но я полагаю, что конвертер применяется только при записи / загрузке из базы данных.

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

Как я могу вставить / обновить тысячу разделителей на лету при наборе?

I понять ваш вопрос как, может ли преобразование быть сделано на стороне клиента, то есть в браузере. И ответ - да. Для простых случаев вы можете использовать textField.setPattern(regexp), где regexp - это String с шаблоном регулярного выражения. Для более сложных сценариев ios требуется, конечно, немного JavaScript logi c, но не беспокойтесь, в каталоге есть надстройка TextField Formatter , которая оборачивает библиотеку Cleave JS и дает вам хороший Java API для этой цели.

В качестве альтернативы вы можете использовать BigDecimalFieldField компонент каркаса, который также ограничивает ввод определенным числовым форматом. Тип значения этого поля не String, а BigDecimal.

...