Commit 05c673c5 by Patryk Czarnik

Edycja produktu z walidacją w formularzu

parent 88e70a7a
......@@ -7,13 +7,16 @@ import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttribute;
import jakarta.validation.Valid;
import sklep.basket.Basket;
import sklep.model.Product;
import sklep.repository.ProductRepository;
......@@ -82,7 +85,7 @@ public class ProductController {
}
@GetMapping("/new")
public String nowyProdukt() {
public String nowyProdukt(@ModelAttribute Product product) {
return "product_form";
}
......@@ -99,9 +102,33 @@ public class ProductController {
}
@PostMapping({"/new", "/{id}/edit"})
public String zapiszProdukt(Product product) {
productRepository.save(product);
return "product_form";
// Ta metoda zapisuje dane przysłane z formularza obojętnie, czy to było edit, czy new
// Adnotacja @Valid powoduje, że Spring dokona walidacji obiektu PRZED uruchomieniem tej metody.
// Jeśli nie ma dodatkowego parametru BindingResult, a są błędy walidacji, to Spring naszej metody w ogóle nie uruchomi.
// Jeśli jednak metoda ma parametr BindingResult, to
// metoda zawsze jest uruchamiana przez Springa,
// a w tym parametrze zawarte są informacje o przebiegu walidacji, w tym błędy.
// Bez adnotacji @ModelAttribute też działało
public String saveProduct(@ModelAttribute @Valid Product product,
BindingResult bindingResult) {
// W tej wersji dane z wypełnionego formularza odbieramy w postaci jednego obiektu Product.
// Spring sam wpisze dane do pól o takich samych nazwach.
// Taki parametr od razu staje się częścią modelu (to jest tzw. ModelAttribute)
if(bindingResult.hasErrors()) {
System.err.println("Są błędy: " + bindingResult.getAllErrors());
// normalnie wyświetlilibyśmy coś na stronie...
// ale robi to za nas tag f:form i f:errors
// Dopóki są błędy, pozostajemy na stronie formularza.
return "product_form";
} else {
// Gdy podczas próby zapisu (operacja save) obiekt nie spełnia warunków walidacji, to jest wyrzucany wyjątek.
System.out.println("id przed zapisem: " + product.getId());
productRepository.save(product);
System.out.println("id po zapisie: " + product.getId());
return "redirect:/products";
// Po zaakceptowaniu danych, klient jest przenoszony do listy produktów.
}
}
@GetMapping(produces="text/plain")
......
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="jakarta.tags.core"%>
<%@taglib prefix="f" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Edycja danych produktu</title>
<link rel="stylesheet" type="text/css" href="/styl.css">
<meta charset="UTF-8">
<title>Edycja danych produktu</title>
<link rel="stylesheet" type="text/css" href="/styl.css">
</head>
<body>
<h1>Edycja produktu</h1>
<form id="product-form" method="post">
<table class="form">
<tr>
<td><label for="productId">Numer:</label></td>
<td><input id="productId" name="id" placeholder="brak"
type="number" readonly="readonly" value="${product.id}" /></td>
</tr>
<tr>
<td><label for="productName">Nazwa towaru:</label></td>
<td><input id="productName" name="productName"
placeholder="nazwa..." type="text" value="${product.productName}" />
</td>
</tr>
<tr>
<td><label for="price">Cena:</label></td>
<td><input id="price" name="price" placeholder="12.90"
title="tu wpisz cenę" type="number" step="0.01"
value="${product.price}" /></td>
</tr>
<tr>
<td><label for="vat">Stawka VAT:</label></td>
<td><input id="vat" name="vat" placeholder="0.23"
title="tu wpisz vat" type="number" step="0.01"
value="${product.vat}" /></td>
</tr>
<tr>
<td><label for="description">Opis:</label></td>
<td><textarea id="description" name="description" rows="10"
cols="120">${product.description}</textarea></td>
</tr>
<tr>
<td><button>Zapisz</button></td>
</tr>
</table>
</form>
<div class="action">
<a href="/products">powrót do listy produktów</a>
</div>
<div class="action">
<a href="/">powrót do spisu treści</a>
</div>
<c:choose>
<c:when test="${not empty(product.id)}">
<h1>Edycja produktu nr ${product.id}</h1>
</c:when>
<c:otherwise>
<h1>Edycja nowego produktu</h1>
</c:otherwise>
</c:choose>
<f:form id="product-form" method="post" modelAttribute="product">
<table class="form-tab">
<tr>
<td><f:label path="id">Numer:</f:label></td>
<td><f:input path="id" placeholder="brak" type="number" readonly="true"/></td>
</tr>
<tr>
<td><f:label path="productName">Nazwa towaru:</f:label></td>
<td><f:input path="productName" placeholder="nazwa..." type="text"/>
<f:errors path="productName" element="div" cssClass="form-error"/>
</td>
</tr>
<tr>
<td><f:label path="price">Cena:</f:label></td>
<td><f:input path="price" placeholder="12.90" type="number" step="0.01"/>
<f:errors path="price" element="div" cssClass="form-error"/>
</td>
</tr>
<tr>
<td><f:label path="vat">Stawka VAT:</f:label></td>
<td><f:input path="vat" placeholder="0.23" type="number" step="0.01"/>
<f:errors path="vat" element="div" cssClass="form-error"/>
</td>
</tr>
<tr>
<td><f:label path="description">Opis:</f:label></td>
<td><f:textarea path="description" rows="10"/></td>
</tr>
<tr>
<td><f:button>Zapisz</f:button></td>
</tr>
</table>
</f:form>
<div><a class="action" href="/products">powrót do listy produktów</a></div>
<div><a class="action" href="/">powrót do spisu treści</a></div>
</body>
</html>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment