Spring Boot Thymeleaf - processing Form values - spring-mvc

I'm learning Spring Boot+thymeleaf at the same time, so apologies if this is a noob question - however i haven't seen an example of what I'm trying to achieve.
I'm building a questionnaire of Question objects. Each Question object has properties like description, weightage, and a TreeMap of answer options with Pts for the answer as the Key, and the option text as the value.
The Question sequence to be displayed matters, and the option sequence matters as well(hence the TreeMap for options).
I iterate over the List of questions in the form like this(this shows just one question and iteration over the options for that question) :
<form action="#" th:action="#{/frm}" th:object="${scorer}" method="post">
<table>
<tr th:each="question, iterStat: ${questionList}">
<td th:text="${question.getQuestionText()}"></td>
<td>
<select th:field="*{answers}">
<option th:each="option :${questionList[iterStat.index].getAnswerOptions()}"
th:value="${option.getKey()}"
th:text= "${option.getValue()}">
</option>
</select>
</td>
</tr>
</table>
</form>
So, here are my questions:
Since the order of the answers is important for me(i need to send back text that is dependent on what they selected for each question), is there a way to retrieve(on POST) a sorted map of (question,chosen answer) in the order of questions displayed without having to name each question field?
What does the form-bound bean need to look like? I guess I'm also looking for some insight into how Spring Boot does its magic here?

Related

unable to understand an example from developer.mozilla.org

In the following tutorial https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications
There is an example (at the beginning)
<input type="file" id="input" onchange="handleFiles(this.files)">
Where does this.files come from?
this.files is the objects that correspond to the files selected by the user.

Thymeleaf: how use the dates.format method with i18n through object model

I am working with Spring Framework and Thymeleaf 3.0.9.RELEASE
About a list report, In a #Controller exists the following:
model.addAttribute("personas", personaService.findAll());
model.addAttribute("dateFormatPattern", "date.format.pattern");
I have read the following:
Thymeleaf: Use #dates.format() function for format date with internatinalization.
Thus in the view exists the following:
<tbody>
<tr th:each="persona : ${personas}" >
<td th:text="${personaStat.count}">###</td>
<td th:text="${persona.id}">###</td>
<td th:text="${persona.nombre}">###</td>
<td th:text="${persona.apellido}">###</td>
<td th:text="${#dates.format(persona.fecha, #messages.msg('date.format.pattern'))}">###</td>
Until here "${#dates.format(persona.fecha, #messages.msg('date.format.pattern'))}" works fine.
Thus from:
model.addAttribute("dateFormatPattern", "date.format.pattern")
you can see that date.format.pattern (the value of the attribute) is used directly in #messages.msg('date.format.pattern').
Thus until here model.addAttribute("dateFormatPattern", "date.format.pattern") is useless or is not need it
I want to know (if is possible) how would be the correct syntax to use the dateFormatPattern (the key of the attribute) instead, it to expect that Thymeleaf retrieve the date.format.pattern value and then retrieve the correct pattern from the .properties file.
Reason: the scenario is where there is a high potential possibility to change date.format.pattern value to other and thus it to be reflected through many views (html files about reports where the Date field is used) than the dateFormatPattern key instead.
Thus if date.format.pattern is changed to date.format.abc.pattern it should be in the server side, not for each .html file. Therefore dateFormatPattern (the key of the attribute) remains without changes

Thymeleaf errors messages optimization

I looked at this tutorial: https://spring.io/guides/gs/validating-form-input.
Using th:errors results in <br> separeted error messages. I want to have an unordered list. So I've defined a fragment like this ...
<td th:fragment="validationMessages(field)" th:if="${#fields != null and field != null and #fields.hasErrors(field)}">
<ul>
<li th:each="error : ${#fields.errors(field)}" th:text="${error}"></li>
</ul>
</td>
... and using it with ...
<td th:replace ="form :: validationMessages('age')"></td>
Is there a "clean code" solution / best practice, like overriding the render implementation of th:errors?
You could probably create your own Thymeleaf Processor, based on org.thymeleaf.spring4.processor.attr.SpringErrorsAttrProcessor, that used your own method of delimiting errors, and then use that rather than the one Thymeleaf gives you. It doesn't look particularly designed for extending, though.
I think the way you did it is probably best. I tend to prefer my HTML templates to be in a templating language (like Thymeleaf) rather than in Java code. You can modify as needed (such as adding styling classes) and it's clear what the code does. This is exactly the kind of thing template fragments are made for.

Meteor dynamic form generation

I have a survey form I would like an admin to be able to add more questions to on the fly. The way I'm thinking of doing this is to have the admin add questions to a Questions collection with several properties e.g:
{
"description" : "desc",
"fieldType" : "textField",
"sortOrder" : 1,
"dataType" : "text",
"_id" : "eFopP8XFgY8Br93fA"
}
and then on the client side, loop through these using an #each block and a dynamic template like so:
{{#each questions}}
{{>Template.dynamic template=fieldType}}
{{/each}}
Now the "fieldType" field would correspond to the name of a stored template e.g
<template name="textField">
<div>
<input id="{{_id}}" type="{{dataType}}" class="validate">
<label for="{{_id}}">{{description}}</label>
</div>
</template>
and inside these templates would have different input fields depending on the type.
I have two issues:
Is this a good way to go about this problem?
If it is, how would you be able to get the values of these input fields when saving the answers (as we don't know what fields could be there at compile time)
Regarding your first question, I agree with #Kyll regarding autoform and I think you can pass the schema as a json object dynamically.
Regarding your 2nd question, please check SO question Dynamically add form fields in meteorjs where you will find answer to your second question. You can easily grab value of all fields in your dynamically created form using .serializeArray() JQuery serializeArray

Pass TWIG Objects to Javascript (json_encode result is empty)

I have a collection of items passed from my controller to my twig template called qualifications. I then loop through each object in the collection and print it to a row in the table. Every respective row has an "Edit" button, which should pass that object's values to a javascript function. Here is my code:
{%for qualification in qualifications%}
<tr id="qualification_{{qualification.id}}">
<td>{{qualification.name}}</td>
<td>{{qualification.saqaId}}</td>
<td>{{qualification.qualificationType}}</td>
<td>{%if (qualification.course is null) %} - {%else%} {{qualification.course.name}} {%endif%}</td>
<td>0</td>
<td><a class="button btn-primary btn-xs" onclick="setForm({{qualification|json_encode(constant('JSON_PRETTY_PRINT'))}});">Edit</a></td>
</tr>
{%endfor%}
I am getting the information in the table row as expected, but when looking at the HTML on the Edit button I just see onclick="setForm({});". I have tried with and without the raw, I have also tried {{qualification|json_encode(constant('JSON_PRETTY_PRINT'))}} but all return blank.
On a similar, but not related note. I have been having other issues with TWIG as well. {{dump()}} just loads a while and then gives a blank page with an unspecified 500 error. have tried activating the twig debug in services.xml and config.yml with what documentation I could find, but to no avail. This, however is not my primary concern, my primary concern is json_encode returning an empty result.
And help or advice on this would be greatly appreciated as I have run into a wall.
Have you tried to {{ dump(qualifications) }}? What is the output?

Resources