lab 5 main part

This commit is contained in:
parap 2023-05-01 23:05:23 +04:00
parent efd20a1796
commit c7b8f30077
10 changed files with 519 additions and 3 deletions

Binary file not shown.

View File

@ -0,0 +1,52 @@
package ru.ip.labs.labs.films.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ip.labs.labs.films.dto.ActorDTO;
import ru.ip.labs.labs.films.service.ActorService;
import javax.validation.Valid;
@Controller
@RequestMapping("/actor")
public class ActorMvcController {
private ActorService actorService;
public ActorMvcController(ActorService actorService) {
this.actorService = actorService;
}
@GetMapping
public String getActors(Model model) {
model.addAttribute("actors",
actorService.findAllActors().stream()
.map(ActorDTO::new).toList());
model.addAttribute("actorDTO", new ActorDTO());
return "actors-catalog";
}
@PostMapping(value = {"", "/{id}"})
public String saveActor(@PathVariable(required = false) Long id,
@ModelAttribute @Valid ActorDTO actorDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "actors-catalog";
}
if (id == null || id <= 0) {
actorService.addActor(actorDTO.getName(), actorDTO.getSurname());
} else {
actorService.updateActor(id, actorDTO.getName(), actorDTO.getSurname());
}
return "redirect:/actor";
}
@PostMapping("/delete/{id}")
public String deleteGenre(@PathVariable Long id) {
actorService.deleteActor(id);
return "redirect:/actor";
}
}

View File

@ -0,0 +1,70 @@
package ru.ip.labs.labs.films.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ip.labs.labs.films.dto.FilmDTO;
import ru.ip.labs.labs.films.models.Film;
import ru.ip.labs.labs.films.service.ActorService;
import ru.ip.labs.labs.films.service.FilmsService;
import ru.ip.labs.labs.films.service.GenreService;
import javax.validation.Valid;
@Controller
@RequestMapping("/film")
public class FilmMvcController {
private FilmsService filmService;
private GenreService genreService;
private ActorService actorService;
public FilmMvcController(FilmsService filmService, GenreService genreService, ActorService actorService) {
this.filmService = filmService;
this.genreService = genreService;
this.actorService = actorService;
}
@GetMapping
public String getFilms(Model model) {
model.addAttribute("films",
filmService.findAllFilms().stream()
.map(FilmDTO::new).toList());
model.addAttribute("filmDTO", new FilmDTO());
model.addAttribute("allGenres",
genreService.findAllGenres().stream()
.map(g -> g.getName()).toList());
model.addAttribute("allActors",
actorService.findAllActors().stream()
.map(a -> a.getName() + " " + a.getSurname()).toList());
return "films-catalog";
}
@PostMapping(value = {"", "/{id}"})
public String saveFilm(@PathVariable(required = false) Long id,
@ModelAttribute @Valid FilmDTO filmDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "films-catalog";
}
Long filmId = filmDTO.getId();
if (id == null || id <= 0) {
Film result = filmService.addFilm(filmDTO.getName());
filmId = result.getId();
} else {
filmService.updateFilm(id, filmDTO.getName());
}
filmService.updateGenres(filmId, filmDTO.getGenre());
filmService.updateActors(filmId, filmDTO.getFullNames());
return "redirect:/film";
}
@PostMapping("/delete/{id}")
public String deleteGenre(@PathVariable Long id) {
filmService.deleteFilm(id);
return "redirect:/film";
}
}

View File

@ -0,0 +1,52 @@
package ru.ip.labs.labs.films.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ip.labs.labs.films.dto.GenreDTO;
import ru.ip.labs.labs.films.service.GenreService;
import javax.validation.Valid;
@Controller
@RequestMapping("/genre")
public class GenreMvcController {
private GenreService genreService;
public GenreMvcController(GenreService genreService) {
this.genreService = genreService;
}
@GetMapping
public String getGenres(Model model) {
model.addAttribute("genres",
genreService.findAllGenres().stream()
.map(GenreDTO::new).toList());
model.addAttribute("genreDTO", new GenreDTO());
return "genres-catalog";
}
@PostMapping(value = {"", "/{id}"})
public String saveGenre(@PathVariable(required = false) Long id,
@ModelAttribute @Valid GenreDTO genreDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "genres-catalog";
}
if (id == null || id <= 0) {
genreService.addGenre(genreDTO.getName());
} else {
genreService.updateGenre(id, genreDTO.getName());
}
return "redirect:/genre";
}
@PostMapping("/delete/{id}")
public String deleteGenre(@PathVariable Long id) {
genreService.deleteGenre(id);
return "redirect:/genre";
}
}

View File

