Java spring thymeleaf form

Руководство: Thymeleaf + Spring. Часть 2

Первое, что покажет наша страница /WEB-INF/templates/seedstartermng.html, — это список с начальными стартовыми данными, которые в данный момент сохранены. Для этого нам потребуются некоторые внешние сообщения, а также некоторая работа выражений для атрибутов модели. Как это:

List of Seed Starters

Date Planted Covered Type Features Rows
13/01/2011 yes Wireframe Electric Heating, Turf
1 Thymus Thymi 12

Здесь много чего посмотреть. Давайте посмотрим на каждый фрагмент отдельно.

Прежде всего, этот раздел будет отображаться только при наличии seed стартеров. Мы достигаем этого с помощью атрибута th:never и функции #lists.isEmpty(. ).

Обратите внимание, что все служебные объекты, такие как #lists, доступны в выражениях Spring EL так же, как и в выражениях OGNL в стандартном диалекте.

Следующее, что нужно увидеть, это много интернационализированных (экстернализованных) текстов, таких как:

«>List of Seed Starters

   Date Planted Covered Type Features Rows . 

Это приложение Spring MVC, мы уже определили bean-компонент MessageSource в нашей конфигурации Spring (объекты MessageSource являются стандартным способом управления внешними текстами в Spring MVC):

@Bean public ResourceBundleMessageSource messageSource()

… и это свойство basename указывает, что в нашем пути к классам у нас будут файлы, такие как Messages_es.properties или Messages_en.properties. Давайте посмотрим на испанскую версию:

title.list=Lista de semilleros date.format=dd/MM/yyyy bool.true=sí bool.false=no seedstarter.datePlanted=Fecha de plantación seedstarter.covered=Cubierto seedstarter.type=Tipo seedstarter.features=Características seedstarter.rows=Filas seedstarter.type.WOOD=Madera seedstarter.type.PLASTIC=Plástico seedstarter.feature.SEEDSTARTER_SPECIFIC_SUBSTRATE=Sustrato específico para semilleros seedstarter.feature.FERTILIZER=Fertilizante seedstarter.feature.PH_CORRECTOR=Corrector de PH 

В первом столбце таблицы мы покажем дату, когда был подготовлен стартер. Но мы покажем, что он отформатирован так, как мы определили в нашем DateFormatter. Для этого мы будем использовать синтаксис двойной скобки ($>), который будет автоматически применять сервис преобразования Spring, в том числе DateFormatter, который мы зарегистрировали при настройке.

Далее показано, покрыт ли начальный контейнер seed starter или нет, путем преобразования значения свойства булевого покрытого бина в интернационализированное «да» или «нет» с буквальным выражением подстановки:

Теперь мы должны показать тип начального seed starter контейнера. Тип представляет собой java-перечисление с двумя значениями (WOOD и PLASTIC), и поэтому мы определили два свойства в нашем файле Messages с именами seedstarter.type.WOOD и seedstarter.type.PLASTIC.

Но чтобы получить интернационализированные имена типов, нам нужно добавить seedstarter.type. префикс к значению enum с помощью выражения, результат которого мы затем будем использовать в качестве ключа сообщения:

Самая сложная часть этого списка — колонка фич. В нем мы хотим отобразить все функции нашего контейнера, которые представлены в виде массива перечислений Feature, разделенных запятыми. Как «Электрическое отопление, газон».

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

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

Для этого мы создаем следующий код:

Последний столбец нашего списка на самом деле будет довольно простым. Даже если у него есть вложенная таблица для отображения содержимого каждой строки в контейнере:

6 Создание Форм

6.1 Обработка командного объекта

Объект команды — это имя, которое Spring MVC дает бинам поддержки форм, то есть объектам, которые моделируют поля формы и предоставляют методы получения и установки, которые будут использоваться платформой для установления и получения значений, введенных пользователем в браузере.

Thymeleaf требует, чтобы вы указали объект команды, используя атрибут th:object в вашем теге :

Это согласуется с другим использованием th:object, но на самом деле этот конкретный сценарий добавляет некоторые ограничения для правильной интеграции с инфраструктурой Spring MVC:

  • Значения атрибутов th:object в тегах формы должны быть выражениями переменных ($ ), указывающими только имя атрибута модели, без навигации по свойствам. Это означает, что выражение типа $ является допустимым, но $ не будет.
  • Внутри тега другой атрибут th:object не может быть указан. Это согласуется с тем фактом, что HTML-формы не могут быть вложенными.

6.2 Inputs

Давайте теперь посмотрим, как добавить input в нашу форму:

Как видите, мы вводим новый атрибут: th:field. Это очень важная функция для интеграции Spring MVC, поскольку она выполняет всю тяжелую работу по связыванию вашего input со свойством в компоненте поддержки формы. Вы можете видеть его как эквивалент атрибута пути в теге из библиотеки тегов JSP Spring MVC.

Атрибут th:field ведет себя по-разному в зависимости от того, прикреплен ли он к тегу , или (а также в зависимости от конкретного типа тега ). В этом случае (input[type = text]) приведенная выше строка кода похожа на:

