Not able to load partial templates using Thymleaf - spring-boot

I have templates/header.html with following code
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<div class="testing" th:fragment="header">
2016 Header
</div>
</body>
</html>
I have templates/index.html with following code
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<div th:insert="header :: header"></div>
<h3>User Registration</h3>
<form action="/AddUser" method="post">
<input type="text" name="fname" id="lname" placeholder="Firstname"
required /> <input type="text" name="lname" id="fname"
placeholder="Lastname" required />
<button type="submit">Insert</button>
</form>
</body>
</html>
I am expecting 2016 Header in index.html. But, nothing is getting displayed.
I am using following configuration in my gradle dependencies
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
Please tell me where i am going wrong.

Related

SpringBoot - I tried to pass parameters from a view to controller, and I tried to display result in another view, but it doesn't work

I tried to build a form in home.jsp
<form method="POST" action="uploadfile" th:action="#{/uploadfile}" enctype="multipart/form-data">
<input type="file" name="file" accept=".xls"/> <br/><br/>
<label for="fname">order address:</label>
<input type="text" id="address" name="address" size="50">
<label for="lname">order account:</label>
<input type="text" id="account" name="account" size="50"><br/><br/>
<label for="lname">:</label>
<button type="submit">summit/button>
</form>
result.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/style.css" rel="stylesheet">
<meta charset="UTF-8">
<title>result</title>
</head>
<body>
<div th:if="${message}">
<h2 th:text="${message}"/></div>
<form action="/download" method="post">
<text name="filename" type="text" value="${downloadfile}"/><br/>
<input type="submit" value="download XML" />
</form>
</body>
</html>
here is my controller
#PostMapping("/uploadfile")
public ModelAndView uploadFile(#RequestParam("file") MultipartFile file,
#RequestParam(name="address", required = false) String myaddress,
#RequestParam(name="account", required = false) String myaccount
)
{
....................
..................
ModelAndView model = new ModelAndView("result"); //tried to return this parameters
model.addObject("excecontentslist",tempExcelcontentList); //tried to show the contents of Excel
model.addObject("message",consequencemsg);//tried to show the message we have
model.addObject("downloadfile",xmlfilename); //tried to show the xml which is gonna download
return model;//got 404 error when all things has been done
}
all I trying to do was to send datas which is model to result.jsp to show the data out there,but it doesn't work,just showed the 404 error ,any idea?

java.lang.ClassNotFoundException: org.unbescape.uri.UriEscape

I get this error when ever I try to load this web page:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" type="text/css" th:href="#{/webjars/bootstrap/3.3.7/css/bootstrap.min.css}"/>
<link rel="stylesheet" type="text/css" th:href="#{/css/main.css}"/>
<title>Competition</title>
</head>
<body>
<div>
<p th:text="'Name: ' + ${competition.name}" />
<p th:text="'Date: ' + ${competition.date}" />
<p th:text="'Venue: ' + ${competition.Venue}" />
<div th:if="${competition.competitors != null}">
<h3>Competitors</h3>
<ul>
<li th:each="item : ${competition.competitors}" th:text="${item}"></li>
</ul>
</div>
<h4>Add Competitor.</h4>
<form action="#" th:action="#{/competitions/{id}(id=${competition.id})}" th:object="${email}" method="post">
<p>User email: <input type="text" th:field="*{text}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</div>
<p th:text="${competition.id}"></p>
</body>
</html>
I added the org.unbescape dependency to my pom.xml.
I started getting this error when I added the the URL to the form
(This line:)
th:action="#{/competitions/{id}(id=${competition.id})}"
It looks like you are using a older version of org.unbescape. The class UriEscape was introduced in versin 1.1.0. Ref here
Can you try by upgrading the org.unbescape version to 1.1.1 as follows?
<dependency>
<groupId>org.unbescape</groupId>
<artifactId>unbescape</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>

Passing bean field to th:field in Thymeleaf fragment

I'm trying to refactor our Thymeleaf code that have a lot of copy-paste. The general idea is we have something like this:
<form th:object="${createForm}">
<div><input type="text" th:field="*{first}"/> <!-- some boilerplate code --></div>
<div><input type="text" th:field="*{second}"/> <!-- some boilerplate code --></div>
<div><input type="text" th:field="*{third}"/> <!-- some boilerplate code --></div>
<div><input type="text" th:field="*{fourth}"/> <!-- some boilerplate code --></div>
</form>
and I want to refactor the fragment
<input type="text" th:field="*{first}"/> <!-- some boilerplate code -->
to a separate file as it is a lot of copy paste (there is quite some HTML in the boilerplate code section).
My first approach was to do something like this:
<form th:object="${createForm}">
<div th:replace="fragments/input :: input(*{first}" />
<div th:replace="fragments/input :: input(*{second}" />
<div th:replace="fragments/input :: input(*{third}" />
<div th:replace="fragments/input :: input(*{fourth}" />
</form>
and then have a fragments/input.html file
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
</head>
<body>
<div th:fragment="input(field)">
<input th:field="${field}"/> <!-- some boilerplate code -->
</div>
</body>
</html>
But, once compiled/deployed, I get error
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'field' available as request attribute
Anyone an idea how to solve this? The question is to reduce code copy-paste while retaining the benefit of having th:field.
I also tried use th:with like this
<div th:width="field=*{first}" th:replace="fragments/smallslider :: input()" />
and fragment
<div th:fragment="input()">
<input th:field="${field}"/> <!-- some boilerplate code -->
</div>
but that did neither produce error nor generate HTML.
I solved this in similar way as #Wilson did.
Fragment:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head></head>
<body>
<div th:fragment="input(fieldName)">
<input th:field="*{__${fieldName}__}" type="text">
</div>
</body>
</html>
Calling:
<form th:object="${createForm}">
<div th:replace="fragments/input :: input('first')" />
<div th:replace="fragments/input :: input('second')" />
<div th:replace="fragments/input :: input('third')" />
<div th:replace="fragments/input :: input('fourth')" />
</form>
you can achive this by passing the name of your bean field to the fragment like so.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
</head>
<body>
<div th:fragment="input(fieldName, fieldValue)">
<input th:name="${fieldName}" th:value=${fieldValue}/> <!-- some boilerplate code -->
</div>
</body>
</html>
and call it like so
<form th:object="${createForm}">
<div th:replace="fragments/input :: input('field', *{field})" />
</form>

