Wspólna walidacja pól tekstowych i list rozwijanych

0

Mam problem z walidacją formularza. Formularz składa się z pól tekstowych i list rozwijanych. Listy rozwijane mają początkowo już jakąś wartość więc one nigdy nie będą puste (nie podlegają walidacji) i teraz jak walidacja nie przechodzi pomyślnie na polach tekstowych to znikają opcje list rozwijanych i zostaje puste pole, natomiast po poprawieniu błędów w polach tekstowych formularza nie da się przesłać dalej, bo listy rozwijane są puste i po prostu odświeża stronę bez możliwości pójścia dalej i zapisania danych z formularza.

u jest plik html

<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org" th:replace="~{layout :: template (~{:: .uk-section})}">
<head>
</head>
<body>

<div class="uk-section">
    <div class="uk-container uk-container-small">
        <h1 class="uk-heading-bullet">Kalkulator</h1>

        <form class="uk-form-horizontal uk-margin-large" action="#" th:action="@{select-equipment}"
              th:object="${selectEquipment}" method="post">

            <div class="uk-margin">
                <label class="uk-form-label">Kontrahent:</label>
                <div class="uk-form-controls">
                    <input class="uk-input uk-form-width-large valid" type="text" th:field="*{clientName}"
                           placeholder="Wpisz nazwę kontrahenta" th:errorclass="uk-form-danger" required>
                    <div th:if="${#fields.hasErrors('clientName')}"
                         class="uk-form-width-large uk-text-small uk-text-danger">
                        Nazwa kontrahenta powinna mieć minimum 3 znaki
                    </div>
                </div>
            </div>

            <div class="uk-margin">
                <label class="uk-form-label">Ilość mikropali:</label>
                <div class="uk-form-controls">
                    <input class="uk-input uk-form-width-large" type="number" th:field="*{pilesQuantity}"
                           placeholder="Wpisz liczbę całkowitą" th:errorclass="uk-form-danger" required>
                    <div th:if="${#fields.hasErrors('pilesQuantity')}" class="uk-text-small uk-text-danger">
                        Wpisz liczbę całkowitą większą od 1
                    </div>
                </div>
            </div>

            <div class="uk-margin">
                <label class="uk-form-label">Głębokość mikropali:</label>
                <div class="uk-form-controls">
                    <input class="uk-input uk-form-width-large" type="number" th:field="*{depth}"
                           placeholder="Wpisz liczbę metrów" th:errorclass="uk-form-danger" required>
                    <div th:if="${#fields.hasErrors('depth')}" class="uk-text-small uk-text-danger">
                        Wpisz liczbę całkowitą w zakresie od 1 do 30
                    </div>
                </div>
            </div>

            <div class="uk-margin">
                <label class="uk-form-label">Wymagana nośność obliczeniowa [kN]:</label>
                <div class="uk-form-controls">
                    <input class="uk-input uk-form-width-large" type="number" th:field="*{capacity}"
                           placeholder="Wpisz liczbę całkowitą" th:errorclass="uk-form-danger" required>
                    <div th:if="${#fields.hasErrors('capacity')}" class="uk-text-small uk-text-danger">
                        Wpisz liczbę całkowitą większą od 1
                    </div>
                </div>
            </div>

            <div class="uk-margin">
                <label class="uk-form-label">Długość pojedynczej żerdzi:</label>
                <div class="uk-form-controls">
                    <select class="uk-select uk-form-width-large" th:field="*{singleBarLength}"
                            th:errorclass="uk-form-danger">
                        <option th:each="singleBarLength : ${barLengths}"
                                th:value="${singleBarLength}"
                                th:text="|${singleBarLength} m|"></option>
                    </select>
                    <div th:if="${#fields.hasErrors()}" class="uk-hidden">
                    </div>
                </div>
            </div>

            <div class="uk-margin">
                <label class="uk-form-label">Ilość wymaganych nakrętek:</label>
                <div class="uk-form-controls">
                    <select class="uk-select uk-form-width-large" th:field="*{nutsQuantity}"
                            th:errorclass="uk-form-danger">
                        <option th:each="nutsQuantity : ${nutsQuantity}"
                                th:value="${nutsQuantity}"
                                th:text="${nutsQuantity} "></option>
                    </select>
                    <div th:if="${#fields.hasErrors()}" class="uk-hidden">
                    </div>
                </div>
            </div>

            <div class="uk-margin">
                <label class="uk-form-label">Typ nakrętki:</label>
                <div class="uk-form-controls">
                    <select class="uk-select uk-form-width-large" th:field="*{nutType}">
                        <option th:each="nutType : ${nutType}"
                                th:value="${nutType}"
                                th:text="${nutType} "></option>
                    </select>
                </div>
            </div>

            <div class="uk-margin">
                <label class="uk-form-label">Ilość wymaganych płyt oporowych:</label>
                <div class="uk-form-controls">
                    <select class="uk-select uk-form-width-large" th:field="*{platesQuantity}">
                        <option th:each="platesQuantity : ${platesQuantity}"
                                th:value="${platesQuantity}"
                                th:text="${platesQuantity} "></option>
                    </select>
                </div>
            </div>

            <div class="uk-margin">
                <label class="uk-form-label">Rozmiar płyty oporowej:</label>
                <div class="uk-form-controls">
                    <select class="uk-select uk-form-width-large" th:field="*{plateSize}"
                            th:errorclass="uk-form-danger">
                        <option th:each="plateSize : ${plateSize}"
                                th:value="${plateSize}"
                                th:text="${plateSize} "></option>
                    </select>
                </div>
            </div>

            <div class="uk-width-1-1">
                <input type="submit" class="uk-button uk-button-secondary uk-width-1-1" value="Oblicz">

            </div>
        </form>

    </div>
