<input type="radio" th:field="*{questoes[__${iter.index}__].respostaCorreta}"
th:value="${alternativa.texto}">
I'm working on a project using Thymeleaf and Spring Boot. In my form, I have a set of radio buttons generated dynamically using Thymeleaf. Each radio button is associated with a text input field, and I'm using th:field and th:value attributes to bind the input values. However, when I submit the form, the th:field for the radio button (respostaCorreta) sends both the old value and the new th:value, resulting in something like "OldResponse,NewResponse". I want to send only the new value (th:value) and ignore the old one. How can I achieve this?
System.out.println("\\n\\n\\n" + questaoDTO.getRespostaCorreta() + "\\n\\n\\n");
The result is TH:FIELD,TH:VALUE
, but i want just TH:VALUE
.
I want to send only the new value (th:value
) and ignore the old one. How can I achieve this?
Frontend:
<form th:object="${quiz}" id="quizForm" th:action="${quiz.id == null} ? '/quiz' : '/quiz/' + ${quiz.id}"
method="post" enctype="multipart/form-data">
<div class="form-floating mb-3">
<input class="form-control" type="text" id="quizTitle" th:field="*{titulo}" placeholder="Título do Quiz"
required>
<label for="quizTitle">Título</label>
</div>
<div class="form-floating mb-3">
<input class="form-control" type="number" id="totalPontos" th:field="*{totalPontos}"
placeholder="Pontuação" value="0" readonly required>
<label for="totalPontos">Pontuação</label>
</div>
<div class="form-floating mb-3">
<input class="form-control" type="file" id="imagem" th:field="*{imagem.arquivo}">
<label for="imagem">Selecione uma foto para este quiz</label>
</div>
<div class="form-floating mb-3" id="teste">
<select class="form-select" id="category" th:field="*{categoria}" required>
<option th:each="categoria : ${categorias}" th:value="${categoria.id}" th:text="${categoria.nome}">
</option>
</select>
<label for="category">Categoria</label>
</div>
<div class="form-floating mb-3" id="inputQuestao">
<!-- Questões serão adicionadas aqui -->
<fieldset th:each="questao, questaoStat : ${quiz.questoes}">
<legend class="text-center">Pergunta [[${questaoStat.index} + 1]]</legend>
<div class="form-floating mb-3">
<input type="text" class="form-control" th:field="*{questoes[__${questaoStat.index}__].texto}"
placeholder="Texto da Pergunta" required>
<label th:for="*{questoes[__${questaoStat.index}__].texto}">Pergunta</label>
</div>
<div class="form-floating mb-3">
<input type="text" class="form-control"
th:field="*{questoes[__${questaoStat.index}__].respostaCorreta}" placeholder="Texto da Pergunta"
readonly>
<label th:for="*{questoes[__${questaoStat.index}__].respostaCorreta}">Resposta Correta</label>
</div>
<div class="d-flex justify-content-between mb-3 gap-3">
<div class="col form-floating">
<input onfocusout="alterarPontos()" type="number" class="form-control"
th:field="*{questoes[__${questaoStat.index}__].pontos}" placeholder="Pontos" required>
<label th:for="*{questoes[__${questaoStat.index}__].pontos}">Pontos</label>
</div>
<div class="col form-floating">
<input type="file" class="form-control"
th:field="*{questoes[__${questaoStat.index}__].imagem.arquivo}">
<label th:for="*{questoes[__${questaoStat.index}__].imagem.arquivo}">Selecione uma imagem para
ilustrar a pergunta</label>
</div>
</div>
<h5>Alternativas</h5>
<div th:each="alternativa, alternativaStat : ${questao.alternativas}" class="mb-3">
<div class="d-flex justify-content-between align-items-center gap-3">
<div class="form-floating flex-grow-1">
<input type="text" class="form-control"
th:field="*{questoes[__${questaoStat.index}__].alternativas[__${alternativaStat.index}__].texto}"
placeholder="Digite a possível resposta" required>
<label
th:for="*{questoes[__${questaoStat.index}__].alternativas[__${alternativaStat.index}__].texto}"
th:text="${{'A)', 'B)', 'C)', 'D)'}[__${alternativaStat.index}__]}"></label>
</div>
<div>
<input type="radio"
th:field="*{questoes[__${questaoStat.index}__].respostaCorreta}"
th:value="${alternativa.texto}"
th:id="'alternativa_' + ${questaoStat.index} + '_' + ${alternativaStat.index}" />
<label th:for="*{questoes[__${questaoStat.index}__].respostaCorreta}"
th:text="Correta"></label>
</div>
</div>
</div>
</fieldset>
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary" type="button" id="btnNovaQuestao">Adicionar Nova Pergunta</button>
<button class="btn btn-secondary" type="submit">Salvar Quiz</button>
</div>
</form>
Backend:
@PostMapping("/quiz/{id}")
@Transactional
public String alterarQuiz(@ModelAttribute QuizDTO dto) {
Quiz existingQuiz = quizRepository.findById(dto.getId()).orElseThrow();
existingQuiz.setCategoria(dto.getCategoria());
existingQuiz.setTitulo(dto.getTitulo());
existingQuiz.setTotalPontos(dto.getTotalPontos());
ImagemQuiz imagemQuiz = existingQuiz.getImagem();
if (imagemQuiz == null) {
imagemQuiz = new ImagemQuiz();
imagemQuiz.setQuiz(existingQuiz);
}
imagemQuiz.setNomeArquivo(dto.getImagem().getArquivo().getOriginalFilename());
try {
imagemQuiz.setArquivo(dto.getImagem().getArquivo().getBytes());
} catch (IOException ex) {
// Tratar IOException aqui
}
existingQuiz.setImagem(imagemQuiz);
// Limpar e adicionar questões
existingQuiz.getQuestoes().clear();
for (QuestaoDTO questaoDTO : dto.getQuestoes()) {
Questao questaoEntity = new Questao();
questaoEntity.setTexto(questaoDTO.getTexto());
questaoEntity.setPontos(questaoDTO.getPontos());
System.out.println("\n\n\n" + questaoDTO.getRespostaCorreta() + "\n\n\n");
questaoEntity.setRespostaCorreta(questaoDTO.getRespostaCorreta());
// IMAGEM DA QUESTÃO BANCO DE DADOS
ImagemQuestao imagemEntity = new ImagemQuestao();
imagemEntity.setNomeArquivo(questaoDTO.getImagem().getArquivo().getOriginalFilename());
try {
imagemEntity.setArquivo(questaoDTO.getImagem().getArquivo().getBytes());
} catch (IOException ex) {
// Tratar IOException aqui
}
questaoEntity.setImagem(imagemEntity);
// ALTERNATIVAS DA QUESTÃO BANCO DE DADOS
List<Alternativa> alternativasEntity = new ArrayList<>();
for (AlternativaDTO alternativaDTO : questaoDTO.getAlternativas()) {
Alternativa alternativaEntity = new Alternativa();
alternativaEntity.setTexto(alternativaDTO.getTexto());
alternativaEntity.setQuestao(questaoEntity);
alternativasEntity.add(alternativaEntity);
}
questaoEntity.setAlternativas(alternativasEntity);
questaoEntity.setQuiz(existingQuiz);
existingQuiz.getQuestoes().add(questaoEntity);
}
quizRepository.save(existingQuiz);
return "redirect:/backoffice/quiz";
}