How to pass only string in thymeleaf form? - spring

I have a little problem. When I have an object with some fields, it's easy to pass these fields through form:
Controller:
#RequestMapping("/")
public String hello(Model model) {
model.addAttribute("test", Test);
return "index";
}
html:
<form th:action="#{/process}" method="post" th:object="${test}">
<input type="text" th:field="*{value}"/>
<input type="submit" />
</form>
But what if I don't want to have an object and pass only string? Something like that:
Controller:
#RequestMapping("/")
public String hello(Model model) {
model.addAttribute("test", "test string");
return "index";
}
html:
<form th:action="#{/process}" method="post">
<input type="text" th:field="${test}"/>
<input type="submit" />
</form>
doesn't work.
Thanks for help!
For next question in comments:
index.html:
<form th:action="#{/process}" method="post">
<textarea th:text="${sourceText}"/>
<input type="submit" />
ggg.html:
<textarea th:text="${sourceText}"/>
controller:
#RequestMapping("/")
public String hello(Model model) {
model.addAttribute("sourceText", "asdas");
return "index";
}
#RequestMapping("/process")
public String process(Model model, #ModelAttribute(value = "sourceText") String sourceText) {
return "ggg";
}

th:field is used only if you declare object like th:object.
<form th:action="#{/process}" method="post">
<input type="text" th:value="${sourceText}" name="sourceText"/>
<input type="submit" />
</form>
Spring matches values by "name" attribute. Just catch it with #RequestParam in controller like
#RequestMapping("/process")
public String process(Model model, #RequestParam String sourceText) {
return "ggg";
}

According how Spring MVC works you can't use a string as an object in a form, you need an object to encapsulate that string, because the form structure is Object and then any field linked to it.
In your case, I would create a view form object for those common situations, something like formView with the String attribute text. And you could use the same object in similar situations.
Other option if you don't want to create this extra object, you could send the data by AJAX, and build the data array to send to the controller in javascript.
Personally I would go for the first option, is more reusable.
Hope this help you

Related

Spring Web application tymeleaf : POST request directed to wrong address

I have post mapping for URL: "/bank/addnew" My controller looks like:
Upon submission the form is submitted to "http://127.0.0.1:8082/banks/%20/banks" However, I need it to go to "http://127.0.0.1:8082/banks/addnew". Thanks for the Help!
#Controller
public class BankController {
#Autowired private BankService bankService;
#GetMapping("/banks")
public String bankList() {
return "bank/bank_list";
}
#PostMapping(value="/banks/addnew")
public String addNew(Bank bank) {
bankService.save(bank);
return "redirect: /banks";
}
}
And my template:
<form method="POST" action="#" th:action="#{/banks/addnew}" >
<div class="form-group">
<label for="recipient-name" class="col-form-label">Bank Name:</label>
<input type="text" class="form-control" id="recipient-name" name="name">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
The Post Method was actually working okay. I checked it by printing the Model object inside the target controller. However, it was being submitted to the database a NULL value because I didn't initialize getters and setters for my Model. Finally, there was a space in the return string, thus I removed it.
The controller Should have a return statement with no space.
return "redirect:/banks";

Controller Not receiving value from span in HTML using Spring boot and Thymeleaf