</div>

</body>
</html>

Tak wygląda kontroler

@GetMapping("select-equipment")
public String showSelectEquipmentPage(Model model) {
    model.addAttribute("selectEquipment", new SelectEquipment());
    Double[] barLengths = {1.0, 1.5, 2.0, 3.0, 4.0, 6.0};
    model.addAttribute("barLengths", barLengths);
    Integer[] nutsQuantity = {1, 2};
    model.addAttribute("nutsQuantity", nutsQuantity);
    String[] nutType = {"Nakrętka kulista", "Nakrętka kulista galv", "Nakrętka HEX", "Nakrętka HEX galv"};
    model.addAttribute("nutType", nutType);
    Integer[] platesQuantity = {1, 2};
    model.addAttribute("platesQuantity", platesQuantity);
    String[] plateSize = {"150x150x8", "150x150x10", "200x200x10", "200x200x20", "200x200x25", "250x250x20", "250x250x25", "250x250x30"};
    model.addAttribute("plateSize", plateSize);
    return "selectEquipment";
}

@PostMapping("select-equipment")
public String createEquipment(@ModelAttribute("selectEquipment") @Valid SelectEquipmentModel selectEquipment,
                              BindingResult bindingResult,
                              @ModelAttribute("equipment") EquipmentModel equipment,
                              RedirectAttributes attributes,
                              Model model) {


    if (bindingResult.hasErrors()) {

        return "selectEquipment";
    }

    selectEquipmentService.saveSelectEquipment(selectEquipment);
    attributes.addFlashAttribute("selectEquipment", selectEquipment);


    model.addAttribute("equipment", new Equipment());
    Bar bar = barService.chooseBar(selectEquipment);
    equipment.setBar(bar);
    int barsQuantity = barService.countQuantityOfBars(selectEquipment);
    equipment.setBarsQuantity(barsQuantity);
    Coupling coupling = couplingService.chooseCoupling(bar);
    equipment.setCoupling(coupling);
    int couplingsQuantity = barService.countQuantityOfCouplings(barsQuantity);
    equipment.setCouplingsQuantity(couplingsQuantity);
    Nut nut = nutService.chooseNut(selectEquipment, bar);
    equipment.setNut(nut);
    Plate plate = plateDao.findPlateBySize(selectEquipment.getPlateSize());
    equipment.setPlate(plate);

    equipmentService.saveEquipment(equipment);
    attributes.addFlashAttribute("equipment", equipment);

    return "redirect:/selected-equipment";
}

A tu jest model

@NotEmpty(message = "To pole nie może być puste")
@Size(min=3)
private String clientName;
@NotNull(message = "To pole nie może być puste")
@Min(1)
private Integer pilesQuantity;
@NotNull(message = "To pole nie może być puste")
@Min(1)
@Max(30)
private Double depth;
@NotNull(message = "To pole nie może być puste")
@Min(1)
private Double capacity;
private Double singleBarLength;
private Integer nutsQuantity;
private String nutType;
private Integer platesQuantity;
private String plateSize;
2

Thymeleaf w Springu już czas temu zszedł na (optymistycznie) drugi plan, sądzę że nikt nad tym nie ślęczy, mały nacisk na rozwój, testy.
Projekty z wizarda nie bardzo chodzą, tzreba korygować itd...

Walidacja robiona przez kontener ma pewne quirk'i i potrafię uwierzyć, że źle się sprzęga z robieniem form przez w/w. Trzeba by analizować jak to gania na HTTP

1 użytkowników online, w tym zalogowanych: 0, gości: 1