This article is an example of a Kendo Wizard Component sending an HTTP POST to a Spring Boot backend. The framework used is Kendo UI for jQuery. In this example, we send the entire Wizard form data after all the questions are answered.
The IDE used is Spring Tool Suite 4 and it is expected that the reader know a thing or two about Spring Boot. This is about Kendo Wizard so there won't be any extensive Spring Boot explanations. Make sure you are connected to the Internet because the code pulls the Kendo library from the Telerik CDN. Take note that this is just a demonstration code and you'll need to purchase a license if you are going to use Kendo UI for jQuery for more than just evaluation purposes.
First on the agenda is our controllers. Here is the WizardController
class.
package com.blogspot.jpllosa.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.blogspot.jpllosa.model.Questionaire;
@Controller
public class WizardController {
@GetMapping("/wizard")
public String wizardForm() {
return "wizard";
}
@GetMapping("/success")
public String successPage() {
return "success";
}
@PostMapping("/wizard")
public ResponseEntity wizardSubmit(@ModelAttribute Questionaire questionaire) {
System.out.println(questionaire);
return new ResponseEntity<>("",
HttpStatus.OK);
}
}
This class handles a couple of HTTP GET requests and an HTTP POST request. GET requests to /wizard
and /success
resources return the wizard.html
and success.html
templates respectively.
The POST request to the /wizard
resource is handled by the wizardSubmit
method. Spring is kind enough to map the Form data received to the Questionaire
class. When a POST request is received, this prints the questionaire contents to the console and reponds with an HTTP OK.
Here's the Questionaire
class.
package com.blogspot.jpllosa.model;
public class Questionaire {
private String section1answer1;
private String section1answer2;
private String section2answer1;
private String section2answer2;
public String getSection1answer1() {
return section1answer1;
}
public void setSection1answer1(String section1answer1) {
this.section1answer1 = section1answer1;
}
public String getSection1answer2() {
return section1answer2;
}
public void setSection1answer2(String section1answer2) {
this.section1answer2 = section1answer2;
}
public String getSection2answer1() {
return section2answer1;
}
public void setSection2answer1(String section2answer1) {
this.section2answer1 = section2answer1;
}
public String getSection2answer2() {
return section2answer2;
}
public void setSection2answer2(String section2answer2) {
this.section2answer2 = section2answer2;
}
@Override
public String toString() {
return "Questionaire [section1answer1=" + section1answer1 + ", section1answer2=" + section1answer2
+ ", section2answer1=" + section2answer1 + ", section2answer2=" + section2answer2 + "]";
}
}
Here is the meat of this example. The Kendo Wizard has a couple of sections, each with a couple of questions. After answering all the questions, clicking on done triggers the done
event handler. What this function does is grab all the form data and put it into a FormData
object. The FormData
is then sent to the /wizard
endpopint via an AJAX request. If successful, the frontend code handles the POST-Redirect-GET because the backend can't do a redirect from an AJAX request. The backend just prints what was received in this example.
<!--https://jpllosa.blogspot.com-->
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Kendo Wizard POST to Spring Boot Example</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"></meta>
<link href="https://kendo.cdn.telerik.com/2021.1.224/styles/kendo.default-v2.min.css" rel="stylesheet"></link>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2021.1.224/js/kendo.all.min.js"></script>
</head>
<body>
<div id="wizard"></div>
<script>
var $wizard = $("#wizard");
var wizard = $wizard.kendoWizard({
validateForms: true,
steps: [{
title: "Sample Questionaire",
content: "Click <b>Next</b> to begin.",
},{
title: "Section 1",
form: {
formData: {
section1answer1: "",
section1answer2: "",
},
items: [{
field: "section1answer1",
label: "Some silly question 1:",
validation: {
required: true,
},
},{
field: "section1answer2",
label: "Some silly question 2:",
validation: {
required: true,
},
}],
},
},{
title: "Section 2",
form: {
formData: {
section2answer1: "",
section2answer2: "",
},
items: [{
field: "section2answer1",
label: "Another silly question 1:",
validation: {
required: true,
},
},{
field: "section2answer2",
label: "Another silly question 2:",
validation: {
required: true,
},
}],
},
},{
title: "Done",
content: "Thank you for answering.",
}],
done: function(e) {
var forms = e.forms;
var formData = new FormData();
for (let a = 0; a < forms.length; a++) {
var form = forms[a];
for (let b = 0; b < form._fields.length; b++) {
var field = form._fields[b];
formData.append(field.field, form._model[field.field]);
}
}
$.ajax({
type: "POST",
url: "/wizard",
contentType: false, // do not send content type header
processData: false, // do not transform into a query string
data: formData,
})
.done(function(data, textStatus, jqXhr) {
// success = redirect to success page
if (textStatus === 'success') {
// post redirect get
// back-end can't redirect from ajax request
window.location.replace("/success");
}
})
.fail(function(jqXhr, textStatus, errorThrown) {
console.log("fail");
})
.always(function() {
console.log("always");
});
}
}).data('kendoWizard');
</script>
<style>
.k-stepper .k-step-label .k-step-text {
max-width: calc(30em - 20px);
}
</style>
</body>
</html>
Here is how it would look like:
Kendo Wizard Start |
Kendo Wizard Questions |
Kendo Wizard Done |
Kendo Wizard Success |
Spring Boot should print something like below:
2021-10-23 21:05:25.845 INFO 5872 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet Completed initialization in 1 ms
Questionaire [section1answer1=silly 1, section1answer2=silly 2, section2answer1=another 1, section2answer2=another 2]
There you have it. The complete project can be cloned from github.com/jpllosa/spring-boot-kendo-wizard.