Spring + Thymeleaf not able to populate String on render

I have a testt.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.thymeleaf.org ">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Advanced Test</title>
</head>
<body>
<form action="#" th:action="#{getClasses}" method="GET">
<br />
<br />
<p style="margin-left: 35px">Submit fully classified package names</p>
Class Name: <input type="text" name="class_name" size="90px"></input>
<input type="text" name="classes" size="90px" th:field="${foo}"></input>
<input type="submit" value="Submit" ></input> <br />
</form>
</body>
</html>
And have the following code in the controller method:
model.addAttribute("foo", "foo");
return "testt";
Why "foo" is not populating in the html? If instead of String i add an object and try to get its variable it works fine.
i think if you want use it like this you should use th:value instead of th:field
You need this th:field=__${foo}__,
have a look at the doc here:http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html

Jquery mobile href link dont load new page

i'm a web devoper from Italy...I have a problem with loading with href
example:
i have one.html with this code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta names="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<title>dkrMobile</title>
<!--caricamento librerie-->
<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/jquery.mobile-1.3.1.min.js"></script>
<link rel="stylesheet" href="css/jquery.mobile-1.3.1.min.css">
</head>
<body>
<!-- LOGIN -->
<div data-role="page" id="loginPage">
<div data-role="content">
<div style=" text-align:center">
<img style="width: 70%;" src="http://www.laboncloud.it/dkrmobile/css/images/logdkr.png">
</div>
<form action="#pageFile">
<div data-role="fieldcontain">
<label for="userNameLogin">
Username
</label>
<input name="" id="userNameLogin" placeholder="" value="" type="text">
</div>
<div data-role="fieldcontain">
<label for="passwordLogin">
Password
</label>
<input name="" id="passwordLogin" placeholder="" value="" type="password">
</div>
<a data-role="button" data-theme="a" data-transition="fade" href="two.html" data-prefetch="trues">
Login
</a>
</form>
</div>
</div>
</body>
</html>
and the two.html with this code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta names="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<title>dkrMobile</title>
<!--caricamento librerie-->
<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/jquery.mobile-1.3.1.min.js"></script>
<link rel="stylesheet" href="css/jquery.mobile-1.3.1.min.css">
<link rel="stylesheet" href="css/jqm-icon-pack-fa.css">
<script type="text/javascript" src="js/tolito-1.0.5.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/tolito-1.0.5.min.css" />
<!--css userinterface-->
<link rel="stylesheet" href="css/ui.css" />
</head>
<body>
<div data-role="page" id="loadingPage">
<div data-role="content">
<h1>caricamento di tutti i contenuti in corso</h1>
<a data-role="button" data-theme="a" data-transition="fade" href="#pageFile">skip</a>
</div>
</div>
<div data-role="page" id="pageFile">
<div data-role="content">
<h1>dueeee</h1>
</div>
</div>
<!-- FILE-->
</body>
</html>
now if tap on login - the two.html will no be loaded.
want a demo?
here the demo
if I click on skip in two.html dont show nothing (if I refresh the page it start work).
the only way is data-ajax="false" ? why?
This is not an error. To understand this problem you must understand how jQuery Mobile works.
Multi HTML template can't be mixed with multi page template. For example when working with several HTML pages, only first one can have more then one page. When jQuery Mobile loads other HTML files it will strip HEAD (we dont need it because first HTML HEAD content is already loaded into the DOM) and it will load ONLY first page it can find in a file, every other page will be discarded.
data-prefetch will not help you here. Also you are initializing it incorrectly, data-prefetch attribute don't have a value, it is just data-prefetch, example:
<a data-role="button" data-theme="a" data-transition="fade" href="two.html" data-prefetch>Login</a>
If you want to find out more how jQuery Mobile handles multiple HTML and multiple page templates or what are they take a look at this ARTICLE or THIS one. To be transparent they are my personal blog articles. Everything you need to know can be found there.
Basically solution to your problem would be to have all pages inside a single HTML file, or you should brake two.html into two separate HTML files. you decide what is a best solution for you.

Resources