create.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" type="text/css" href="/css/main.css" />
</head>
<body>
<a th:href="#{/admin/}">Admin</a>
<br>
<br>
<br>
<h1>Add core phrases to the database</h1>
<br>
<br>
<form method="POST" th:object="${corePhrasesCreateForm}">
<table>
<tr>
<td>Quotation cluster (" "):</td>
<td><input
type="number"
id="quotation-cluster"
name="quotation-cluster"
th:value="${quotationCluster}"/></td>
<td th:if="${#fields.hasErrors('quotationCluster')}" th:errors="*{quotationCluster}">quotationCluster</td>
</tr>
<tr>
<td>Quotation Exclamation cluster ("!")</td>
<td><input
type="number"
id="quotation-exclamation-cluster"
name="quotation-exclamation-cluster"
th:value="${quotationExclamationCluster}"/></td>
<td th:if="${#fields.hasErrors('quotationExclamationCluster')}" th:errors="*{quotationExclamationCluster}">quotationExclamationCluster</td>
</tr>
<tr>
<td>Phrases</td>
<td><textarea rows="5" cols="60" name="value" placeholder="Key phrases" th:text="${value}"></textarea></td>
<td class="error" th:if="${#fields.hasErrors('value')}" th:errors="*{value}">value</td>
</tr>
</table>
<br/>
<input type="submit" value="submit"/>
</form>
</body>
</html>
Validator
import com.example.marketing3.semantics.semanticsClusters.repositories.ClusterRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
#RequiredArgsConstructor
#Service
public class CorePhraseFormValidator implements Validator {
private final ClusterRepository clusterRepository;
#Override
public boolean supports(Class<?> clazz) {
return false;
}
#Override
public void validate(Object target, Errors errors) {
System.out.println();
}
Controller
#Controller
#RequestMapping("/semantics/phrases/core")
#RequiredArgsConstructor
public class CorePhraseController {
#GetMapping({"/create", "/create/"})
public String createGet(CorePhrasesCreateForm corePhrasesCreateForm) {
return "semantics/phrases/core/create";
}
#PostMapping({"/create", "/create/"})
public String createPost(#Valid CorePhrasesCreateForm corePhrasesCreateForm,
BindingResult bindingResult,
RedirectAttributes atts) {
corePhraseFormValidator.validate(corePhrasesCreateForm, bindingResult);
if (bindingResult.hasErrors()) {
return "semantics/phrases/core/create";
}
atts.addAttribute("message", "Core phrases created");
String result = "";
return "redirect:/general/message";
}
}
The form has been rendered.
I entered
Quotation cluster (" "): 1
Quotation Exclamation cluster ("!"): 2
And some text for phrases.
Like this:
The problem:
To createPost quotationCluster and quotationExclamationCluster came as zeroes.
But I entered 1 and 2 respectively.
Could you help me understand what I have don wrongly and correct the situation.
Change
<input type="number" id="quotation-cluster"
name="quotation-cluster" th:value="${quotationCluster}"/>
To:
<input type="number" id="quotation-cluster" th:field="*{questionCluster}"
name="quotationCluster" th:value="${quotationCluster}"/>
the name and th:field should be same as the declared attribute in your java class CorePhraseForm. Repeat this for the the next input (Textarea).
Related
Hi I'm having some trouble retrieving information from the user using a spring controller.
the controller looks like this:
#Slf4j
#Controller("indexController")
public class IndexController {
List<String> userInput = new ArrayList<>(Arrays.asList(new String[]{"Apple", "Blackberry", "Strawberry"}));
public List<String> getUserInput() {
return userInput;
}
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String home(
Model model
){
log.info("home path was hit");
model.addAttribute("options", getUserInput());
model.addAttribute("option", new Object());
return "index";
}
#RequestMapping(value = "createOrder", method = RequestMethod.POST)
public String placeUserOrder(
Model model,
#ModelAttribute("option")String usersInput
){
log.info("createOrder path was hit");
log.info(usersInput);
return "redirect:/home";
}
the index.thml within re main/resource/templates folder looks like this:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>home page</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h2>your orders are:</h2>
<form method="post" action="/createOrder" th:object="${order}">
<th:text alignment-baseline="text-before-edge" aria-atomic="true" > select a copybook</th:text>
<select class="from-control" id="dropDownList">
<option value="0">select copybook</option>
<option th:each="option : ${options}" th:value="${option}" th:text="${option}" >
<input type="hidden" name="${_csrf.usersChoiceFromThymeleaf}" value="${_csrf.token}" />
</option>
<input type="submit" name="createOrder" value="place">
</select>
</p>
</p>
</form>
<th:block th:each="order : ${orders}">
<tr>
<td th:text="${order.value}"></td>
</tr>
</th:block>
</body>
</html>
every time after i set a breakpoint within the post function the option value is empty.
what am i doing wrong?
shouldnt i expect a string from selected dropdown menu?
i tried to fetch an int and it remains empty as well
the model contains also only 2 key value pairs "option"->""
and org.springframework.validation.BindingResult.option -> {BeanPropertyBindingResult#7472} "org.springframework.validation.BeanPropertyBindingResult: 0 errors"
I am building an App where a new website can be added to the list and I would now like to be able to redirect the user to this given website. How do I do that?
For example, a user can add to the list: www.example.com. Clicking the link (inside Index.html) will take the user to the example homepage.
index.html is where I would like the link to appear to the user
<td><a th:href="#{'/website.link'}">Link</a></td>
new.html page can add links
<div alight="left">
<tr>
<label class="form-label">Link</label>
<td><input type="text" th:field="*{link}" class="form-control"
placeholder="Link" /></td>
</tr>
</div>
Notice I don't have anything in the Controller yet.
Consider a Contr-application like:
#Controller
#SpringBootApplication
public class Application {
private final List<URI> allLinks = Collections.synchronizedList(new ArrayList<>());
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#ModelAttribute("allLinks")
public List<URI> allLinks() {
return allLinks;
}
#GetMapping("/")
public String index() {
return "index";
}
#PostMapping(value = "/", params = "send")
public void sendMeThere(#RequestParam String link, HttpServletResponse response) throws IOException {
// response send redirect! (relative/absolute/throws exception)
response.sendRedirect(link);
}
#PostMapping(value = "/")
public String addLink(#RequestParam String link) throws URISyntaxException {
links.add(new URI(link)); // throws exception!
return "redirect:/";
}
}
We can try it out with an index.html like this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" lang="en">
<head>
<title>Hello Links</title>
</head>
<body>
<h2>Add More Lnks</h2>
<form action="" th:action="#{/}" method="post">
<label>Link</label>
<input type="text" name="link"
placeholder="http://www.example.com" />
<input type="submit" value="Add Link" />
</form>
<hr/>
<h2>Naviagte via form submit</h2>
<form action="" th:action="#{/}" method="post">
<select name="link">
<option th:each="link : ${allLinks}" th:value="${link}" th:text="${link}" />
</select>
<input type="submit" value="Send me There" />
<input type="hidden" name="send" />
</form>
<hr/>
<h2>Naviagte via link</h2>
<ul>
<li th:each="link : ${allLinks}">
<!-- encapsulate ${link} in thymeleaf url #{...} (relative or absolute) -->
<a th:href="#{${link}}" th:text="${link}"/>
</li>
</ul>
</body>
</html>
It looks like:
References:
HttpServletResponse#sendRedirect
Thymeleaf URL Syntax
In the post "Hello World" phase of my Spring journey. Creating an app that POSTS two fields which RESULT in three fields.
My controller has three fields. Two are populated on POST, and all three should populate the RESULT fields.
The Controller:
#Slf4j
#Controller
public class GreetController {
#GetMapping("/greeting")
public String greetingForm(Model model) {
model.addAttribute("greeting", new Greeting());
}
#PostMapping("/greeting")
public String greetingSubmit(#ModelAttribute Greeting greeting, Model model) {
model.addAttribute("greeting", greeting);
}
}
The Model:
public class Greeting {
//fields correspond to greeting.html
private long id;
private String content;
private String numbah;
public String getNumbah() { return numbah; }
public void setNumbah() {
this.numbah = SomeFunctions.functionOne(this.getContent());
}
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public String getContent() { return content; }
public void setContent(String content) { this.content }
}
The View:
<!DOCTYPE HTML>
this is greeting.html
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Getting Started: Handling Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Form</h1>
<!--th.fields correspond to fields in th.object (ie greeting.java)-->
<form action="#" th:action="#{/greeting}" th:object="${greeting}" method="post">
<p>Id: <input type="text" th:field="*{id}" /></p>
<p>Message: <input type="text" th:field="*{content}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<h1>Result</h1>
<p th:text="'id: ' + ${greeting.id}" />
<p th:text="'content: ' + ${greeting.content}" />
<p th:text="'numbah: ' + ${greeting.numbah}" />
Submit another message
</body>
</html>
Note:
The ${greeting.numbah} field, as configured above, is resulting in null. I had a log statement in that function that never returned anything, indicating that the function in the model is never firing. However, when the view was configured like this...
<body>
<h1>Form</h1>
<!--th.fields correspond to fields in th.object (ie greeting.java)-->
<form action="#" th:action="#{/greeting}" th:object="${greeting}" method="post">
<p>Id: <input type="text" th:field="*{id}" /></p>
<p>Message: <input type="text" th:field="*{content}" /></p>
<p>Some Number: <input type="text" th:field="*{numbah}"></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<h1>Result</h1>
<p th:text="'id: ' + ${greeting.id}" />
<p th:text="'content: ' + ${greeting.content}" />
<p th:text="'numbah: ' + ${greeting.numbah}" />
Submit another message
</body>
...the field was populating, so the function itself....functions.
Long short, what I'm attempting to do here is take id and content, do someFunction(content)=numbah and return id, content, and numbah.
Thank you in advance.
It always gets down to something simple, doesn't it?
There was a typo in the setNumbah constructor in the model.
This is why I hardly ever post on sites like this: because you almost always figure out what you did wrong if you just sleep on it and have another look.
Thanks for checking this out and apologies that it's not a "high quality" problem/answer. Will delete if that's the protocol for a self-answered question.
This has been asked a few times but all of them did not answer my question. I have been trying to get different functionalities to work with Thymeleaf for two days now and been very unsuccessful. I have only been able to get it to work with spring-boot, however right now I am using spring-MVC.
First I will show you my dependencies
<%# taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Create a New Account</title>
<link th:href="#{/resources/css/loginForm.css}" href="/resources/css/loginForm.css" rel="stylesheet"
type="text/css"/>
</head>
<body>
<form action="#" th:action="#{/createNewAccount}" th:object="${user}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{username}" /></td>
<td th:if="${#fields.hasErrors('name')}" th:errors="*{username}">Name Error</td>
</tr>
<tr>
<td>Password:</td>
<td><input type="text" th:field="*{password}" /></td>
<td th:if="${#fields.hasErrors('age')}" th:errors="*{password}">Password Error</td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
</html>
Now so you can see the errors my intellij IDE is showing:
User.java
package com.practice.domain;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* Created by DrewJocham on 8/30/15.
*/
public class User {
#NotNull
#Size(min = 2, max = 30)
private String username;
#NotNull
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
The field name you call hasErrors with needs to match the field name in the object. Like so:
<td th:if="${#fields.hasErrors('username')}" th:errors="*{username}">Name Error</td>
Note that hasErrors('name') became hasErrors('username'), and:
<td th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password Error</td>
Note that hasErrors('age') became hasErrors('password').
As for the errors being highlighted in Intellij, I think they're misleading, and are related to this open issue: https://youtrack.jetbrains.com/issue/IDEA-132738
I have three fields department_Id,department_Name,department_location in departmentForm act as a model object in this model form.
I have use annotation to validate the fields. Now, I want to only use two fields in different jsp page say create.jsp and one field in different jsp page say getDepartmentById.
When I press submit button of create.jsp, validation is happening but after providing correct information its not submitted cause in this page.
I haven't give one field department_Id which is auto generated by my DAO layer. So, please help me, how to reject this value to execute my create.jsp page for successfully creating department in database.
When I printed the BindingResult object, it shown as follow:
Field error in object 'departmentForm' on field 'departmentId': rejected value [null];
codes [NotEmpty.departmentForm.departmentId,NotEmpty.departmentId,NotEmpty.java.lang.String,NotEmpty];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable:
codes [departmentForm.departmentId,departmentId]; arguments [];
default message [departmentId],org.hibernate.validator.constraints.NotEmpty.message},
[Ljava.lang.Class;#4fc4a198,[Ljava.lang.Class;#764d2b11];
default message [may not be empty]`
This is how I coded in controller:
#RequestMapping(value = "/createDepartment", method = RequestMethod.POST)
public String createEmployee(#Valid DepartmentForm departmentForm,
BindingResult bindingResult, Map<String, DepartmentForm> model)
throws Exception {
if (bindingResult.hasErrors()) {
System.out.println(bindingResult);
bindingResult.reject(departmentForm.getDepartmentId());
return "departmentForm";
}
System.out.println("mr ankur jadiy");
model.put("departmentForm", departmentForm);
departmentForm.setUpdateStatus('A');
if (departmentForm.getUpdateStatus() == 'A') {
departmentServiceImpl
.actionDecider(convertDeptFormToDeptBO(departmentForm));
}
return "Success";
}
my DepartmentForm code is as follow:
package com.nousinfo.tutorial.model;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
public class DepartmentForm {
#NotEmpty
#Size(min = 1, max = 20,message="")
private String departmentId;
#NotEmpty
private String departmentName;
private String departmentLocation;
private Character updateStatus;
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public String getDepartmentLocation() {
return departmentLocation;
}
public void setDepartmentLocation(String departmentLocation) {
this.departmentLocation = departmentLocation;
}
public Character getUpdateStatus() {
return updateStatus;
}
public void setUpdateStatus(Character updateStatus) {
this.updateStatus = updateStatus;
}
}
and my create.jsp is
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://jakarta.apache.org/taglibs/input-1.0" prefix="input"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="s"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Create Department</title>
<link rel="stylesheet" href="css/style.css" type="text/css"></link>
</head>
<body>
<table width="1254" height="74" border="0" align="center">
<tr>
<td width="300" height="68" align="center" bgcolor="#99CCFF"><h2>
<span class="style1">Employee Details </span>
</h2></td>
<td width="100" height="68" align="center" bgcolor="#FFFFFF"><img
src="./image/emps.jpg" width="190" height="92" /></td>
</tr>
</table>
<p>
<br />
</p>
<hr size="1" width="786">
<form:form id="form" method="post" action="/EmployeeWebSpring/departmentController/createDepartment"
modelAttribute="departmentForm">
<table>
<tr>
<form:hidden path="updateStatus" />
</tr>
<tr>
<td>
Department_Name:
<font color="red"><form:errors path="departmentName" /></font>
</td>
</tr>
<tr>
<td><form:input path="departmentName" /></td>
</tr>
<tr>
<td>
Department_Location:
<font color="red"><form:errors path="departmentLocation" /></font>
</td>
</tr>
<tr>
<td><form:input path="departmentLocation" /></td>
</tr>
</table>
<br>
<br />
<p> </p>
<br>
<tr>
<td><input type="submit" name="method" value="save" /></td>
<td><input type="submit" name="method" value="cancel" /></td>
</tr>
<hr size="1" width="786">
<p> </p>
</form:form>
</body>
</html>
What the error says is that you're missing value for departmentId, which is not surprising since you defined it as
#NotEmpty
#Size(min = 1, max = 20,message="")
You don't really need to validate departmentId if it's autogenerated by your code. You probably should remove it from the DepartmentForm, especially since it's not in the form, or at least make it optional.
You can make it mandatory in your business object, but the form backing object should reflect what's in the form.
update
If departmentId is a database-generated id, you should set it as disallowed in your controller's InitBinder:
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(new String[] { "departmentId" });
}