Spring Boot and Thymeleaf: Switching Pages through Nav bar links - java

I am working on a Car Dealership project utilizing:
Java 8
Spring boot
Thymeleaf
AWS mySQL database
my current problem is that i an having trouble using my nav bar to move between html pages.
i have 5 html pages( index.html, customer.html, employee.html, vehicle.html, and transaction.html)
code from index.html:
<a class="active" th:href="#{/index.html}"><i class="(Put css class here)"></i> Home</a>
<a th:href="#{/vehicle.html}"><i class="(Put css class here)"></i> Vehicles </a>
<a th:href="#{/customer.html}"><i class="(Put css class here)"></i> Customers </a>
<a th:href="#{/employee.html}"><i class="(Put css class here)"></i> Employees </a>
<a th:href="#{/transaction.html}"><i class="(Put css class here)"></i> Transactions </a>
code from IndexController:
#Controller
public class IndexController {
#RequestMapping("/index")
public String index(){
return "index";
}
}
the page loads normally at localhost:8088 when first opened, but when i click "home" or any other button i get a 404.
if anyone could simply point me in a general direction i would greatly appreciate it.

Instead, try to make GetMapping requests in the controller for those different links.
Example:
#GetMapping("/customer")
public String getCustomer(){
return "customer.html";
}
And in your html class (nav bar):
<a th:href="#{/customer}"><i class="(Put css class here)"></i> Customers </a>
*Make sure to remove the .html, but this depends on how you've configured it in your config, but I believe this is the default configuration.

Related

Controller problem with header's data with Spring Boot and Thymeleaf

so here's my problem.
I'm trying to have dynamic data in my header. It's supposed to represent the number of items a user has in his cart.
So here's my header (the header is a fragment that I included in the layout.html) and the data is in the last li
<nav >
<ul>
<li><a th:href="#{/index}" class="">Home</a></li>
<li><a th:href="#{/products/list}" class="">Products</a></li>
<li><a th:href="#{/admin/index}" class="">Admin</a></li>
<li>Account</li>
<li>Contacts</li>
<li><a th:href="#{/login}" class="">Login</a></li>
<li><a th:href="#{/user-page}" class="">User</a></li>
<li>
<p th:text="${cart.id}"></p>
</li>
</ul>
</nav>
But since the header is available on every page of the web app, what should I do (in the controllers) to get this data?
I tried to put the cart data in the IndexController but it doesn't work. I'm not comfortable with Spring and Thymeleaf so I might be doing something wrong or maybe I missed something on data binding. I only have once constraint, I don't want to use Ajax or Jquery. Unless I have no choice but I doubt that. Here's what I tried in the IndexController
#GetMapping({"/", "/index", "/home"})
public String getIndex(Model model) {
this.userCart.setId(5);
this.userCart.setNumberItems(11);
model.addAttribute("cart", userCart);
model.addAttribute("phrase", "Oui oui si si 92izi");
model.addAttribute("nbItems", "10");
return "index";
}
I also tried to make another method mapped to "/" but it causes an error since I can't have to methods mapped to the same url. So what am I supposed to do ?
If you need a model attribute application wide, then you can use an #ControllerAdvice annotated class:
#ControllerAdvice
public class GlobalControllerAdvice {
#ModelAttribute("numberOfItemsInCart")
public int getNumberOfItemsInCart() {
// get the cart and return the number of items
}
}
And use this attribute in your template:
<p th:text="${numberOfItemsInCart}"></p>
The method that is annotated with #ModelAttribute can also declare HttpServletRequest request as a parameter if needed (See https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-arguments for all possible arguments for the method).
See https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-controller-advice for more details about #ControllerAdvice.

Spring Boot & Thymeleaf: list of links

Java/Spring Boot web app here using Thymeleaf as the templating engine.
My bean:
public class InventoryItem {
private String modelNumber;
private String name;
// getters, setters and ctors omitted for brevity
}
My Spring controller:
#Controller
#RequestMapping("/inventory")
public class InventoryController {
#GetMapping("/{inventoryId}")
public String viewInventory(#PathVariable("inventoryId") String inventoryId, Model model) {
List<InventoryItem> inventory = getSomehow(inventoryId);
model.addAttribute("inventory", inventory);
return "inventory";
}
}
And a snippet from the inventory.html file that Thymeleaf must template:
<div class="col-md-4 mt-5">
<div class="panel-body">Inventory Items</div>
<ul>
<li th:each="item :${inventory}" th:text="${item.name}"></li>
</ul>
</div>
At runtime this produces a nice unordered list of inventory item names.
What I want now is to make this an unordered list of hyperlinks (<a/>) such that the rendered HTML looks like so:
<ul>
<li>Goose</li>
<li>Duck</li>
<!-- etc. -->
</ul>
Where 12345 and 23456 are InventoryItem#modelNumbers and where Goose and Duck are InventoryItem#names. I've asked the Google Gods high and low and cannot find a working example of using Thymeleaf to render a list (ordered/unordered alike) of hyperlinks. Any ideas?
Something like this would work ...
<div class="col-md-4 mt-5">
<div class="panel-body">Inventory Items</div>
<ul>
<li th:each="item :${inventory}">
<a th:href="#{/inventoryDetails/{modelNumber}(modelNumber=${item.modelNumber})}" th:text="${item.name}">Goose</a>
</li>
</ul>
</div>
If you would like to get more information on how to work with Link URLs, follow Thymeleaf documentation.

