Thymeleaf dynamic text - spring

I'm using thymeleaf for email templates but text for these templates are from database.
It looks like this:
<html>
<header>
</header>
<body>
Hello <th:block th:text="${dbText}> </th:block>
</body>
</html>
so, property dbText is String from db.
Question: is it possible to somehow store thymeleaf dynamic property in dbText?
I mean, when I fetch dbText it's
"my friend <th:block th:text="${name}"></th:block>"
so when I try to replace name property in thymeleaf it doesn't replace my value instead of name but render this:
"my friend ${name}"

Ideally, you'd want to drop an object into your template via a model, and then access name as a property of that object.
In your controller:
#RequestMapping(value="/your-uri", method = RequestMethod.GET)
public String showName(Model model) {
User someUser = new User("First", "Last");
model.addAttribute("user", someUser);
}
Then in your view:
<p th:text="${user.firstName} + ' ' + ${user.lastName}></p>
This is assuming that your User class has the following:
private String firstName
private String lastName
// getters & setters
This would output:
<p>First Last</p>

Related

How to save tags in database or map n controller

How can I map tag values with controller and save it to DB
<input type="text" name="tags" placeholder="Tags" class="tm-input form-control tm-input-info"/>
<script type="text/javascript">
$(".tm-input").tagsManager();
</script>
#PostMapping("/index")
public String addPRoduct(#RequestParam("name") String name, #RequestParam("tags") List<String> tags, #RequestParam("description") String details ) {
Product product = new Product();
product.setName(name);
product.setTags(tags);
product.setDescription(details);
proRepo.save(product);
return "done";
}
product.setTags(tags) is getting NULL
I want to store multiple tags values in DB which are created once it enter in textbox Please find the screenshot for tags values

Why a Spring MVC model attribute is not (always) accessible in the model?

After reading questions and answers on the topic, such as
Explanation of the model object in Spring
as well as the official documentation of Spring MVC, I still wonder why is a Spring MVC model attribute is not (always) accessible in the model. For example in my code below you can see a Spring MVC Controller class:
#Controller
#RequestMapping("/student")
public class StudentController {
#RequestMapping("/showForm")
public String showForm(Model model) {
Student theStudent = new Student();
model.addAttribute("student", theStudent);
return "student-form";
}
#RequestMapping("/processFormV1")
public String processStudentInput(#ModelAttribute("student") Student student, Model model) {
System.out.println("student.getFirstName(): " + student.getFirstName());
System.out.println("student.getLastName(): " + student.getLastName());
return "student-confirmation";
}
#RequestMapping("/processFormV2")
public String processStudentInput(Model model) {
Student student = (Student) model.getAttribute("student");
System.out.println("student.getFirstName(): " + student.getFirstName());
System.out.println("student.getLastName(): " + student.getLastName());
return "student-confirmation";
}
}
and this is my view, student-form.jsp:
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<title>Student Form</title>
</head>
<body>
<form:form action="processFormV2" modelAttribute="student">
First name: <form:input path="firstName"/>
<br>
Last name: <form:input path="lastName"/>
<input type = "submit" value="Submit"/>
</form:form>
</body>
</html>
Now, when the form action is processFormV2 and I submit the form, the line below gives me a null for the student:
Student student = (Student) model.getAttribute("student");
However, when I change the form action to processFormV1 and I submit the form, in the controller method I am able to read the provided values for both names of the Student correctly.
Why is this so?
What is the scope of the values in a Model? Request or Session? From what I have, I always thought the scope is session. Is that right?

Spring form elements, multiple nestedPath and referencing inputs with Javascript