@ -52,10 +52,18 @@ public class FilmDTO {
return fullNames;
}
public void setFullNames(List<String> fullNames) {
this.fullNames = fullNames;
}
public List<String> getGenre() {
return genre;
}
public void setGenre(List<String> genre) {
this.genre = genre;
}
@Override
public String toString() {
String res = "\nFilm{" +

View File

@ -0,0 +1,3 @@
.selected {
background: #2150de;
}

View File

@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="/css/Table.css">
</head>
<body>
<div layout:fragment="content">
<div class="m-3">
<div class="btn-group">
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-success" id="addBtn">Добавить</button>
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-info" id="editBtn">Изменить</button>
<button class="btn btn-danger" id="deleteBtn">Удалить</button>
</div>
<table class="table table-hover" id="table">
<thead>
<tr>
<th>#</th>
<th>Имя</th>
<th>Фамилия</th>
</tr>
</thead>
<tbody>
<tr th:each="actor, iterator: ${actors}" th:attr="onclick=|selectRow(${iterator.index})|" th:id="${actor.id}">
<!-- th:attr="onclick=|selectRow(1)"-->
<td th:text="${iterator.index} + 1"></td>
<td th:text="${actor.name}"></td>
<td th:text="${actor.surname}"></td>
</tr>
</tbody>
</table>
<div class="modal fade" tabIndex="-1" id="edit-modal"><!-- style={{ display: props.visible ? 'block' : 'none' }}-->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Добавление</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть" onClick={props.closeHandler}></button>
</div>
<form class="modal-body" method="post" id="edit-form">
<div class="mb-3">
<label htmlFor="genre" class="form-label">Имя</label>
<input type="text" th:field="${actorDTO.name}" name="name" class="form-control" required autoComplete="off">
</div>
<div class="mb-3">
<label htmlFor="genre" class="form-label">Фамилия</label>
<input type="text" th:field="${actorDTO.surname}" name="surname" class="form-control" required autoComplete="off">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="closeBtn" data-bs-dismiss="modal">Закрыть</button>
<button class="btn btn-primary" id="submitBtn" type="submit">Добавить</button>
</div>
</form>
</div>
</div>
</div>
</div>
<form method="post" style="display: none" id="delete-form">
</form>
</div>
<th:block layout:fragment="scripts">
<script>
let table = document.getElementById("table");
let addBtn = document.getElementById("addBtn");
let editBtn = document.getElementById("editBtn");
let deleteBtn = document.getElementById("deleteBtn");
let submitBtn = document.getElementById("submitBtn");
let closeBtn = document.getElementById("closeBtn");
let editForm = document.getElementById("edit-form");
let deleteForm = document.getElementById("delete-form");
let selectRow = (index) => {
table.children[1].children[index].classList.toggle("selected");
}
addBtn.onclick = () => {
editForm.action = "/actor";
editForm.previousElementSibling.children[0].textContent = "Добавление";
editForm.children[1].children[1].textContent = "Добавить";
}
editBtn.onclick = () => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
setTimeout(() => {
closeBtn.click();
}, 500);
return;
}
editForm.action = "/actor/" + elem.id;
editForm.previousElementSibling.children[0].textContent = "Изменение";
submitBtn.textContent = "Изменить";
editForm.name.value = elem.children[1].textContent;
}
deleteBtn.onclick = () => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
return;
}
deleteForm.action = "/actor/delete/" + elem.id;
deleteForm.submit();
}
</script>
</th:block>
</body>
</html>

View File

@ -6,9 +6,9 @@
</head>
<body>
<div layout:fragment="content">
<a href="/filmsCatalog" class="btn btn-success mt-1">фильмы</a>
<a href="/genresCatalog" class="btn btn-success mt-1">жанры</a>
<a href="/actorsCatalog" class="btn btn-success mt-1">актеры</a>
<a href="/film" class="btn btn-success mt-1">фильмы</a>
<a href="/genre" class="btn btn-success mt-1">жанры</a>
<a href="/actor" class="btn btn-success mt-1">актеры</a>
</div>
</body>
</html>

View File

