To keep forms consistent, arrange buttons in the following order:
Save Cancel Reset Delete
This also means that pressing the Enter key in a form field will perform the default Submit action "Save", which is usually what people expect.
For example:
<div class="form-group row">
<div class="col-sm-10">
<input class="btn btn-primary" name="action" id="save" type="submit" value="Save" />
<a th:href="'/reg/atconorder/' + ${order.id}" class="btn btn-secondary">Cancel</a>
<input class="btn btn-secondary" type="reset" value="Reset" />
</div>
<div class="col-sm-2">
<input class="btn btn-danger" th:if="${attendee.id != null}" type="submit" name="action" value="Delete" />
</div>
</div>
Dates and times that represent a specific instant in time should be stored in the database in UTC, but should
generally be shown to the user in the user's time zone (currently PST is hardcoded in DateTimeService.java
.
In Model objects, this is most easily achieved with OffsetDateTime
, which is supported by modern JDBC libraries,
making mapping to/from the database easy.
The only notable exception is the attendee's date of birth, which is actually a LocalDate (stored without timezone information). Though technically not true, we generally want to assume that someone born on April 3rd at 1:00 AM on the east coast treats their birthday as April 3rd, even though they were actually born on April 2nd at 10:00 PM in the pacific time zone.
More than you ever wanted to know about time:
Handy examples when using Thymeleaf:
- String formatting using literal substitutions:
<span th:text="|(${attendee.age} years old)|"></span>
- Date formatting using DateTimeService (preferred)
<td th:text="${dts.format(tillSession.startTime)}"></td>
(See DateTimeService.java
for more details. It is included in the model with the
name dts
.)
- Date formatting using thymeleaf-extras-java8time
<span th:text="|${#temporals.format(attendee.birthDate , 'MM/dd/yyyy')} (${attendee.getAge()})|">01/01/1990 (29)</span>
<td th:text="${t.startTime} ? ${#temporals.format(t.startTime, 'EEE MM/dd/yyyy h:mm:ss a zzz')} : ''"></td>
- Display content if the current user has a specific right thymeleaf-extras-springsecurity:
<div class="row" th:if="${#authorization.expression('hasAuthority(''attendee_search'')')}">
...
</div>
Spring Boot (the framework this service is based on) has rich support for configuration via the application.properties
file and environment variables.
Read a value from configuration:
...
public GuestImportService(@Value("${registration.guestinputpath}") String onlineImportInputPath,
@Value("${registration.onlinedlqpath}") String onlineDLQPath) {
this.onlineImportInputPath = onlineImportInputPath;
this.onlineDLQPath = onlineDLQPath;
}
...
Some settings have default values set in the application.properties
file, but may be configured at run time
via the user interface. See SettingsController.java
for more information. When set, configuration is cached in
memory and stored in the database, which takes precedence over default values configured in application.properties
.