I have a thymeleaf fragment called nav which I include in all front-end pages, it goes like so:
<nav class="navbar navbar-expand-md navbar-dark bg-dark" th:fragment="nav">
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
How to get Java data here ?
</ul>
</div>
</nav>
But what I want to do now is get some data from the database and have that data available in this fragment, which in turn will appear on every page that includes this fragment.
If I want to pass data to a view regularly from a controller, I would use Model and model.addAttribute and return the appropriate view which would contain the relevant model data, but how can I pass data to this fragment?
You can create an interceptor and add model attribute on the postHandle method (which allows you access to the ModelAndView object. The interceptor will have to be on all the controllers that have this fragment.
You can add the relevant model attributes to the session and access them via ${session.attribute}.
Use the #ControllerAdvice annotation in combination with #ModelAttribute to add a model attribute to all controllers.
Related
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.
I am implementing Role based spring security
In this example they have used thymeleaf for frontend purpose, but I am using angular9 with html.
they are using sec:authorize="hasRole('ROLE_ADMIN')" to provide access to the admin,in the same way if I want to provide the same thing in html, for that I have used the following code,
<li *ngFor="let user of users">
{{user.username}} ({{user.firstName}} {{user.lastName}})
- <a sec:authorize="hasRole('ROLE_ADMIN')" (click)="deleteUser(user.userid)" class="text-danger">Delete</a>
</li>
The person logged in is Role_user, eventhough the delete link is visible to the user.
How can I restrict.
Thanks in advance.
use *ngIf directive to show and hide the anchor tag
<li *ngFor="let user of users">
{{user.username}} ({{user.firstName}} {{user.lastName}})
- <a *ngIf="hasRole('ROLE_ADMIN')" (click)="deleteUser(user.userid)" class="text-danger">Delete</a>
</li>
but the hasRole() must return boolean. because *ngIf accepts the boolean
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.
Model has Map(String,Integer), this map displayed on page in checkboxes like:
<ul>
<li th:each="item : ${map}">
<input type="checkbox" th:checked="${item.value} == 1" th:id="${item.key}"/>
<label th:for="${item.key}" th:text="${item.key}"/>
</li>
</ul>
How should i submit checkboxes state changes?
If you are using Spring MVC as your application and Thymeleaf as your view engine please check out this section on dynamic forms and working with them:
http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dynamic-fields
Essentially what you want to do is have an object that would have a Map as a variable within it, which would then bind all your inputs against when it hits the controller.
e.g.
public class MyObject {
Map<String, Integer> myMap;
// getters and setters
}
I need to send the data which is present in a list from my spring controller to thymeleaf (html) how can I send the data? after receiving how can I iterate the data in thymeleaf
Put your list inside your ModelMap or ModelAndView object then traverse it using th:each within your thymeleaf page.
From Java side:
modelMap.addAttribute("list", myListOfThings);
From Thymeleaf side:
<ul>
<li th:each="item : ${list}">
<span th:text="${item}">Default</span>
</li>
</ul>