… Но на самом деле это немного больше, потому что th:field также будет применять зарегистрированную службу преобразования Spring, включая DateFormatter, который мы видели ранее (даже если выражение поля не заключено в квадратные скобки). Благодаря этому дата будет отображаться правильно отформатированной.

Значения для атрибутов th:field должны быть выражениями выбора (* ), что имеет смысл, учитывая тот факт, что они будут оцениваться на компоненте, поддерживающем форму, а не на переменных контекста (или атрибутах модели в жаргоне Spring MVC). ).

В отличие от выражений в th:object, эти выражения могут включать в себя навигацию по свойствам (фактически здесь позволено любое выражение, разрешенное для атрибута пути тега JSP).

Обратите внимание, что th:field также понимает новые типы элемента , представленные в HTML5, такие как , и т. д., эффективно добавляя полную поддержку HTML5 для Spring MVC.

6.3 Checkbox fields

th:field также позволяет определять входные данные checkbox флажков. Давайте посмотрим пример с нашей HTML-страницы:

Обратите внимание, что здесь есть кое-что еще, кроме самого флажка, например, внешняя метка, а также использование функции #ids.next(‘closed’) для получения значения, которое будет применено к атрибуту id входных данных флажка.

Зачем нам нужно динамическое создание атрибута id для этого поля? Поскольку флажки являются потенциально многозначными, и, следовательно, к их значениям идентификатора всегда будет добавлен суффикс порядкового номера (внутренне используя функцию #ids.seq(…)), чтобы гарантировать, что каждый из флажков input одного и того же свойства имеет другое значение идентификатора.

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

Обратите внимание, что на этот раз мы добавили атрибут th:value, потому что поле функций не является логическим, как было описано выше, а представляет собой массив значений.

Давайте посмотрим вывод HTML, сгенерированный этим кодом:

Здесь мы видим, как суффикс последовательности добавляется к каждому атрибуту id input и как функция #ids.prev(…) позволяет нам извлечь последнее значение последовательности, сгенерированное для определенного идентификатора ввода.

Не беспокойтесь об этих скрытых входах с name = «_ features»: они автоматически добавляются, чтобы избежать проблем с браузерами, не отправляющими невыбранные значения флажков на сервер при отправке формы.

Также обратите внимание, что если бы наше свойство features содержало некоторые выбранные значения в нашем form-backing bean, то th:field позаботилось бы об этом и добавило бы атрибут checked=«checked» в соответствующие входные теги.

6.4 Radio Button fields

Поля переключателей задаются аналогично не булевым (многозначным) флажкам, за исключением того, что, конечно, они не многозначны:

6.5 Dropdown/List selectors

Поля выбора состоят из двух частей: тега и его вложенных тегов . При создании поля такого типа только тег должен включать атрибут th:field, но атрибуты th:value во вложенных тегах будут очень важны, поскольку они будут обеспечивать возможность узнать, какова текущая выбранная опция (аналогично не булевым флажкам и переключателям).

Давайте перестроим поле типа выпадающий список:

На данный момент, понять этот кусок кода довольно легко. Просто обратите внимание, как приоритет атрибута позволяет нам устанавливать атрибут th:each в самом теге .

6.6 Dynamic fields

Благодаря расширенным возможностям связывания полей формы в Spring MVC, мы можем использовать сложные выражения Spring EL для привязки динамических полей формы к нашему form-backing bean. Это позволит нам создавать новые объекты Row в нашем компоненте SeedStarter и добавлять поля этих строк в нашу форму по запросу пользователя.

Для этого нам понадобится пара новых замапированных методов в нашем контроллере, которые добавят или удалят строку из нашего SeedStarter в зависимости от наличия определенных параметров запроса:

@RequestMapping(value="/seedstartermng", params=) public String addRow(final SeedStarter seedStarter, final BindingResult bindingResult) < seedStarter.getRows().add(new Row()); return "seedstartermng"; >@RequestMapping(value="/seedstartermng", params=) public String removeRow( final SeedStarter seedStarter, final BindingResult bindingResult, final HttpServletRequest req)

И теперь мы можем добавить динамическую таблицу в нашу форму:

 
Row Variety Seeds per cell
1 __].seedsPerCell>" />

Достаточно много вещей здесь, но не так много, чтобы не понимать… за исключением одной странной вещи:

Если вы помните из учебника «Использование Thymeleaf», то синтаксис __$__ является выражением предварительной обработки, которое является внутренним выражением, которое вычисляется до фактической оценки всего выражения. Но почему такой способ указания индекса строки? Не будет ли этого достаточно с:

…вообще-то нет. Проблема в том, что Spring EL не оценивает переменные в скобках индекса массива, поэтому при выполнении вышеприведенного выражения мы получим ошибку, сообщающую нам, что rows[rowStat.index] (вместо rows[0], rows[1] и т. д.) недопустимая позиция в коллекции строк. Вот почему здесь необходима предварительная обработка.

Давайте посмотрим на фрагмент полученного HTML-кода после того, как несколько раз нажали «Add Row»:

  1         2         

Источник

Читайте также:  Python что такое return
Оцените статью