英文:
Java spring boot - retrieve dynamic inputs
问题
我正在尝试构建一个小型的选择题应用程序:
你有一个包含多个问题和多个潜在答案的问卷。用户可以在所有答案中只选择一个(使用单选按钮)。
用户提交表单,但现在我正在尝试从服务器检索用户选择的答案,但我对要做什么没有太多线索,因为这些字段是动态的。
<form method="post" th:action="@{/score}" class="qcm-questions">
<input type="hidden" name="id_quiz" th:value="${id_quiz}" />
<input type="hidden" name="pseudo" th:value="${pseudo}" />
<fieldset class="qcm-questions-item" th:each="question: ${questions}">
<h2 th:text="${question.getLabel()}"></h2>
<small th:text="'Question ' + ${questionStat.index}"></small>
<div th:each="answer: ${question.getAnswers()}">
<label th:text="${answer.getLabel()}" th:for="${answer.getId_answer()}"></label>
<input type="radio" th:id="${answer.getId_answer()}" th:name="${question.getId_question()}" th:value="${answer.getId_answer()}" />
</div>
</fieldset>
<button>Soumettre QCM</button>
</form>
我找到的唯一方法是:
@PostMapping
public String registerScore(@RequestParam("id_quiz") final long id_quiz, @RequestParam("pseudo") final String pseudo, ServletRequest request) {
Map<String, String[]> answers = request.getParameterMap();
answers.remove("id_quiz");
answers.remove("pseudo");
return "page";
}
也许你有比这更好的想法?
英文:
I'm trying to build a small QCM Application:
You have an quiz that have multiple questions and therefore multiple potential answer. The user can select only one answer between all (using radio buttons).
The user submit the form, but now i'm trying to retrieve the answers that the user selected on the server but I have not much clue on what to do because those fields are dynamic.
<form method="post" th:action="@{/score}" class="qcm-questions">
<input type="hidden" name="id_quiz" th:value="${id_quiz}" />
<input type="hidden" name="pseudo" th:value="${pseudo}" />
<fieldset class="qcm-questions-item" th:each="question: ${questions}">
<h2 th:text="${question.getLabel()}"></h2>
<small th:text="'Question ' + ${questionStat.index}"></small>
<div th:each="answer: ${question.getAnswers()}">
<label th:text="${answer.getLabel()}" th:for="${answer.getId_answer()}"></label>
<input type="radio" th:id="${answer.getId_answer()}" th:name="${question.getId_question()}" th:value="${answer.getId_answer()}" />
</div>
</fieldset>
<button>Soumettre QCM</button>
</form>
The only method I found is this :
@PostMapping
public String registerScore(@RequestParam("id_quiz") final long id_quiz, @RequestParam("pseudo") final String pseudo, ServletRequest request) {
Map<String, String[]> answers = request.getParameterMap();
answers.remove("id_quiz");
answers.remove("pseudo");
return "page";
}
Maybe you have a better idea than this ?
答案1
得分: 0
您可以通过参数或模型属性从表单中检索输入。个人而言,我认为模型属性的解决方案更简便,以下是一个相应的代码示例。
我创建了两个模型属性,传递给控制器。第一个将包含所有测验详情,第二个将是在您的表单中收集的答案。
模型属性是对象,当然您可以根据需要进行适应。
```java
@Controller
public class FormQuizController {
@GetMapping("/quiz")
public String main(Model model) {
Question quest1 = new Question();
quest1.setId(1);
quest1.setLabel("What is the answer?");
Answer answer1 = new Answer(1, "answer 1");
Answer answer2 = new Answer(2, "answer 2");
Answer answer3 = new Answer(3, "answer 3");
Answer[] answers = {answer1, answer2, answer3};
quest1.setAnswers(answers);
Question quest2 = new Question();
quest2.setId(2);
quest2.setLabel("What is the answer again?");
quest2.setAnswers(answers);
Question[] questions = {quest1, quest2};
Quiz quiz = new Quiz();
quiz.setId_quiz(1);
quiz.setPseudo("Quiz 1");
quiz.setQuestions(questions);
ResultQuiz resultQuiz = new ResultQuiz(0, "init", new int[questions.length], new int[questions.length]);
model.addAttribute("quiz", quiz);
model.addAttribute("resultQuiz", resultQuiz);
return "quiz";
}
@PostMapping("/score")
public String score(@ModelAttribute ResultQuiz resultQuiz) {
System.out.println(resultQuiz);
return "score";
}
}
主方法创建了一个包含2个问题和每个问题3个答案的测验。它还创建了一个使用虚假数据初始化的resultQuiz。
score方法通过ResultQuiz对象检索测验结果。
以下是域类的代码(为了简洁起见,省略了getter / setter / 构造函数):
public class Quiz {
private int id_quiz;
private String pseudo;
private Question[] questions;
}
public class Question {
private int id;
private String label;
private Answer[] answers;
}
public class Answer {
private int id;
private String text;
}
public class ResultQuiz {
private int id_quiz;
private String pseudo;
private int[] id_question = {0, 0};
private int[] id_answer = {0, 0};
}
然后是使用Thymeleaf的HTML页面代码。
th:object指示与表单相关联的对象。然后,您可以直接绑定数据。
要使用Thymeleaf访问属性的值,您只需指定其名称。
iter变量提供了每次迭代的索引。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>test form</title>
</head>
<body>
<form method="post" th:action="@{/score}" th:object="${resultQuiz}" class="qcm-questions">
<input type="hidden" th:name="'id_quiz'" th:value="${quiz.id_quiz}" >
<input type="hidden" th:name="'pseudo'" th:value="${quiz.pseudo}" >
<p th:text="'Valeur de resultQuiz:' + ${resultQuiz}"></p>
<fieldset class="qcm-questions-item" th:each="question, iter: ${quiz.questions}">
<h2 th:text="${question.label}"></h2>
<small th:text="'Question ' + ${iter.index}"></small>
<input type="hidden" th:name="'id_question['+${iter.index}+']'" th:value="${question.id}" >
<div th:each="answer: ${question.answers}">
<label>
<span th:text="${answer.text}" th:for="${answer.text}"></span>
<input type="radio" th:name="'id_answer['+${iter.index}+']'" th:value="${answer.id}" />
</label>
</div>
</fieldset>
<button type="submit">Soumettre QCM</button>
</form>
</body>
</html>
最后是分数HTML页面的代码:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>test form</title>
</head>
<body>
<span th:text="'For Quiz '+${resultQuiz.id_quiz}+' with name '+${resultQuiz.pseudo}"></span>
<h2>Results are:</h2>
<p th:each="question, iter: ${resultQuiz.id_question}">
<span th:text="'For question '+${question} +' answer is '+${resultQuiz.id_answer[iter.index]}"></span>
</p>
</body>
</html>
英文:
You can retrieve inputs from a form through parameters or modelattributes.
I found personnally the model attribute solution easier and below is a code to do it like so.
I have created 2 modelattributes that I pass to the controller.
The first one will contain all the quiz details and the second one will be the answers collected in you form.
Modelattributes are objects and of course you can adapt the entities.
@Controller
public class FormQuizController {
@GetMapping ("/quiz")
public String main(Model model) {
Question quest1 = new Question();
quest1.setId(1);
quest1.setLabel("What is the answer?");
Answer answer1 = new Answer (1, "answer 1");
Answer answer2 = new Answer (2, "answer 2");
Answer answer3 = new Answer (3, "answer 3");
Answer[] answers = {answer1, answer2, answer3};
quest1.setAnswers(answers);
Question quest2 = new Question();
quest2.setId(2);
quest2.setLabel("What is the answer again?");
quest2.setAnswers(answers);
Question[] questions = {quest1, quest2};
Quiz quiz = new Quiz();
quiz.setId_quiz(1);
quiz.setPseudo("Quiz 1");
quiz.setQuestions(questions);
ResultQuiz resultQuiz = new ResultQuiz(0,"init", new int[questions.length],new int[questions.length]);
model.addAttribute("quiz", quiz);
model.addAttribute("resultQuiz", resultQuiz);
return "quiz";
}
@PostMapping ("/score")
public String score(@ModelAttribute ResultQuiz resultQuiz) {
System.out.println(resultQuiz);
return "score";
}
}
The method main is creating a quiz with 2 questions and 3 answers for each questions. It is also creating a resultQuiz initialized with fake data.
the method score is retrieving the result of the quiz through the object ResultQuiz.
Below the classes for domain (getters/setters/constructors omitted for brevity):
public class Quiz {
private int id_quiz;
private String pseudo;
private Question[] questions;
}
public class Question {
private int id;
private String label;
private Answer[] answers;
}
public class Answer {
private int id;
private String text;
}
public class ResultQuiz {
private int id_quiz;
private String pseudo;
private int[] id_question = {0,0};
private int[] id_answer = {0,0};
}
Then the code for the html pages using thymeleaf.
th:object indicates the object linked to the form. Then you can bind data directly.
To access values of an attribute with thymeleaf you just need to indicate the name of it.
iter variable gives you the index of each iteration.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>test form</title>
</head>
<body>
<form method="post" th:action="@{/score}" th:object="${resultQuiz}" class="qcm-questions">
<input type="hidden" th:name="'id_quiz'" th:value="${quiz.id_quiz}" >
<input type="hidden" th:name="'pseudo'" th:value="${quiz.pseudo}" >
<p th:text="'Valeur de resultQuiz:'+${resultQuiz}"></p>
<fieldset class="qcm-questions-item" th:each="question, iter: ${quiz.questions}">
<h2 th:text="${question.label}"></h2>
<small th:text="'Question ' + ${iter.index}"></small>
<input type="hidden" th:name="'id_question['+${iter.index}+']'" th:value="${question.id}" >
<div th:each="answer: ${question.answers}">
<label>
<span th:text="${answer.text}" th:for="${answer.text}"></span>
<input type="radio" th:name="'id_answer['+${iter.index}+']'" th:value="${answer.id}" />
</label>
</div>
</fieldset>
<button type="submit">Soumettre QCM</button>
</form>
</body>
</html>
And finally the code for the score html page:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>test form</title>
</head>
<body>
<span th:text="'For Quiz '+${resultQuiz.id_quiz}+' with name '+${resultQuiz.pseudo}"></span>
<h2>Results are:</h2>
<p th:each="question, iter: ${resultQuiz.id_question}">
<span th:text="'For question '+${question} +' answer is '+${resultQuiz.id_answer[iter.index]}"></span>
</p>
</body>
</html>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论