admin管理员组文章数量:1310498
i want to update the content of div "output" without reloading the whold page. When the user inputs something and hits the run button, the server will output the evaluation on the div "output". But the following code puts only div "output" on the browser. The other piece of page is gone. what i have done wrong ?
<body>
<div class="container mx-auto">
<div th:insert="fragments/body :: navigation (true, ${spieler.name}, ${spieler.punkte}, ${spieler.level})"></div>
<div class="d-flex justify-content-center">
<label class="text-center mt-4" id="thetext">Du liebst Abenteuer und möchte endlich reisen.<br>
Du hast ein bisschen Geld und das reicht für ein Ticket zur nächsten Insel.<br>
Unglücklicherweise ist dein Schiff in einem Sturm gesunken. <br>
Du hat glück, an einen Strand zu landen. <br><br>
Jetzt musst du die Herausforderungen mit deinen SQL-Kenntnissen meistern.<br>
Je schneller du die Probleme löst, desto besser ist dein Ranking.<br><br>
Viel Spaß !!!<br>
</label>
</div>
<div class="d-flex justify-content-center">
<input id="startButton" onclick="nachsteFrage()" class="btn-secondary mt-4"
type="button" value="Weiter">
</div>
<form method="post" th:action="@{/level1-answer}" th:object="${answer}">
<div class="form-group">
<input type="text" class="form-control mt-4" id="codeArea" name="antwort" th:field = "*{SQL}"
rows="3" placeholder="Hier steht dein Code ...">
<br>
<div class="d-flex justify-content-center">
<button onclick="updateOutput()" class="btn-secondary mt-4"
id="ausfuehrenBtn">run</button>
</div>
</div>
</form>
<div id="output" style="overflow:scroll; height:400px;">
<span th:text = "${evaluation}"></>
</div>
</div>
<script th:inline="javascript">
function updateOutput() {
$.get("output").done(function(fragment) {
$("#output").replaceWith(fragment);
});
}
</script>
</body>
the controller
@RequestMapping(value="/level1-answer", method=RequestMethod.POST)
public String postSQL (Model map, @ModelAttribute("answer") Answer answer) {
map.addAttribute("evaluation",answer.getSQL() + " this is correct or incorrect");
return "level1 :: #output";
}
the html file is in templates/level1.html
i want to update the content of div "output" without reloading the whold page. When the user inputs something and hits the run button, the server will output the evaluation on the div "output". But the following code puts only div "output" on the browser. The other piece of page is gone. what i have done wrong ?
<body>
<div class="container mx-auto">
<div th:insert="fragments/body :: navigation (true, ${spieler.name}, ${spieler.punkte}, ${spieler.level})"></div>
<div class="d-flex justify-content-center">
<label class="text-center mt-4" id="thetext">Du liebst Abenteuer und möchte endlich reisen.<br>
Du hast ein bisschen Geld und das reicht für ein Ticket zur nächsten Insel.<br>
Unglücklicherweise ist dein Schiff in einem Sturm gesunken. <br>
Du hat glück, an einen Strand zu landen. <br><br>
Jetzt musst du die Herausforderungen mit deinen SQL-Kenntnissen meistern.<br>
Je schneller du die Probleme löst, desto besser ist dein Ranking.<br><br>
Viel Spaß !!!<br>
</label>
</div>
<div class="d-flex justify-content-center">
<input id="startButton" onclick="nachsteFrage()" class="btn-secondary mt-4"
type="button" value="Weiter">
</div>
<form method="post" th:action="@{/level1-answer}" th:object="${answer}">
<div class="form-group">
<input type="text" class="form-control mt-4" id="codeArea" name="antwort" th:field = "*{SQL}"
rows="3" placeholder="Hier steht dein Code ...">
<br>
<div class="d-flex justify-content-center">
<button onclick="updateOutput()" class="btn-secondary mt-4"
id="ausfuehrenBtn">run</button>
</div>
</div>
</form>
<div id="output" style="overflow:scroll; height:400px;">
<span th:text = "${evaluation}"></>
</div>
</div>
<script th:inline="javascript">
function updateOutput() {
$.get("output").done(function(fragment) {
$("#output").replaceWith(fragment);
});
}
</script>
</body>
the controller
@RequestMapping(value="/level1-answer", method=RequestMethod.POST)
public String postSQL (Model map, @ModelAttribute("answer") Answer answer) {
map.addAttribute("evaluation",answer.getSQL() + " this is correct or incorrect");
return "level1 :: #output";
}
the html file is in templates/level1.html
Share Improve this question asked Dec 2, 2021 at 15:19 CT11CT11 731 silver badge7 bronze badges 5-
Your
ausfuehrenBtn
button is currently placed inside the<form>
- and therefore when you click it, the form submission logic will be executed:method="post" action="/level1-answer"
. TheupdateOutput()
function (which is aGET
not aPOST
) will not be called at all. You can see this for yourself by moving the button to after the closing</form>
tag. TheGET
in the function may still fail if you do not have a controller for it. Basically: don't mix form-based actions with Ajax actions, like this. – andrewJames Commented Dec 2, 2021 at 19:57 -
Minor point: The span element is missing a proper closing tag:
<span th:text="${evaluation}"></span>
. – andrewJames Commented Dec 2, 2021 at 19:57 - If you want to do this, check out htmx as it is build for doing this kind of thing. I have a few articles on my website to get you started with htmx and Thymeleaf if you are interested: wimdeblauwe./tags/htmx – Wim Deblauwe Commented Dec 3, 2021 at 7:37
- @andrewJames how can i solve this problem please ? Sorry, i'm new in Spring – CT11 Commented Dec 3, 2021 at 8:53
- It's not really a Spring question - it's a HTML forms vs. Ajax question. You have all the pieces you need in your question, but you have just mixed together two separate approaches. I have tried to show an example which focuses on the Ajax approach - see my answer. – andrewJames Commented Dec 3, 2021 at 15:09
2 Answers
Reset to default 7Here is a very basic demo, to show one approach.
I start with the main web page testajax.html
:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-patible" content="ie=edge">
<title>Test Ajax Fragment</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.jquery./jquery-3.6.0.min.js"></script>
</head>
<body>
<h3>A Permanent Heading</h3>
<div id="output">
Some initial text displayed here. This will be replaced.
</div>
<br>
<button onclick="updateOutput()"
id="ausfuehrenBtn">run</button>
<script>
function updateOutput() {
$.post("test_ajax_frag").done(function (fragment) {
console.log(fragment);
$("#output").replaceWith(fragment);
});
}
</script>
</body>
</html>
Note that there is no <form>
here, because we are not going to be submitting any form data - we will, instead, be using an Ajax request, later on.
The controller used to display this page:
@RequestMapping(value="/test_ajax", method=RequestMethod.GET)
public String sendHtml(Model map) {
//map.addAttribute("foo", "bar");
return "testajax";
}
It's a simple GET
handler, used to display the initial page. I don't even have any specific Model
data in this case, just to keep the demo simple.
The Thymeleaf fragment template is testajaxfragment.html
:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf">
<body>
<div th:fragment="test_frag">
<div id="output">
Some replacement content.
</div>
</div>
</body>
</html>
The main page contains an Ajax call, which is executed when the button is clicked:
$.post("test_ajax_frag")
We need a separate controller for that:
@RequestMapping(value="/test_ajax_frag", method=RequestMethod.POST)
public String sendHtmlFragment(Model map) {
//map.addAttribute("foo", "bar");
return "testajaxfragment :: test_frag";
}
In this case, I chose to use a POST request in the Ajax call - so the controller has to also be a POST
handler.
When the controller runs, it returns a fragment of HTML to the JavaScript function which called it. That function then replaces the output
div:
$("#output").replaceWith(fragment);
This is a fairly crude approach, but shows the technique you are asking about in the question and in your ments.
this works for me
<script>
$(document).ready(function () {
//call function when page is loaded
getContent();
//set on change listener
$('#selection').change(getContent);
function getContent() {
//create url to request fragment
var url = /content/;
if ($('#selection').val() === "Content 1") {
url = url + "content1";
} else {
url = url + "content2";
}
//load fragment and replace content
$('#replace_div').load(url);
}
})
</script>
https://riptutorial./thymeleaf/example/28530/replacing-fragments-with-ajax
本文标签: javascriptUpdate content in Thymeleaf without reloading whole pageStack Overflow
版权声明:本文标题:javascript - Update content in Thymeleaf without reloading whole page - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741823067a2399480.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论