mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-16 12:45:48 +00:00
vikram-Ajabe -Software Engineer Assignment
This commit is contained in:
parent
f9399b7a9f
commit
2c5cf16284
15 changed files with 507 additions and 62 deletions
|
@ -0,0 +1,78 @@
|
|||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
|
||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "pet_attributes")
|
||||
public class PetAttributes extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Column(name = "petId", nullable = false, unique = true)
|
||||
private Long petId;
|
||||
|
||||
@Column(name = "temperament")
|
||||
private String temperament;
|
||||
|
||||
@Column(name = "length")
|
||||
private Double length;
|
||||
|
||||
@Column(name = "weight")
|
||||
private Double weight;
|
||||
|
||||
@Column(name = "energy_level")
|
||||
private Integer energyLevel;
|
||||
|
||||
// Getters and Setters
|
||||
|
||||
public Long getPetId() {
|
||||
return petId;
|
||||
}
|
||||
|
||||
public void setPetId(Long petId) {
|
||||
this.petId = petId;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Integer getEnergyLevel() {
|
||||
return energyLevel;
|
||||
}
|
||||
|
||||
public void setEnergyLevel(Integer energyLevel) {
|
||||
this.energyLevel = energyLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PetAttributes [petId=" + petId + ", temperament=" + temperament + ", length=" + length + ", weight="
|
||||
+ weight + ", energyLevel=" + energyLevel + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/petAttributes")
|
||||
public class PetAttributesController {
|
||||
|
||||
private final PetAttributesRepository petAttributesRepository;
|
||||
|
||||
private final PetAttributesService petAttributesService;
|
||||
|
||||
@Autowired
|
||||
public PetAttributesController(PetAttributesRepository petAttributesRepository,PetAttributesService petAttributesService) {
|
||||
this.petAttributesRepository = petAttributesRepository;
|
||||
this.petAttributesService=petAttributesService;
|
||||
}
|
||||
|
||||
@GetMapping("/all")
|
||||
public String list(Model model) {
|
||||
model.addAttribute("listAttributes", petAttributesRepository.findAll());
|
||||
return "petAttributes/list";
|
||||
}
|
||||
|
||||
@GetMapping("/new")
|
||||
public String showCreateForm(Model model) {
|
||||
model.addAttribute("petAttributes", new PetAttributes());
|
||||
return "petAttributes/form";
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
public String save(@ModelAttribute PetAttributes petAttributes, RedirectAttributes redirectAttributes) {
|
||||
petAttributesRepository.save(petAttributes);
|
||||
redirectAttributes.addFlashAttribute("successMessage", "Saved successfully!");
|
||||
return "redirect:/petAttributes/all";
|
||||
}
|
||||
|
||||
@GetMapping("/edit/{id}")
|
||||
public String showEditForm(@PathVariable("id") Integer id, Model model) {
|
||||
PetAttributes attr = petAttributesRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Invalid ID: " + id));
|
||||
model.addAttribute("petAttributes", attr);
|
||||
return "petAttributes/form";
|
||||
}
|
||||
@GetMapping("/search")
|
||||
public String showSearchForm() {
|
||||
return "petAttributes/search";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/search", params = "petId")
|
||||
public String searchByPetId(@RequestParam("petId") Integer petId, Model model) {
|
||||
PetAttributes result = petAttributesService.findByPetId(petId);
|
||||
if (result != null) {
|
||||
model.addAttribute("listAttributes", List.of(result));
|
||||
} else {
|
||||
model.addAttribute("listAttributes", List.of());
|
||||
model.addAttribute("error", "No results for Pet ID: " + petId);
|
||||
}
|
||||
return "petAttributes/search";
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String delete(@PathVariable("id") Integer id, RedirectAttributes redirectAttributes) {
|
||||
petAttributesRepository.deleteById(id);
|
||||
redirectAttributes.addFlashAttribute("successMessage", "Deleted successfully!");
|
||||
return "redirect:/petAttributes/all";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface PetAttributesRepository extends JpaRepository<PetAttributes, Integer> {
|
||||
|
||||
PetAttributes findByPetId(int petId);
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
public interface PetAttributesService {
|
||||
|
||||
PetAttributes save(PetAttributes attributes);
|
||||
|
||||
PetAttributes findByPetId(int petId);
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class PetAttributesServiceImpl implements PetAttributesService {
|
||||
|
||||
private final PetAttributesRepository petAttributesRepository;
|
||||
|
||||
@Autowired
|
||||
public PetAttributesServiceImpl(PetAttributesRepository repository) {
|
||||
this.petAttributesRepository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public PetAttributes save(PetAttributes attributes) {
|
||||
return petAttributesRepository.save(attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public PetAttributes findByPetId(int petId) {
|
||||
return petAttributesRepository.findByPetId(petId);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface PetRepository extends CrudRepository<Pet, Integer> {
|
||||
|
||||
Pet findById(int id);
|
||||
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
# database init, supports mysql too
|
||||
|
||||
database=h2
|
||||
spring.sql.init.schema-locations=classpath*:db/${database}/schema.sql
|
||||
spring.sql.init.data-locations=classpath*:db/${database}/data.sql
|
||||
|
@ -23,3 +24,8 @@ logging.level.org.springframework=INFO
|
|||
|
||||
# Maximum time static resources should be cached
|
||||
spring.web.resources.cache.cachecontrol.max-age=12h
|
||||
|
||||
spring.h2.console.enabled=true
|
||||
|
||||
# Optional: Change the console path (default is /h2-console)
|
||||
spring.h2.console.path=/h2-console
|
||||
|
|
|
@ -62,3 +62,13 @@ CREATE TABLE visits (
|
|||
);
|
||||
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 TABLE pet_attributes (
|
||||
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
pet_id INTEGER NOT NULL,
|
||||
temperament VARCHAR(255),
|
||||
length INTEGER,
|
||||
weight INTEGER,
|
||||
energy_level INTEGER
|
||||
);
|
||||
|
||||
|
|
|
@ -46,3 +46,19 @@ visitDate=Visit Date
|
|||
editOwner=Edit Owner
|
||||
addNewPet=Add New Pet
|
||||
petsAndVisits=Pets and Visits
|
||||
petTypes=Pet Types
|
||||
addPetAttributes=Add Pet Attributes
|
||||
save=Save
|
||||
petTypeAdded=Pet Type Added Successfully.
|
||||
pet.attributes=Pet Attributes
|
||||
pet.id=Pet ID
|
||||
temperament=Temperament
|
||||
length=Length
|
||||
weight=Weight
|
||||
energy.level=Energy Level
|
||||
pages=Pages
|
||||
petAttributes=Pet Attributes
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,84 +4,89 @@
|
|||
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" type="image/x-icon" th:href="@{/resources/images/favicon.png}">
|
||||
<title th:text="#{layoutTitle}">PetClinic :: a Spring Framework demonstration</title>
|
||||
<link th:href="@{/webjars/font-awesome/css/font-awesome.min.css}" rel="stylesheet">
|
||||
<link rel="stylesheet" th:href="@{/resources/css/petclinic.css}" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" type="image/x-icon" th:href="@{/resources/images/favicon.png}">
|
||||
<title th:text="#{layoutTitle}">PetClinic :: a Spring Framework demonstration</title>
|
||||
<link th:href="@{/webjars/font-awesome/css/font-awesome.min.css}" rel="stylesheet">
|
||||
<link rel="stylesheet" th:href="@{/resources/css/petclinic.css}" />
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-dark" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" th:href="@{/}"><span></span></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#main-navbar">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="main-navbar" style>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" th:href="@{/}"><span></span></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#main-navbar">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="main-navbar" style>
|
||||
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0" th:remove="all">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0" th:remove="all">
|
||||
|
||||
<li th:fragment="menuItem (link,active,title,glyph,text)" th:class="nav-item">
|
||||
<a th:class="${active==menu ? 'nav-link active' : 'nav-link'}" th:href="@{__${link}__}" th:title="${title}">
|
||||
<span th:class="'fa fa-'+${glyph}" class="fa fa-home"></span>
|
||||
<span th:text="${text}">Template</span>
|
||||
</a>
|
||||
</li>
|
||||
<li th:fragment="menuItem (link,active,title,glyph,text)" th:class="nav-item">
|
||||
<a th:class="${active==menu ? 'nav-link active' : 'nav-link'}" th:href="@{__${link}__}"
|
||||
th:title="${title}">
|
||||
<span th:class="'fa fa-'+${glyph}" class="fa fa-home"></span>
|
||||
<span th:text="${text}">Template</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav me-auto">
|
||||
<ul class="nav navbar-nav me-auto">
|
||||
|
||||
<li th:replace="~{::menuItem ('/','home','home page','home',#{home})}">
|
||||
<span class="fa fa-home" aria-hidden="true"></span>
|
||||
<span th:text="#{home}">Home</span>
|
||||
</li>
|
||||
<li th:replace="~{::menuItem ('/','home','home page','home',#{home})}">
|
||||
<span class="fa fa-home" aria-hidden="true"></span>
|
||||
<span th:text="#{home}">Home</span>
|
||||
</li>
|
||||
|
||||
<li th:replace="~{::menuItem ('/owners/find','owners','find owners','search',#{findOwners})}">
|
||||
<span class="fa fa-search" aria-hidden="true"></span>
|
||||
<span th:text="#{findOwners}">Find owners</span>
|
||||
</li>
|
||||
<li th:replace="~{::menuItem ('/owners/find','owners','find owners','search',#{findOwners})}">
|
||||
<span class="fa fa-search" aria-hidden="true"></span>
|
||||
<span th:text="#{findOwners}">Find owners</span>
|
||||
</li>
|
||||
<li th:replace="~{::menuItem ('/vets.html','vets','veterinarians','th-list',#{vets})}">
|
||||
<span class="fa fa-th-list" aria-hidden="true"></span>
|
||||
<span th:text="#{vets}">Veterinarians</span>
|
||||
</li><i class="fa fa-paw"></i> Pet Attributes
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
th:replace="~{::menuItem ('/petAttributes/all','petAttributes','Pet Attributes','paw',#{petAttributes})}">
|
||||
</li>
|
||||
|
||||
<li th:replace="~{::menuItem ('/vets.html','vets','veterinarians','th-list',#{vets})}">
|
||||
<span class="fa fa-th-list" aria-hidden="true"></span>
|
||||
<span th:text="#{vets}">Veterinarians</span>
|
||||
</li>
|
||||
<li
|
||||
th:replace="~{::menuItem ('/oups','error','trigger a RuntimeException to see how it is handled','exclamation-triangle',#{error})}">
|
||||
<span class="fa exclamation-triangle" aria-hidden="true"></span>
|
||||
<span th:text="#{error}">Error</span>
|
||||
</li>
|
||||
|
||||
<li
|
||||
th:replace="~{::menuItem ('/oups','error','trigger a RuntimeException to see how it is handled','exclamation-triangle',#{error})}">
|
||||
<span class="fa exclamation-triangle" aria-hidden="true"></span>
|
||||
<span th:text="#{error}">Error</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid">
|
||||
<div class="container xd-container">
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid">
|
||||
<div class="container xd-container">
|
||||
<th:block th:insert="${template}" />
|
||||
|
||||
<th:block th:insert="${template}" />
|
||||
<br />
|
||||
<br />
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 text-center">
|
||||
<img src="../static/images/spring-logo.svg" th:src="@{/resources/images/spring-logo.svg}"
|
||||
alt="VMware Tanzu Logo" class="logo">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 text-center">
|
||||
<img src="../static/images/spring-logo.svg" th:src="@{/resources/images/spring-logo.svg}"
|
||||
alt="VMware Tanzu Logo" class="logo">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script th:src="@{/webjars/bootstrap/dist/js/bootstrap.bundle.min.js}"></script>
|
||||
<script th:src="@{/webjars/bootstrap/dist/js/bootstrap.bundle.min.js}"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
|
38
src/main/resources/templates/petAttributes/form.html
Normal file
38
src/main/resources/templates/petAttributes/form.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{fragments/layout :: layout (~{::body}, 'Pet Attributes Form')}">
|
||||
<body>
|
||||
<h2 th:text="${petAttributes.id} != null ? 'Edit' : 'Add'">Pet Attributes</h2>
|
||||
|
||||
<form th:action="@{/petAttributes/save}" th:object="${petAttributes}" method="post">
|
||||
<input type="hidden" th:field="*{id}"/>
|
||||
|
||||
<!-- Show hidden petId input only for Edit -->
|
||||
<th:block th:if="${petAttributes.id != null}">
|
||||
<input type="hidden" th:field="*{petId}" />
|
||||
</th:block>
|
||||
|
||||
<!-- Show visible petId input only for Add -->
|
||||
<th:block th:unless="${petAttributes.id != null}">
|
||||
<label>Pet ID:</label>
|
||||
<input type="number" th:field="*{petId}" class="form-control" /><br/>
|
||||
</th:block>
|
||||
<!--<label>Pet ID:</label>
|
||||
<input type="number" th:field="*{petId}" class="form-control"/><br/>-->
|
||||
|
||||
<label>Temperament:</label>
|
||||
<input type="text" th:field="*{temperament}" class="form-control"/><br/>
|
||||
|
||||
<label>Length:</label>
|
||||
<input type="number" th:field="*{length}" class="form-control" step="0.01"/><br/>
|
||||
|
||||
<label>Weight:</label>
|
||||
<input type="number" th:field="*{weight}" class="form-control" step="0.01"/><br/>
|
||||
|
||||
<label>Energy Level:</label>
|
||||
<input type="number" th:field="*{energyLevel}" class="form-control"/><br/>
|
||||
|
||||
<button type="submit" class="btn btn-success">Save</button>
|
||||
<a class="btn btn-secondary" th:href="@{/petAttributes}">Cancel</a>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
48
src/main/resources/templates/petAttributes/list.html
Normal file
48
src/main/resources/templates/petAttributes/list.html
Normal file
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org"
|
||||
th:replace="~{fragments/layout :: layout (~{::body}, 'Pet Attributes')}">
|
||||
<body>
|
||||
<h2>Pet Attributes</h2>
|
||||
|
||||
<a class="btn btn-primary" th:href="@{/petAttributes/new}">Add New</a>
|
||||
<a class="btn btn-primary" th:href="@{/petAttributes/search}">Search by Pet ID</a>
|
||||
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<!--<th>ID</th>-->
|
||||
<th>Pet ID</th>
|
||||
<th>Temperament</th>
|
||||
<th>Length</th>
|
||||
<th>Weight</th>
|
||||
<th>Energy Level</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="attr : ${listAttributes}">
|
||||
<!-- <td th:text="${attr.id}">1</td>-->
|
||||
<td th:text="${attr.petId}">100</td>
|
||||
<td th:text="${attr.temperament}">Calm</td>
|
||||
<td th:text="${attr.length}">25.0</td>
|
||||
<td th:text="${attr.weight}">10.0</td>
|
||||
<td th:text="${attr.energyLevel}">4</td>
|
||||
<td>
|
||||
<a th:href="@{'/petAttributes/edit/' + ${attr.id}}">Edit</a> |
|
||||
|
||||
<!-- POST-based delete form -->
|
||||
<form th:action="@{'/petAttributes/delete/' + ${attr.id}}" method="post"
|
||||
style="display:inline;">
|
||||
<button type="submit" class="btn btn-link p-0" onclick="return confirm('Delete?')">
|
||||
Delete
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div th:if="${successMessage}" class="alert alert-success" th:text="${successMessage}"></div>
|
||||
</body>
|
||||
</html>
|
57
src/main/resources/templates/petAttributes/petAttribute.html
Normal file
57
src/main/resources/templates/petAttributes/petAttribute.html
Normal file
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns:th="https://www.thymeleaf.org" th:replace="~{fragments/layout :: layout (~{::body},'vets')}">
|
||||
|
||||
<body>
|
||||
|
||||
<h2 th:text="#{vets}">Veterinarians</h2>
|
||||
|
||||
<table id="vets" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th th:text="#{name}">Name</th>
|
||||
<th th:text="#{specialties}">Specialties</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="vet : ${listVets}">
|
||||
<td th:text="${vet.firstName + ' ' + vet.lastName}"></td>
|
||||
<td>
|
||||
<span th:each="specialty : ${vet.specialties}" th:text="${specialty.name + ' '}" /> <span
|
||||
th:if="${vet.nrOfSpecialties == 0}" th:text="#{none}">none</span>
|
||||
</td>
|
||||
</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="@{'/vets.html?page=__${i}__'}">[[${i}]]</a>
|
||||
<span th:unless="${currentPage != i}">[[${i}]]</span>
|
||||
</span>
|
||||
<span>] </span>
|
||||
<span>
|
||||
<a th:if="${currentPage > 1}" th:href="@{'/vets.html?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="@{'/vets.html?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="@{'/vets.html?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="@{'/vets.html?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>
|
45
src/main/resources/templates/petAttributes/search.html
Normal file
45
src/main/resources/templates/petAttributes/search.html
Normal file
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
th:replace="~{fragments/layout :: layout(~{::template}, 'petAttributes')}">
|
||||
|
||||
<th:block th:fragment="template">
|
||||
<h2>Search by Pet ID</h2>
|
||||
|
||||
<form th:action="@{/petAttributes/search}" method="get">
|
||||
<div class="form-group">
|
||||
<label for="petId">Pet ID:</label>
|
||||
<input type="number" class="form-control" id="petId" name="petId" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-2">Search</button>
|
||||
</form>
|
||||
|
||||
<div th:if="${error}" class="alert alert-warning mt-3" th:text="${error}"></div>
|
||||
|
||||
<div th:if="${listAttributes}">
|
||||
<h3 class="mt-4">Results</h3>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<!-- <th>ID</th>-->
|
||||
<th>Pet ID</th>
|
||||
<th>Temperament</th>
|
||||
<th>Length</th>
|
||||
<th>Weight</th>
|
||||
<th>Energy Level</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="attr : ${listAttributes}">
|
||||
<!-- <td th:text="${attr.id}"></td>-->
|
||||
<td th:text="${attr.petId}"></td>
|
||||
<td th:text="${attr.temperament}"></td>
|
||||
<td th:text="${attr.length}"></td>
|
||||
<td th:text="${attr.weight}"></td>
|
||||
<td th:text="${attr.energyLevel}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</th:block>
|
||||
</html>
|
Loading…
Reference in a new issue