How to show notification with animation without reloading stranicy after submitting the form in Spring Boot?

Prilocaine on Spring Boot + Thymeleaf

There is a form. After clicking the button the data is saved in database field , redirect to the same page and
a notification appears on the same page that the save completed successfully.
Everything works fine, notification appears, but I don't like reboots page and this notice appears statically(sharply). I wish this process was no restart and the notification appeared to smoothly, with some animation. Vasona need to use AJAX and Javascript, but I don't know how to do it.

How to implement it?

Controller:

@PostMapping("/sketches/add")
 public String addSketch(
 @Valid Sketch sketch
 BindingResult result,
 ModelMap model,
 RedirectAttributes redirectAttributes) {
 redirectAttributes.addFlashAttribute("message", "Failed");
 redirectAttributes.addFlashAttribute("alertClass", "alert-danger");
 if (result.hasErrors()) {
 return "admin/add-sketch";
}
sketchRepository.save(sketch);
 redirectAttributes.addFlashAttribute("message", "Success!");
 redirectAttributes.addFlashAttribute("alertClass", "alert-success");
 return "redirect:/admin/sketches/add";
 }


Form in HTML:

<form action="#" th:action="@{/admin/sketches/add}" th:object="${sketch}" method="post" id="save-sketch">
 <div class="add-sketch">
 <div class="title">
 <div class="title-text">
<p>Title
 <span th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="error"></span>
</p>
 <input type="text" class="title-input" th:field="*{title}">
</div>
 <div class="title-file">
 <label for="file-input">
 <img th:src="@{/images/add image.png}" alt="upload image">
</label>
 <input id="file-input" type="file"/>
</div>
 <span id="image-text">No file chosen, yet</span>
</div>

 <!--SKETCH TEXT====================================-->
 <div class="sketch-text">
 <p>Sketch Text
 <span th:if="${#fields.hasErrors('text')}" th:errors="*{text}" class="error"></span>
</p>
 <textarea name="sketch-area" id="" cols="55" rows="6" th:field="*{text}"></textarea>
</div>

<!--DROPDOWN-->
 <div class="select">
 <select name="select-category" id="select-category" th:field="*{category}">
 <option value="Buttons">Buttons</option>
 <option value="Potentiometers">Potentiometers</option>
 <option value="Encoders">Encoders</option>
 <option value="Leds">Leds</option>
</select>
</div>

 <span th:if="${#fields.hasErrors('category')}" th:errors="*{category}" class="error"></span>

 <!--ADD GIF=====================================-->
 <input type="file" id="gif-file" hidden="hidden">
 <button type="button" id="gif-button">Add. GIF<i class="fa fas-image"></i></button>
 <span id="gif-text">No file chosen, yet</span>

 <div class="save-sketch">
 <button type="submit" class="save-sketch-button">Save Sketch</button>
</div>
 <div th:if="${message}" th:class="${'alert' + alertClass}" class="success-message animated slideInDown">
 <div class="success-content">
 <i class="fas fa-check-circle"></i>
 <p th:text="${message}"></p>
</div>
</div>

</div>
 </form>


Unit with a notice in the form displayed or not displayed according to the response from the controller:
<div th:if="${message}" th:class="${'alert' + alertClass}" class="success-message animated slideInDown">
 <div class="success-content">
 <i class="fas fa-check-circle"></i>
 <p th:text="${message}"></p>
</div>
 </div>
April 19th 20 at 12:33
2 answers
April 19th 20 at 12:35
Hello!
All of you have correctly speculated about Ajax & JS, CSS.
To write code from scratch will not, and will only tell you the stages to achieve the desired...
1) Create a method that ajax request will return a @ResponseBody, or create a controller and add the annotation @RestController
2) Before the end tag </body> add the js code for Ajax.
https://ruseller.com/jquery.php?id=11
https://api.jquery.com/jquery.ajax/
3) Next, the controller process the request and return a String or, for example, Map<String, String> with the desired data.
4) In ajax success event, show your block with the animation.

Now, about the animation itself...
Animation can be done with CSS or JS.
Here is an example CSS
For example here, your block and it is hidden by default
<div class="notify" style="display:none;"></div>
When success make this unit show() (visible).
Show - https://api.jquery.com/show/
Hide - https://api.jquery.com/hide/

It only remains to add animations - @keyframes
https://www.w3schools.com/css/css3_animations.asp

Here, ready libraries
https://stephanwagner.me/jBox
https://notifyjs.jpillora.com/
Thank you for your detailed answer!
I liked the library Timepicker. Functionality everything is perfect for me. No need to fence layout for their own notifications. So I decided to use it) - Eugene_V commented on April 19th 20 at 12:38
April 19th 20 at 12:37
Found a library Timepicker, everything works as it should.
That is what we have at the output:

Method that saves the fields in the database:

@PostMapping("/sketches/add")
 public String addSketch(
 @Valid Sketch sketch
 BindingResult result,
 RedirectAttributes redirectAttributes) {

 redirectAttributes.addFlashAttribute("action", "save");
 if (result.hasErrors()) {
 return "admin/add-sketch";
}
sketchRepository.save(sketch);
 return "redirect:/admin/sketches/add";
 }


Connection biblioteki Timepicker in html file:

<link rel="stylesheet" th:href="@{/libs/timepicker/timepicker.min.css}">

 <script th:src="@{/libs/jquery/jquery-3.4.1.min.js}"></script>
 <script defer th:src="@{/libs/toastr/toastr.min.js}"></script>
 <script defer th:src="@{/js/add-sketch.js}"></script>


Settings for the library Timepicker in a separate file add-sketch.js:

/*TIMEPICKER OPTIONS*/
timepicker.options = {
 "closeButton": false,
 "debug": false,
 "newestOnTop": false,
 "progressBar": false,
 "positionClass": "toast-bottom-right",
 "preventDuplicates": false,
 "onclick": null,
 "showDuration": "300",
 "hideDuration": "1000",
 "timeOut": "2000",
 "extendedTimeOut": "1000",
 "showEasing": "swing",
 "hideEasing": "linear",
 "showMethod": "fadeIn",
 "hideMethod": "fadeOut"
};


The call to the script library at the end of the html file:

<script th:inline="javascript">
 $(document).ready(function () {
 var action = [[${action}]];
 if (action === 'save') {
timepicker["success"]("Success!")
}
});
</script>

Find more questions by tags ThymeleafSpring