I have the following content in my HTML which is using Thymeleaf
<form action="#" th:action="#{/shutDown}" th:object="${ddata}" method="post">
<span>Domain</span>
<span th:text="${domain}" th:field="*{domain}">domain</span>
<input type="Submit" value="close" />
</form>
And I have the following in my Controller which is using Sprint Boot
#RequestMapping(value = "/shutDown", method = RequestMethod.POST)
public ModelAndView shutDownPage(ModelAndView modelAndView, Authentication authentication,
#ModelAttribute("ddata") DInputBean dInputBean) {
String domain = dInputBean.getdomain();
return modelAndView;
}
I'm hoping I'd get value of domain from the HTML in the Controller but it's always null. DInputBean has getters and setters for "domain" field.
The th:field attribute can be used on <input>, <select>, or, <textarea>.
A solution you could possibly replacing you second <span> with a hidden input element.
<form action="#" th:action="#{/shutDown}" th:object="${ddata}" method="post">
<span>Domain</span>
<input type="hidden" th:field="*{domain}" th:value="${domain}" />
<input type="Submit" value="close" />
</form>
If you wanted to keep the second div, just place the <input type="hidden"> inside the second <span> and remove the th:field attribute from the second <span>.
Edit:
If you wanted to add the value of domain in a span.
<form action="#" th:action="#{/shutDown}" th:object="${ddata}" method="post">
<span>Domain</span>
<span th:text="${domain}">domain<span>
<input type="hidden" th:field="*{domain}" th:value="${domain}" />
<input type="Submit" value="close" />
</form>
http://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#inputs
An option is to use a read-only input field:
<input type="text" th:field="*{domain}" th:value="${domain}" readonly="readonly"/>
This both displays the value and sends it on submit.
The key is to add the value of the domain variable to the form:
#GetMapping("/shutDownPage")
public String shutDownPage(Model model) {
model.addAttribute("ddata" new Ddata()); //or however you create your bean
String username = ... //however you get your username
String domain = myRepositoryService.findDomainByUsername(username);
model.addAttribute("domain", domain);
return "shutDownPage";
}
Include an HTML page in the action so that when you open the HTML page in a browser without a server/container, the button will still appear to work:
<form action="confirmationPage.html" th:action="#{/shutDown}" th:object="${ddata}" method="post">
<!-- You can benefit from using a conditional expression -->
<span th:text="${domain != null ? domain : 'No domain supplied'}">[domain]</span>
<input type="hidden" th:field="*{domain}" th:value="${domain}"/>
<input type="Submit" value="close"/>
</form>
And your post method:
#PostMapping("/shutDown") //use shorthand
public String shutDownPagePost(#ModelAttribute("ddata") DInputBean dInputBean {
String domain = dInputBean.getDomain();
//do whatever with it
return "confirmationPage";
}

how to pass checkbox value from jsp to java class

I have in my jsp page some checkbox and I want to pass in my spring controller the checked ones.
insertTaskInformation.jsp
<body>
<div align="center">
<strong> <strong>Title:</strong>${task.title} <form:form
action="addSymbol" method="post" name="catch">
<c:forEach var="symbol" items="${symbols}">
<input type="checkbox" name="id" value="${symbol.type} }">${symbol.type}<BR>
</c:forEach>
<input type="submit" value="Submit">
</form:form>
</strong>
</div>
</body>
taksController.java
#RequestMapping(value="/addSymbol", method = RequestMethod.POST)
public String addSymbol() {
return "administration/taskRecap";
}
You can use spspring:form library and you add in your controller something like this :
#PostMapping("/greeting")
public String greetingSubmit(#ModelAttribute Greeting greeting) {
return "result";
}
And In your first controller, you add an attribute to the model with model.addAttribute(new greeting() ) so the full code will be
#RequestMapping(value="/addSymbol", method = RequestMethod.POST)
public String addSymbol(Model model) {
model.addAttribute(new greeting() )
return "administration/taskRecap";
}
For more information check here

Passing parameters from JSP to controller - Spring MVC

