Passing bean field to th:field in Thymeleaf fragment - spring

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>

Related

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>

Not able to load partial templates using Thymleaf

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.

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

Rendering pages in mvc3 from xml

I want some static pages of application to be rendered from XML i.e. i am planning to have a base page and xml containing structure of the page and xslt which will be transforming this xml to html and at runtime i will be rendering this html to my view and displaying this view
Is there any way/ example for doing the same. Please help
Here is the sample xml
<!DOCTYPE html>
<html>
<head>
<title>Create</title>
<script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript" />
<link href="/Content/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-ui.js" type="text/javascript" />
<script src="/Scripts/jquery.validate.min.js" type="text/javascript" />
<script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript" />
<script src="/Scripts/jquery.unobtrusive-ajax.js" type="text/javascript" />
</head>
<body>
<div id="menucontainer">
<ul id="menu">
<li>
Rutu
</li>
<li>
Employee
</li>
</ul>
</div>
<h2>Create</h2>
<script src="/Scripts/jquery.validate.min.js" type="text/javascript" />
<script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript" />
<form action="/Employee/Create" method="post">
<fieldset>
<legend>EmployeeDetailsModel</legend>
<div class="editor-label">
<label for="EmpName">EmpName</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="EmpName" name="EmpName" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="EmpName" data-valmsg-replace="true" />
</div>
<div class="editor-label">
<label for="DeptId">DeptId</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-number="The field DeptId must be a number." data-val-required="The DeptId field is required." id="DeptId" name="DeptId" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="DeptId" data-valmsg- replace="true" />
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
</form>
<div>
Back to List
</div>
There is a good blog post here that describes how to create an HTML Helper to render the XSLT in a view. You just call the helper class from your view passing in the path to the XSLT and the XML. I have modified this helper so that you can also pass the XSLT and XML as strings to achieve the same results.
MvcContrib project provides an XSLT based view engine http://mvccontrib.codeplex.com/releases - I would suggest to check it out.

Adding button to jQuery Mobile page shows blank page on Windows Phone 7

I'm experimenting with jQuery Mobile and have run into a problem on my Windows Phone 7 browser.
Whenever I add a button to the page, either <input type='button'> or <button>, the whole page doesn't render in the WP7 IE.
When I view the same page in IE7 (using IETester) I get a Script Error "Object doesn't support this property or method" Line 17 Char 45703, and then the page doesn't render.
Here's the html that's generated for my page:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1" /><link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
<script src="http://code.jquery.com/jquery-1.5.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
<title>
iplan
</title></head>
<body>
<div data-role="page" data-theme="b">
<div data-role="header">
<h1>
mobile login</h1>
</div>
<div data-role="content">
ello
<form name="aspnetForm" method="post" action="default.aspx" id="aspnetForm">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTIzNjAxMDE2M2Rk5Yr3L4N9Yyh0TZrUHAh3ZX6rJck=" />
</div>
<label for="ctl00_ContentPlaceHolder1_txtUsername" id="ctl00_ContentPlaceHolder1_lblUsername">Username</label>
<input name="ctl00$ContentPlaceHolder1$txtUsername" type="text" id="ctl00_ContentPlaceHolder1_txtUsername" />
<br />
<label for="ctl00_ContentPlaceHolder1_txtPassword" id="ctl00_ContentPlaceHolder1_Label1">Password</label>
<input name="ctl00$ContentPlaceHolder1$txtPassword" type="password" id="ctl00_ContentPlaceHolder1_txtPassword" />
<br />
<input type="submit" name="ctl00$ContentPlaceHolder1$btnLogin" value="Login" id="ctl00_ContentPlaceHolder1_btnLogin" />
<span id="ctl00_ContentPlaceHolder1_Label2">Boo</span>
</form>
</div>
<div data-role="footer">
© 2011</div>
</div>
</body>
</html>
When I remove that <input type="submit" ... the page renders correctly.
Any ideas?
I had the same problem. Turned out I was using an out of date version of jQuery.
Solved this by using the most recent version.

Resources