mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-17 04:55:50 +00:00
Assignment Changes added for same.
Assignment completed to committed the changes.
This commit is contained in:
parent
1b6436f80e
commit
456a13430e
14 changed files with 402 additions and 1 deletions
|
@ -30,6 +30,7 @@ import jakarta.persistence.FetchType;
|
||||||
import jakarta.persistence.JoinColumn;
|
import jakarta.persistence.JoinColumn;
|
||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.persistence.OneToMany;
|
import jakarta.persistence.OneToMany;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
import jakarta.persistence.OrderBy;
|
import jakarta.persistence.OrderBy;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
@ -57,6 +58,21 @@ public class Pet extends NamedEntity {
|
||||||
@JoinColumn(name = "pet_id")
|
@JoinColumn(name = "pet_id")
|
||||||
@OrderBy("date ASC")
|
@OrderBy("date ASC")
|
||||||
private final Set<Visit> visits = new LinkedHashSet<>();
|
private final Set<Visit> visits = new LinkedHashSet<>();
|
||||||
|
|
||||||
|
@OneToOne(mappedBy ="pet",cascade = CascadeType.ALL)
|
||||||
|
private PetAttribute petAttribute;
|
||||||
|
|
||||||
|
@ManyToOne(fetch=FetchType.LAZY)
|
||||||
|
@JoinColumn(name="owner_id")
|
||||||
|
private Owner owner;
|
||||||
|
|
||||||
|
public Owner getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOwner(Owner owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
public void setBirthDate(LocalDate birthDate) {
|
public void setBirthDate(LocalDate birthDate) {
|
||||||
this.birthDate = birthDate;
|
this.birthDate = birthDate;
|
||||||
|
@ -82,4 +98,13 @@ public class Pet extends NamedEntity {
|
||||||
getVisits().add(visit);
|
getVisits().add(visit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PetAttribute getPetAttribute() {
|
||||||
|
return petAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPetAttribute(PetAttribute petAttribute) {
|
||||||
|
this.petAttribute = petAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
|
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table (name="pet_attributes")
|
||||||
|
public class PetAttribute extends BaseEntity{
|
||||||
|
|
||||||
|
|
||||||
|
@OneToOne
|
||||||
|
@JoinColumn(name="pet_id")
|
||||||
|
private Pet pet;
|
||||||
|
|
||||||
|
//@NotBlank(message="Temperament is required")
|
||||||
|
private String temperament;
|
||||||
|
|
||||||
|
private Double length;
|
||||||
|
|
||||||
|
private Double weight;
|
||||||
|
|
||||||
|
public Pet getPet() {
|
||||||
|
return pet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPet(Pet pet) {
|
||||||
|
this.pet = pet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTemperament() {
|
||||||
|
return temperament;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTemperament(String temperament) {
|
||||||
|
this.temperament = temperament;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLength(Double length) {
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getWeight() {
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeight(Double weight) {
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -95,12 +95,15 @@ class PetController {
|
||||||
@GetMapping("/pets/new")
|
@GetMapping("/pets/new")
|
||||||
public String initCreationForm(Owner owner, ModelMap model) {
|
public String initCreationForm(Owner owner, ModelMap model) {
|
||||||
Pet pet = new Pet();
|
Pet pet = new Pet();
|
||||||
|
PetAttribute petAttribute= new PetAttribute();
|
||||||
|
pet.setPetAttribute(petAttribute);
|
||||||
|
pet.getPetAttribute().setPet(pet);
|
||||||
owner.addPet(pet);
|
owner.addPet(pet);
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/pets/new")
|
@PostMapping("/pets/new")
|
||||||
public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result,
|
public String processCreationForm(Owner owner, @Valid Pet pet,BindingResult result,
|
||||||
RedirectAttributes redirectAttributes) {
|
RedirectAttributes redirectAttributes) {
|
||||||
|
|
||||||
if (StringUtils.hasText(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null)
|
if (StringUtils.hasText(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null)
|
||||||
|
@ -116,6 +119,7 @@ class PetController {
|
||||||
}
|
}
|
||||||
|
|
||||||
owner.addPet(pet);
|
owner.addPet(pet);
|
||||||
|
pet.getPetAttribute().setPet(pet);
|
||||||
this.owners.save(owner);
|
this.owners.save(owner);
|
||||||
redirectAttributes.addFlashAttribute("message", "New Pet has been Added");
|
redirectAttributes.addFlashAttribute("message", "New Pet has been Added");
|
||||||
return "redirect:/owners/{ownerId}";
|
return "redirect:/owners/{ownerId}";
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
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.RequestParam;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class PetViewController {
|
||||||
|
|
||||||
|
private final PetViewRepository petViewRepository;
|
||||||
|
|
||||||
|
public PetViewController(PetViewRepository petViewRepository) {
|
||||||
|
this.petViewRepository = petViewRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ModelAttribute("pet")
|
||||||
|
public Pet findPet(@PathVariable(name = "petId", required = false) Integer petId) {
|
||||||
|
return petId == null ? new Pet()
|
||||||
|
: this.petViewRepository.findById(petId)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Pet not found with id: " + petId
|
||||||
|
+ ". Please ensure the ID is correct " + "and the pet exists in the database."));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/pets/find")
|
||||||
|
public String initFindForm() {
|
||||||
|
return "pets/findPets";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/pets")
|
||||||
|
public String processFindForm(@RequestParam(defaultValue = "1") int page, Pet pet, BindingResult result,
|
||||||
|
Model model) {
|
||||||
|
// allow parameterless GET request for /pets to return all records
|
||||||
|
if (pet.getName() == null) {
|
||||||
|
pet.setName(""); // empty string signifies broadest possible search
|
||||||
|
}
|
||||||
|
|
||||||
|
// find owners by last name
|
||||||
|
Page<Pet> petsResults = findPaginatedForPetsName(page, pet.getName());
|
||||||
|
if (petsResults.isEmpty()) {
|
||||||
|
// no owners found
|
||||||
|
result.rejectValue("Name", "notFound", "not found");
|
||||||
|
return "pets/findPets";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (petsResults.getTotalElements() == 1) {
|
||||||
|
// 1 owner found
|
||||||
|
pet = petsResults.iterator().next();
|
||||||
|
return "redirect:/pets/" + pet.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiple owners found
|
||||||
|
return addPaginationModel(page, model, petsResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String addPaginationModel(int page, Model model, Page<Pet> paginated) {
|
||||||
|
List<Pet> listPets = paginated.getContent();
|
||||||
|
model.addAttribute("currentPage", page);
|
||||||
|
model.addAttribute("totalPages", paginated.getTotalPages());
|
||||||
|
model.addAttribute("totalItems", paginated.getTotalElements());
|
||||||
|
model.addAttribute("listPets", listPets);
|
||||||
|
return "pets/petsList";
|
||||||
|
}
|
||||||
|
private Page<Pet> findPaginatedForPetsName(int page, String name) {
|
||||||
|
int pageSize = 5;
|
||||||
|
Pageable pageable = PageRequest.of(page - 1, pageSize);
|
||||||
|
return petViewRepository.findByNameStartingWith(name, pageable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/pets/{petId}")
|
||||||
|
public ModelAndView showPet(@PathVariable("petId") int petId) {
|
||||||
|
ModelAndView mav = new ModelAndView("pets/petDetails");
|
||||||
|
Optional<Pet> optionalPet = this.petViewRepository.findPetByWithOwnerAndAttribute(petId);
|
||||||
|
Pet pet = optionalPet.orElseThrow(() -> new IllegalArgumentException(
|
||||||
|
"Pet not found with id: " + petId + ". Please ensure the ID is correct "));
|
||||||
|
|
||||||
|
mav.addObject(pet);
|
||||||
|
mav.addObject(pet.getOwner());
|
||||||
|
//mav.addObject(pet.getPetAttribute());
|
||||||
|
return mav;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
|
public interface PetViewRepository extends JpaRepository<Pet, Integer>{
|
||||||
|
|
||||||
|
Page<Pet> findByNameStartingWith(String name, Pageable pageable);
|
||||||
|
|
||||||
|
|
||||||
|
@Query("SELECT p from Pet p LEFT JOIN FETCH p.owner LEFT JOIN FETCH p.petAttribute WHERE p.id= :id")
|
||||||
|
Optional<Pet> findPetByWithOwnerAndAttribute(@Param("id") int id);
|
||||||
|
}
|
|
@ -51,3 +51,8 @@ INSERT INTO visits VALUES (default, 7, '2013-01-01', 'rabies shot');
|
||||||
INSERT INTO visits VALUES (default, 8, '2013-01-02', 'rabies shot');
|
INSERT INTO visits VALUES (default, 8, '2013-01-02', 'rabies shot');
|
||||||
INSERT INTO visits VALUES (default, 8, '2013-01-03', 'neutered');
|
INSERT INTO visits VALUES (default, 8, '2013-01-03', 'neutered');
|
||||||
INSERT INTO visits VALUES (default, 7, '2013-01-04', 'spayed');
|
INSERT INTO visits VALUES (default, 7, '2013-01-04', 'spayed');
|
||||||
|
|
||||||
|
INSERT INTO pet_attributes VALUES (default,2,'Friendly',35.5,12.0);
|
||||||
|
INSERT INTO pet_attributes VALUES (default,9,'social',25.5,10.0);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ DROP TABLE visits IF EXISTS;
|
||||||
DROP TABLE pets IF EXISTS;
|
DROP TABLE pets IF EXISTS;
|
||||||
DROP TABLE types IF EXISTS;
|
DROP TABLE types IF EXISTS;
|
||||||
DROP TABLE owners IF EXISTS;
|
DROP TABLE owners IF EXISTS;
|
||||||
|
DROP TABLE pet_attributes IF EXISTS;
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE vets (
|
CREATE TABLE vets (
|
||||||
|
@ -62,3 +63,13 @@ CREATE TABLE visits (
|
||||||
);
|
);
|
||||||
ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id);
|
ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id);
|
||||||
CREATE INDEX visits_pet_id ON visits (pet_id);
|
CREATE INDEX visits_pet_id ON visits (pet_id);
|
||||||
|
|
||||||
|
CREATE TABLE pet_attributes(
|
||||||
|
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||||
|
pet_id INTEGER,
|
||||||
|
temperament VARCHAR(255),
|
||||||
|
length DOUBLE,
|
||||||
|
weight DOUBLE
|
||||||
|
);
|
||||||
|
ALTER TABLE pet_attributes ADD CONSTRAINT fk_pets_attribute FOREIGN KEY (pet_id) REFERENCES pets (id);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ owners=Owners
|
||||||
addOwner=Add Owner
|
addOwner=Add Owner
|
||||||
findOwner=Find Owner
|
findOwner=Find Owner
|
||||||
findOwners=Find Owners
|
findOwners=Find Owners
|
||||||
|
findPet=Find Pet
|
||||||
|
findPets=Find Pets
|
||||||
updateOwner=Update Owner
|
updateOwner=Update Owner
|
||||||
vets=Veterinarians
|
vets=Veterinarians
|
||||||
name=Name
|
name=Name
|
||||||
|
@ -42,7 +44,11 @@ new=New
|
||||||
addVisit=Add Visit
|
addVisit=Add Visit
|
||||||
editPet=Edit Pet
|
editPet=Edit Pet
|
||||||
ownerInformation=Owner Information
|
ownerInformation=Owner Information
|
||||||
|
petInformation=Pet Information
|
||||||
visitDate=Visit Date
|
visitDate=Visit Date
|
||||||
editOwner=Edit Owner
|
editOwner=Edit Owner
|
||||||
addNewPet=Add New Pet
|
addNewPet=Add New Pet
|
||||||
petsAndVisits=Pets and Visits
|
petsAndVisits=Pets and Visits
|
||||||
|
petAttributeWeight=Weight
|
||||||
|
petAttributeLength=Length
|
||||||
|
petAttributeTemp=Temperament
|
||||||
|
|
|
@ -48,6 +48,11 @@
|
||||||
<span th:text="#{findOwners}">Find owners</span>
|
<span th:text="#{findOwners}">Find owners</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li th:replace="~{::menuItem ('/pets/find','pets','find pets','search',#{findPets})}">
|
||||||
|
<span class="fa fa-search" aria-hidden="true"></span>
|
||||||
|
<span th:text="#{findPets}">Find pets</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li th:replace="~{::menuItem ('/vets.html','vets','veterinarians','th-list',#{vets})}">
|
<li th:replace="~{::menuItem ('/vets.html','vets','veterinarians','th-list',#{vets})}">
|
||||||
<span class="fa fa-th-list" aria-hidden="true"></span>
|
<span class="fa fa-th-list" aria-hidden="true"></span>
|
||||||
<span th:text="#{vets}">Veterinarians</span>
|
<span th:text="#{vets}">Veterinarians</span>
|
||||||
|
|
|
@ -54,6 +54,12 @@
|
||||||
<dd th:text="${#temporals.format(pet.birthDate, 'yyyy-MM-dd')}"></dd>
|
<dd th:text="${#temporals.format(pet.birthDate, 'yyyy-MM-dd')}"></dd>
|
||||||
<dt th:text="#{type}">Type</dt>
|
<dt th:text="#{type}">Type</dt>
|
||||||
<dd th:text="${pet.type}"></dd>
|
<dd th:text="${pet.type}"></dd>
|
||||||
|
<dt th:text="#{petAttributeTemp}">Temperament</dt>
|
||||||
|
<dd th:text="${pet.petAttribute != null ?pet.petAttribute.temperament: 'N/A'}"></dd>
|
||||||
|
<dt th:text="#{petAttributeLength}">Length</dt>
|
||||||
|
<dd th:text="${pet.petAttribute != null ?pet.petAttribute.length: 'N/A'}"></dd>
|
||||||
|
<dt th:text="#{petAttributeWeight}">Weight</dt>
|
||||||
|
<dd th:text="${pet.petAttribute != null ?pet.petAttribute.weight: 'N/A'}"></dd>
|
||||||
</dl>
|
</dl>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top">
|
<td valign="top">
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
<input th:replace="~{fragments/inputField :: input ('Name', 'name', 'text')}" />
|
<input th:replace="~{fragments/inputField :: input ('Name', 'name', 'text')}" />
|
||||||
<input th:replace="~{fragments/inputField :: input ('Birth Date', 'birthDate', 'date')}" />
|
<input th:replace="~{fragments/inputField :: input ('Birth Date', 'birthDate', 'date')}" />
|
||||||
<input th:replace="~{fragments/selectField :: select ('Type', 'type', ${types})}" />
|
<input th:replace="~{fragments/selectField :: select ('Type', 'type', ${types})}" />
|
||||||
|
<input th:replace="~{fragments/inputField :: input ('Temperament', 'petAttribute.temperament', 'text')}" />
|
||||||
|
<input th:replace="~{fragments/inputField :: input ('Length', 'petAttribute.length', 'text')}" />
|
||||||
|
<input th:replace="~{fragments/inputField :: input ('Weigth', 'petAttribute.weight', 'text')}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-offset-2 col-sm-10">
|
<div class="col-sm-offset-2 col-sm-10">
|
||||||
|
|
35
src/main/resources/templates/pets/findPets.html
Normal file
35
src/main/resources/templates/pets/findPets.html
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html xmlns:th="https://www.thymeleaf.org" th:replace="~{fragments/layout :: layout (~{::body},'pets')}">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h2 th:text="#{findPets}">Find Pets</h2>
|
||||||
|
|
||||||
|
<form th:object="${pet}" th:action="@{/pets}" method="get" class="form-horizontal" id="search-pet-form">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="control-group" id="nameGroup">
|
||||||
|
<label class="col-sm-2 control-label" th:text="#{name}">Name </label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input class="form-control" th:field="*{name}" size="30" maxlength="80" />
|
||||||
|
<span class="help-inline">
|
||||||
|
<div th:if="${#fields.hasAnyErrors()}">
|
||||||
|
<p th:each="err : ${#fields.allErrors()}" th:text="${err}">Error</p>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-2 col-sm-10">
|
||||||
|
<button type="submit" class="btn btn-primary" th:text="#{findPet}">Find Pet</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
68
src/main/resources/templates/pets/petDetails.html
Normal file
68
src/main/resources/templates/pets/petDetails.html
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html xmlns:th="https://www.thymeleaf.org" th:replace="~{fragments/layout :: layout (~{::body},'pets')}">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h2 th:text="#{petInformation}">Pet Information</h2>
|
||||||
|
|
||||||
|
<div th:if="${message}" class="alert alert-success" id="success-message">
|
||||||
|
<span th:text="${message}"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div th:if="${error}" class="alert alert-danger" id="error-message">
|
||||||
|
<span th:text="${error}"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-striped" th:object="${pet}">
|
||||||
|
<tr>
|
||||||
|
<th th:text="#{name}">Name</th>
|
||||||
|
<td><b th:text="*{name}"></b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th th:text="#{birthDate}">Birth Date</th>
|
||||||
|
<td th:text="*{birthDate}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th th:text="#{type}">Type</th>
|
||||||
|
<td th:text="*{type}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th th:text="#{petAttributeTemp}">Temperament</th>
|
||||||
|
<td th:text="*{petAttribute != null ?petAttribute.temperament: 'N/A'}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th th:text="#{petAttributeLength}">Length</th>
|
||||||
|
<td th:text="*{petAttribute != null ?petAttribute.length: 'N/A'}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th th:text="#{petAttributeWeight}">Weight</th>
|
||||||
|
<td th:text="*{petAttribute != null ?petAttribute.weight: 'N/A'}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th th:text="#{owner}">Owner</th>
|
||||||
|
<td th:text="*{owner.firstName !=null && owner.lastName !=null ? owner.firstName + ' ' + owner.lastName : 'N/A'}"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Function to hide the success and error messages after 3 seconds
|
||||||
|
function hideMessages() {
|
||||||
|
setTimeout(function () {
|
||||||
|
document.getElementById("success-message").style.display = "none";
|
||||||
|
document.getElementById("error-message").style.display = "none";
|
||||||
|
}, 3000); // 3000 milliseconds (3 seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the function to hide messages
|
||||||
|
hideMessages();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
|
||||||
|
</html>
|
63
src/main/resources/templates/pets/petsList.html
Normal file
63
src/main/resources/templates/pets/petsList.html
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html xmlns:th="https://www.thymeleaf.org" th:replace="~{fragments/layout :: layout (~{::body},'pets')}">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h2 th:text="#{pets}">Pets</h2>
|
||||||
|
|
||||||
|
<table id="pets" class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th th:text="#{name}" style="width: 150px;">Name</th>
|
||||||
|
<th th:text="#{birthDate}" style="width: 200px;">Birth Date</th>
|
||||||
|
<th th:text="#{type}">Type</th>
|
||||||
|
<th th:text="#{petAttributeTemp}">Temperament</th>
|
||||||
|
<th th:text="#{petAttributeLength}">Length</th>
|
||||||
|
<th th:text="#{petAttributeWeight}">Weight</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="pet : ${listPets}">
|
||||||
|
<td>
|
||||||
|
<a th:href="@{/pets/__${pet.id}__}" th:text="${pet.name}" /></a>
|
||||||
|
</td>
|
||||||
|
<td th:text="${pet.birthDate}" />
|
||||||
|
<td th:text="${pet.type}" />
|
||||||
|
<td th:text="${pet.petAttribute != null ?pet.petAttribute.temperament: 'N/A'}" />
|
||||||
|
<td th:text="${pet.petAttribute != null ?pet.petAttribute.length: 'N/A'}" />
|
||||||
|
<td th:text="${pet.petAttribute != null ?pet.petAttribute.weight: 'N/A'}" />
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div th:if="${totalPages > 1}">
|
||||||
|
<span th:text="#{pages}">Pages:</span>
|
||||||
|
<span>[</span>
|
||||||
|
<span th:each="i: ${#numbers.sequence(1, totalPages)}">
|
||||||
|
<a th:if="${currentPage != i}" th:href="@{'/pets?page=' + ${i}}">[[${i}]]</a>
|
||||||
|
<span th:unless="${currentPage != i}">[[${i}]]</span>
|
||||||
|
</span>
|
||||||
|
<span>] </span>
|
||||||
|
<span>
|
||||||
|
<a th:if="${currentPage > 1}" th:href="@{'/pets?page=1'}" th:title="#{first}" class="fa fa-fast-backward"></a>
|
||||||
|
<span th:unless="${currentPage > 1}" th:title="#{first}" class="fa fa-fast-backward"></span>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<a th:if="${currentPage > 1}" th:href="@{'/pets?page=__${currentPage - 1}__'}" th:title="#{previous}"
|
||||||
|
class="fa fa-step-backward"></a>
|
||||||
|
<span th:unless="${currentPage > 1}" th:title="#{previous}" class="fa fa-step-backward"></span>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<a th:if="${currentPage < totalPages}" th:href="@{'/pets?page=__${currentPage + 1}__'}" th:title="#{next}"
|
||||||
|
class="fa fa-step-forward"></a>
|
||||||
|
<span th:unless="${currentPage < totalPages}" th:title="#{next}" class="fa fa-step-forward"></span>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<a th:if="${currentPage < totalPages}" th:href="@{'/pets?page=__${totalPages}__'}" th:title="#{last}"
|
||||||
|
class="fa fa-fast-forward"></a>
|
||||||
|
<span th:unless="${currentPage < totalPages}" th:title="#{last}" class="fa fa-fast-forward"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in a new issue