I have complex form objects, with unlimited depth and I'm trying to edit them on jsp with spring form tags.
Main modelAttribute is bind to spring form, and while I'm iterating through childs, I use nestedPath and everithing works OK. As result I have generated input names something like:
name="elements['secondColumn'][0].elements[0].removed"
Problem is that I can not know the generated name. Why I need it? Let's say that I have delete button from which I want to set appropriate field "removed" to 1.
Update:
How does it works? I am using tag files which are recursively calling them self.
container.tag
<c:forEach items="${elements}" var="element" varStatus="index">
<spring:nestedPath path="elements[${index.count - 1}]">
<my:elementConfig element="${element}">
<my:container elements="${element.elements}"/>
</my:elementConfig>
</spring:nestedPath>
</c:forEach>
elementConfig.tag
...
<form:hidden path="removed"/>
...
<button onclick="delete('howToGetNameOfRemovedHidden')">Delete</button>
...
<jsp:doBody/>
...
Closest match I allready found is a "nestedPath" pageContext attribute, but it contains the name of the modelAttribute (form) name too.
Is there official way to get the generated name?
Thanks
I guess you could go through additional attributes, using for example the HTML5 data-* one:
<c:set var="i" value="0" />
<c:foreach [...]>
<form:input path="[...].remove" data-inputid="input${i}" />
<button class="removebutton" data-inputid="input${i}">Remove</button>
<c:set var="i" value="${i + 1}" />
</c:foreach>
Then, using jQuery for example:
$(function() {
$(".removebutton").click(function() {
var dataInputId = $(this).data("inputid");
$("input[data-inputid='" + dataInputId + "']").val(1);
});
});
But don't forget: if you have nested loops, the data-input should there be unique through the whole document.
As it seems there is no official support for getting generated input names, so I've made a function which handles it. It is based on a functionality I found in Spring form tag library.
Static methods:
public class JspUtils {
public static String escapeJS( String value) {
return StringEscapeUtils.escapeJavaScript( value);
}
public static String getPath( PageContext pageContext, String name) {
String path = (String)pageContext.getRequest().getAttribute( "nestedPath");
if (path == null)
path = (String)pageContext.getAttribute( "nestedPath");
if (path == null)
return name;
path = path.substring( path.indexOf( ".") + 1);
path += name;
return path;
}
public static String getPathJsEscaped( PageContext pageContext, String name) {
return StringEscapeUtils.escapeJavaScript( getPath(pageContext, name));
}
}
tld definition:
<function>
<description>
Get nested path value as string
</description>
<name>getPath</name>
<function-class>com.pathfix.JspUtils</function-class>
<function-signature>java.lang.String getPath(javax.servlet.jsp.PageContext, java.lang.String)</function-signature>
</function>
<function>
<description>
Get nested path value as javascript escaped string
</description>
<name>getPathJsEscaped</name>
<function-class>com.pathfix.JspUtils</function-class>
<function-signature>java.lang.String getPathJsEscaped(javax.servlet.jsp.PageContext, java.lang.String)</function-signature>
</function>
Example usage:
<%# taglib prefix="pathfix" uri="http://pathfix.com"%>
Name: <form:input path="name"/>
Test it!

How to create string template with validation message and watermark in MVC 3

I'd like to create template for string, that will include label, textbox with watermark and validation message for registration form.
In addition, I'd like to add notice (eg. star), that the field is required by getting it from model.
So far I have created file string.cshtml in ~/Views/Account/EditorTemplates containing this:
<span class="editor-label>#Html.Label(ViewData.ModelMetadata.Watermark)</span>
<span class="editor-field">#Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { placeholder = ViewData.ModelMetadata.Watermark })</span>
<span class="error_message">#Html.ValidationMessage(ViewData.ModelMetadata.PropertyName)</span>
Model looks like this:
[Required]
[DataType(DataType.Text)]
[Display(Prompt = "First name")]
public string FirstName { get; set; }
And in view I call it as follows:
#Html.EditorFor(m => m.FirstName)
Does anyone have any idea, where do I go wrong?
Your editor template must be called Text.cshtml and not String.cshtml because you use the [DataType(DataType.Text)] attribute.
You could also specify a custom name for the editor template using the UIHint attribute:
[Required]
[DataType(DataType.Text)]
[Display(Prompt = "First name")]
[UIHint("Foo")]
public string FirstName { get; set; }
and now you could have ~/Views/Account/EditorTemplates/Foo.cshtml.
Andree,
Your problem for not showing the message is this line:
<span class="error_message">#Html.ValidationMessage(ViewData.ModelMetadata.PropertyName)</span>
If you look at your rendered HTML source, you see something like the following:
<span class="field-validation-error" data-valmsg-for="<className>.FirstName" data-valmsg-replace="true"></span>
Notice, that it's including the class in the data attribute. However, ubobtrusive doesn't match this. What you need rendered is simply:
<span class="field-validation-error" data-valmsg-for="FirstName" data-valmsg-replace="true"></span>
In order to accomplish this, change your code in your editor to:
#Html.ValidationMessageFor(v => v)
Likewise, to make you code easier to read, both of these also work for your other code...
#Html.LabelFor(v => v)
#Html.TextBoxFor(v => v, new { placeholder = ViewData.ModelMetadata.Watermark })

#RequestBody being set but not sure how

So this is a super novice question. Im running this tutorial and in some of the methods like this:
#RequestMapping(value="/string", method=RequestMethod.POST)
public #ResponseBody String readString(#RequestBody String string) {
return "Read string '" + string + "'";
}
where there is a string as a requestbody, the string is foo but i don't know how it is set. Is there some method somewhere that sets a default or what (maybe i'm missing something super obvious). The html looks like this
<form id="readString" class="textForm" action="<c:url value="/messageconverters/string" />" method="post">
<input id="readStringSubmit" type="submit" value="Read a String" />
</form>
Thanks for any help you can provide.
As far as I understand the "#RequestBody String string" variable is being set by Spring when you submit your html form using the using post request method.

Resources