@ -0,0 +1,120 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="/css/Table.css">
</head>
<body>
<div layout:fragment="content">
<div class="m-3">
<div class="btn-group">
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-success" id="addBtn">Добавить</button>
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-info" id="editBtn">Изменить</button>
<button class="btn btn-danger" id="deleteBtn">Удалить</button>
</div>
<table class="table table-hover" id="table">
<thead>
<tr>
<th>#</th>
<th>Название</th>
<th>Жанры</th>
<th>Актеры</th>
</tr>
</thead>
<tbody>
<tr th:each="film, iterator: ${films}" th:attr="onclick=|selectRow(${iterator.index})|" th:id="${film.id}">
<!-- th:attr="onclick=|selectRow(1)"-->
<td th:text="${iterator.index} + 1"></td>
<td th:text="${film.name}"></td>
<td th:text="${#strings.arrayJoin(film.genre ,', ')}"></td>
<td th:text="${#strings.arrayJoin(film.fullNames ,', ')}"></td>
</tr>
</tbody>
</table>
<div class="modal fade" tabIndex="-1" id="edit-modal"><!-- style={{ display: props.visible ? 'block' : 'none' }}-->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Добавление</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть" onClick={props.closeHandler}></button>
</div>
<form class="modal-body" method="post" id="edit-form">
<div class="mb-3">
<label htmlFor="nameInput" class="form-label">Название</label>
<input id="nameInput" type="text" th:field="${filmDTO.name}" name="name" class="form-control" required autoComplete="off">
</div>
<select name="genre" class="form-select" th:field="${filmDTO.genre}" multiple="multiple">
<option th:each="g : ${allGenres}"
th:value="${g}"
th:text="${g}"></option>
</select>
<select name="fullNames" class="form-select" th:field="${filmDTO.fullNames}" multiple="multiple">
<option th:each="a : ${allActors}"
th:value="${a}"
th:text="${a}"></option>
</select>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="closeBtn" data-bs-dismiss="modal">Закрыть</button>
<button class="btn btn-primary" id="submitBtn" type="submit">Добавить</button>
</div>
</form>
</div>
</div>
</div>
</div>
<form method="post" style="display: none" id="delete-form">
</form>
</div>
<th:block layout:fragment="scripts">
<script>
let table = document.getElementById("table");
let addBtn = document.getElementById("addBtn");
let editBtn = document.getElementById("editBtn");
let submitBtn = document.getElementById("submitBtn");
let closeBtn = document.getElementById("closeBtn");
let editForm = document.getElementById("edit-form");
let deleteForm = document.getElementById("delete-form");
let selectRow = (index) => {
table.children[1].children[index].classList.toggle("selected");
}
addBtn.onclick = (e) => {
editForm.action = "/film";
editForm.previousElementSibling.children[0].textContent = "Добавление";
editForm.children[1].children[1].textContent = "Добавить";
}
editBtn.onclick = (e) => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
setTimeout(() => {
closeBtn.click();
}, 500);
return;
}
editForm.action = "/film/" + elem.id;
editForm.previousElementSibling.children[0].textContent = "Изменение";
submitBtn.textContent = "Изменить";
editForm.name.value = elem.children[1].textContent;
let genresArr = elem.children[2].textContent.split(", ");
for(let opt of editForm.genre.options) {
if(genresArr.indexOf(opt.value) != -1) opt.selected = true;
}
}
deleteBtn.onclick = () => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
return;
}
deleteForm.action = "/film/delete/" + elem.id;
deleteForm.submit();
}
</script>
</th:block>
</body>
</html>

View File

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="/css/Table.css">
</head>
<body>
<div layout:fragment="content">
<div class="m-3">
<div class="btn-group">
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-success" id="addBtn">Добавить</button>
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-info" id="editBtn">Изменить</button>
<button class="btn btn-danger" id="deleteBtn">Удалить</button>
</div>
<table class="table table-hover" id="table">
<thead>
<tr>
<th>#</th>
<th>Жанр</th>
</tr>
</thead>
<tbody>
<tr th:each="genre, iterator: ${genres}" th:attr="onclick=|selectRow(${iterator.index})|" th:id="${genre.id}">
<!-- th:attr="onclick=|selectRow(1)"-->
<td th:text="${iterator.index} + 1"></td>
<td th:text="${genre.name}"></td>
</tr>
</tbody>
</table>
<div class="modal fade" tabIndex="-1" id="edit-modal"><!-- style={{ display: props.visible ? 'block' : 'none' }}-->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Добавление</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть" onClick={props.closeHandler}></button>
</div>
<form class="modal-body" method="post" id="edit-form">
<div class="mb-3">
<label htmlFor="genre" class="form-label">Название</label>
<input type="text" th:field="${genreDTO.name}" name="name" class="form-control" required autoComplete="off">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="closeBtn" data-bs-dismiss="modal">Закрыть</button>
<button class="btn btn-primary" id="submitBtn" type="submit">Добавить</button>
</div>
</form>
</div>
</div>
</div>
</div>
<form method="post" style="display: none" id="delete-form">
</form>
</div>
<th:block layout:fragment="scripts">
<script>
let table = document.getElementById("table");
let addBtn = document.getElementById("addBtn");
let editBtn = document.getElementById("editBtn");
let submitBtn = document.getElementById("submitBtn");
let closeBtn = document.getElementById("closeBtn");
let editForm = document.getElementById("edit-form");
let deleteForm = document.getElementById("delete-form");
let selectRow = (index) => {
table.children[1].children[index].classList.toggle("selected");
}
addBtn.onclick = (e) => {
editForm.action = "/genre";
editForm.previousElementSibling.children[0].textContent = "Добавление";
editForm.children[1].children[1].textContent = "Добавить";
}
editBtn.onclick = (e) => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
setTimeout(() => {
closeBtn.click();
}, 500);
return;
}
editForm.action = "/genre/" + elem.id;
editForm.previousElementSibling.children[0].textContent = "Изменение";
submitBtn.textContent = "Изменить";
editForm.name.value = elem.children[1].textContent;
}
deleteBtn.onclick = () => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
return;
}
deleteForm.action = "/genre/delete/" + elem.id;
deleteForm.submit();
}
</script>
</th:block>
</body>
</html>