Mapping a HTML button to call a method in a controller class in Spring MVC

I am having some difficulties in calling a method when a button is clicked.
In my Index.JSP
I have the following section of HTML code
<div class="hero-copy">
<h1 class="hero-title mt-0">Deep Algorithm by Sadman Sakib</h1>
<p class="hero-paragraph">A personal portfolio/demonstration of all university and extra-curricular activites, beautifully packaged, in a modern and responsive Spring MVC Web Application</p>
<div class="hero-cta">
<a class="button button-primary" onclick="">View Projects</a>
<div class="lights-toggle">
<input id="lights-toggle" type="checkbox" name="lights-toggle" class="switch" checked="checked" >
<label for="lights-toggle" class="text-xs"><span>Turn me <span class="label-text">dark</span></span></label>
</div>
</div>
</div>
Now "View Projects" is a button which will print "Hello" out in the console, I am not sure what I should be using to call the method in my controller. At the moment I am using onClick but am not sure what I should put as a parameter.
This is my controller class
#Controller
public class HelloController {
#RequestMapping("/projects")
public void add()
{
System.out.println("Hello");
}
}
This is my view, user will click view projects and it will print hello out in the console, how would I go about doing this?
EDIT
When I use a form it works, however when using href it does not link to my controller.
<form action="add">
<input type="submit" class="button button-primary" value="Me">
</form>
<span>View GitHub</span>
<h3>View GitHub</h3>
How can I use href to link back to my controller. Do I need to import some dependencies/taglines
First you must understand what the controller is doing. The controller is mapping the request which have the path /projects, so usually, the url will be something like http://localhost:8080/projects if your app is running on port 8080. Upon calling '/projects' from your browser, the method add() will be executed.
The easiest way to trigger the method add() in the controller is using href in the link.
The code will be as follows:
<a class="button button-primary" href="${pageContext.servletContext.contextPath}/projects">View Projects</a>
If you really want to use the onclick method, then you must create a javascript function and call the url which is mapping to /projects
Update 28/06/20
The code will not work because the method being invoked is returning void. Add #ResponseStatus(value = HttpStatus.OK) on the method then it should work just fine.
#Controller
public class HelloController {
#RequestMapping("/projects")
#ResponseStatus(value = HttpStatus.OK)
public void add()
{
System.out.println("Hello");
}
}
So basically I managed to fix it, I should call my controller using href like this
href="<c:url value="/projects"/>
Cheers to everyone who helped

How to display data from object in zk (zul file)?

I am using zk framework for my internship. I currently have a controller that goes and fetches a special link from an api and I have to create an IFrame in a zul file and bind this link into this iframe.
I do not know how to dynamically bind data either from an object, a modal or a properties file.
<div id="iframe-div" height="100%" style="background: #ccc;">
<iframe id="iframe" width="100%" height="100%" src="https://thisIsTheLink.com"/>
</div>
is there something similar as src="{mylink}" in zk as they do in other front end frameworks? Is it possible to dynamically bind data in zk framework?
Yes it is possible. I recommend using MVVM binding.
zul file:
<window viewModel="#id('vm') #init('com.example.IndexVM')">
<div id="iframe-div" height="100%" style="background: #ccc;">
<iframe id="iframe" width="100%" height="100%" src="#load(vm.includeSrc)" />
</div>
</window>
view model:
public class IndexVM() {
public String getIncludeSrc() {
return "https://thisIsTheLink.com";
}
}
You can even pass parameters to your included file.

How to repeat a Spring model in a Thymeleaf fragment

I have a Spring + Thymeleaf project. I have a fragment for the header part and some pages which include the header.
Below is the (essential part of) the header fragment. As you can see it includes the activeUserWorkgroup model object
dashboard-header.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<body>
<header th:fragment="dashboard-header" class="header">
....
<div class="navbar-right">
<ul class="nav navbar-nav">
<li class="dropdown notifications-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<span class="user-label" style="margin-left:5px;"
th:text="${activeUserWorkgroup.getWorkgroupLabel()}">
</span>
</a>
</li>
</ul>
</div>
</nav>
</header>
</body>
</html>
In every Spring view where I need the header fragment I add the line
<div th:replace="fragments/dashboard-header :: dashboard-header"></div>
The problem is that in every Controller of every View in which I need this header, I have to give the proper value to the activeUserWorkgroup model object. This is both uncomfortable and error prone.
Is there any way to let Spring give the proper model value to the activeUserWorkgroup object without having to write the code in every Controller?
Thank you
This probably what you are looking for. What I would do is create controller that return just the Model object activeUseWorkgroup. Then have all the other controllers extend it.
#Controller
public ControllerA
{
#ModelAttribute("activeUserWorkgroup")
public Object getActiveUserWorkgroup()
{
return new Object();
}
}
#Controller
public ControllerB extends ControllerA
{
}
Maybe is better to create a ControllerAdvice, read the documentation at this link http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html
#ControllerAdvice
public class GlobalControllerAdvice extends ResponseEntityExceptionHandler {
#ModelAttribute("activeUserWorkgroup ")
public String getActiveWorkgroup() {
//YOUR CODE
}
}

Categories