Problème de refresh de fragment thymeleaf avec Ajax-Jquery sous Spring
Bonjour,
J'espère tout d'abord être dans la bonne section.
Je n'ai pas beaucoup d'expérience en codage, et sur un petit projet, je me heurte à un soucis que je ne comprends pas bien (enfin, celui-ci en particulier). J'essaie de développer une application avec Spring boot, thymeleaf et jquery. Je bloque sur l'aspect "Ajax". Voici mon code:
Mon fragment principal:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" th:href="@{/css/StyleMenuDeroulant.css}" />
<link rel="stylesheet" th:href="@{/css/masterStyle.css}" />
<link rel="stylesheet" th:href="@{/css/catalogueRaisonne.css}" />
<script type="text/javascript"
th:src="@{/js/libraries/jquery-3.6.1.complet.js}"></script>
</head>
<body>
<main>
<div id="barre-navigation"
th:replace="fragments/app-fragments :: barre-navigation-frag">
NavNew</div>
<!-- ================================================================================================== -->
<!-- Le contenu principal de la page -->
<div id="home-main-content" class="pplContent"
th:fragment="fragmentCatalogueRaisonne"
th:object="${catalogueRaisonneForm}">
<form th:action="${#httpServletRequest.requestURI}" method="post"
th:object="${catalogueRaisonneForm}">
<!-- action="catalogueRaisonne/decennieSelect" -->
<div id="selectionDecennies" style="margin-top: 300px;"
class="selectionDecennies">
<th:block th:each="decennie : ${decennies}">
<input type="button" th:id="${decennie}" th:value="${decennie}"
th:name="${decennie}" onclick="doAjax()"
th:field="selectedDecennie">
<!-- onclick="retrieveGuests()"-->
</input>
</th:block>
</div>
<div id="resultsBlock">
Le bloc Resultat
</div>
</form>
</div>
<script th:inline="javascript" th:src="@{/js/catalogueRaisonne.js}"></script>
<div id="home-footer"
th:replace="fragments/app-fragments :: copyright">Footer</div>
</main>
</body>
</html> |
Le fragment que je souhaite insérer dans ma div "resultsBlock"
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<th:block th:fragment="frag" th:object="${catalogueRaisonneForm}">
<div id="test1" class="selectionDecennies">
<th:block th:if="${!years.isEmpty()}"
th:each="year : ${years}" >
<!-- th:value="${decennie}" -->
<input type="button" th:id="${year}"
th:value="${year}" th:name="${year}" >
</input>
</th:block>
</div>
</th:block>
</body>
</html> |
Pour cela, j'ai un BaseController:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| package vernano.foundation.vernano.controllers.catalogueRaisonne;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import forms.CatalogueRaisonneForm;
import vernano.foundation.vernano.services.ICatalogueRaisonneService;
@Controller
public class BaseCatalogueRaisonneController {
protected final ICatalogueRaisonneService catalogueRaisonneService;
public BaseCatalogueRaisonneController (ICatalogueRaisonneService catalogueRaisonneService) {
this.catalogueRaisonneService = catalogueRaisonneService;
}
@ModelAttribute("catalogueRaisonneForm")
public CatalogueRaisonneForm getCatalogueRaisonneForm() {
CatalogueRaisonneForm catalogueRaisonneForm = new CatalogueRaisonneForm();
return catalogueRaisonneForm;
}
@ModelAttribute("decennies")
public List<String> getDecennies(){
List<String> decennies = new ArrayList<>();
decennies.addAll(Arrays.asList("1960-1969", "1970-1979", "1980-1989", "1990-1999", "2000-2009"));
return decennies;
}
@ModelAttribute("years")
public List<String> getYears (final CatalogueRaisonneForm catalogueRaisonneForm){
if (catalogueRaisonneForm.getSelectedDecennie() != null && !catalogueRaisonneForm.getSelectedDecennie().isEmpty()) {
return catalogueRaisonneService.getYearsByDecennie(catalogueRaisonneForm.getSelectedDecennie());
} else {
return new ArrayList<>();
}
}
} |
Pour la partie Ajax, j'ai un AjaxController:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| package vernano.foundation.vernano.controllers.catalogueRaisonne;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import forms.CatalogueRaisonneForm;
import vernano.foundation.vernano.services.ICatalogueRaisonneService;
@Controller
@RequestMapping("catalogueRaisonne")
public class AjaxCatalogueRaisonneController extends BaseCatalogueRaisonneController {
public AjaxCatalogueRaisonneController(ICatalogueRaisonneService catalogueRaisonneService) {
super(catalogueRaisonneService);
}
@PostMapping("/decennieSelect/{decennieDep}") //params=
public ModelAndView onDecennieSelect(@ModelAttribute("catalogueRaisonneForm") CatalogueRaisonneForm catalogueRaisonneForm,
@PathVariable("decennieDep") String decennie, final BindingResult bindingResult, final ModelMap model) {
List<String> years = catalogueRaisonneService.getYearsByDecennie(decennie);
ModelAndView modelAndView = new ModelAndView("catalogueRaisonne-years-frag::frag");
/* On nettoie la liste si jamais elle existe déja */
if(catalogueRaisonneForm.getYears() != null && !catalogueRaisonneForm.getYears().isEmpty()) {
catalogueRaisonneForm.getYears().clear();
}
catalogueRaisonneForm.setYears(years);
catalogueRaisonneForm.setSelectedDecennie(decennie);
modelAndView.addObject("years", getYears(catalogueRaisonneForm));
return modelAndView;
}
@GetMapping("/decennieSelect")
public ModelAndView fetch2() {
ModelAndView modelAndView = new ModelAndView("catalogueRaisonne-years-frag::frag");
return modelAndView;
}
} |
et enfin, le js:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function doAjax(){
console.log('Je rentre dans la seconde fonction JS');
console.log('le name vaut : ' + event.target.id);
const decennie = event.target.name;
const anneeDepart = decennie.substring(0,4);
console.log(anneeDepart);
$.ajax({
type:'POST',
url:'catalogueRaisonne/decennieSelect/' + decennie,
success: function(response){ //data
$("#resultsBlock").replaceWith(response);
},
error: function(exception){
alert('Exeption : ' + exception);
}
});
}; |
Lorsque j'arrive sur ma page (controller non ajax), j'ai bien ma liste de décennies qui s'affiche. Quand je clique pour la première fois sur l'un des boutons, par exemple "1970-1979", mon fragment se charge avec les bonnes données et m'affiche ce que je souhaite dans ma div. Mais si je clique sur une autre décennie, par exemple "1990-1999", les données envoyées sont bonnes mais les années affichées restent les même. Je n'arrive pas à afficher les nouvelles données dans la div. Quelqu'un aurait-il une idée de ce qu'il se passe?
Je me demande s'il ne faudrait pas ajouter des "input en "type='hidden'", mais je ne sais pas trop comment les mettre. Je suis ouvert à toute suggestion!