I have a little problem when I want to pass parameter to my controller.
I have one method in controller:
#RequestMapping("/redirect")
public String print(String type, HttpServletRequest servletRequest)
{
String path = "redirect:" + servletRequest.getParameter("type");
return path;
}
And I have some buttons in my jsp file:
<form method="post" action="/WWP/redirect">
<button onclick=" <input type="text" name="type" value="/developer"/>">Developer</button>
<button onclick=<input type="text" name="type" value="/graphic"/>>Graphic</button>
<button onclick=" <input type="text" name="type" value="/cleaner"/>">Cleaner</button>
</form>
In this way I have 3 buttons and when for example I press Developer button variable "type" is "/developer" and I'm sending it to controller. But now my buttons look like this:
http://imageshack.us/photo/my-images/854/buttonspx.png/
It works correct, but I can't get rid this HTML tag and it's really nervous. How to do this? Or how send value to controller in different way. Thanks in advance.
Instead of normal buttons you can have submit buttons and handle them in controller as below
<input type="submit" value="Developer" name="developer"></input>
<input type="submit" value="Graphic" name="graphic"></input>
<input type="submit" value="Cleaner" name="cleaner"></input>
And you can have different methods in the controller class for each of the buttons clicked using the params attribute like this
#RequestMapping(value = "/redirect", method = {RequestMethod.POST}, params = "developer")
public ModelAndView developerMethod(){
}
#RequestMapping(value = "/redirect", method = {RequestMethod.POST}, params = "graphic")
public ModelAndView graphicMethod(){
}
#RequestMapping(value = "/redirect", method = {RequestMethod.POST}, params = "cleaner")
public ModelAndView cleanerMethod(){
}

Portlet:actionurl is not going to #Actionmapping in controller

I am using Liferay portal-6 with Spring-3.
In my portlet, first it goes to the #Rendermapping without params and displays the default jsp,
when I click on a button I am passing the actionurl, but its not going to the corresponding #Actionmapping.
My searchForm.jsp looks like this:
<portlet:actionURL var="showSearchResultsUrl">
<portlet:param name="myaction" value="searchResults" />
</portlet:actionURL>
<form:form id="searchForm" name="searchForm" commandName="patientStoryForm" method="POST" action="${showSearchResultsUrl}" enctype="multipart/form-data" >
<input type="button" name="search_btn" value="Search"/></td>
</form:form>
My controller is like this:
#Controller(value = "searchPatientStoryController")
#RequestMapping(value = "VIEW")
#SessionAttributes(types = PatientStoryForm.class)
public class SearchPatientStoryController {
#RenderMapping
public String showSearchForm(RenderResponse response, Model model) {
return "searchForm";
}
#RenderMapping(params = "myaction=searchResultsForm")
public String showSearchResultsForm(RenderResponse response, Model model) {
return "searchResultsForm";
}
#ActionMapping(params = "myaction=searchResults")
public void searchResults(
#ModelAttribute(value = "patientStoryForm") PatientStoryForm patientStoryForm,
BindingResult bindingResult, ActionResponse response, ActionRequest request,
SessionStatus sessionStatus, Model model) {
response.setRenderParameter("myaction", "searchResultsForm");
}
}
When I click on button in searchForm.jsp it is supposed to go to #Actionmapping but it is not going.
Please help me.
Thanks in advance.
You would need to submit the form in order to invoke the associated action method.
However, in the jsp code, I see the below code which indicates that it is just a button.
<input type="button" name="search_btn" value="Search"/>
In order to submit the form, you can do either of the following ways:
Use a submit button instead of a normal form button like this:
<input type="submit" name="search_btn" value="Search"/>
Invoke a javascript function on click event of the button and submit the form:
<script type="text/javascript">
function submitForm(form){
var actionUrl = '<portlet:actionURL var="showSearchResultsUrl"><portlet:param name="myaction" value="searchResults"/></portlet:actionURL>';
form.action = actionUrl;
form.submit();
}
</script>
and
<input type="button" name="search_btn" value="Search" onclick="javascript:submitForm(this.form)"/>
Can you try replacing your actionURL like the following
<portlet:actionURL name="searchResults" var="showSearchResultsUrl">
<portlet:param name="myaction" value="searchResults" />
</portlet:actionURL>
You need to set the action of your form, something like this:
<form:form action="<%=showSearchResultsUrl%>" id="searchForm" name="searchForm" commandName="patientStoryForm" method="POST" action="${showSearchResultsUrl}" enctype="multipart/form-data" >
<input type="button" name="search_btn" value="Search"/></td>
This way your action name will be "myaction" with the value "searchResults" as your mapping on the controller side.

Resources