Thymeleaf - Button click to call http delete method - spring

I would like to call the url via http delete method. I tried th:onclick and th:action but not working.
html code:
<button id="delete" name="delete" th:onclick="#{'/foos/{id}'(id=${foo.id})}" th:method="delete">Delete</button>
controller code:
#RequestMapping(value="/foos/{id}", method = RequestMethod.DELETE)
#ResponseBody
public String delete(#PathVariable String id) {
studentService.delete(id);
return "Successfully deleted";
}

I think you will need a form for your transaction. And also this hidden input field.
<form action="#" th:action="#{'/delete/{id}'(id=${foo.id})}" th:method="delete" >
<input type="hidden" name="_method" value="delete" />
<button type="submit" id="submitButton"> </button>
</form>

The th:method="delete" creates the hidden input field automatically for you. If you add it manually as well you will have it twice. Check the source code.
I still got the POST Error message after the recommendations here. I found out Spring ignores those hidden fields by default. The solution is to activate it in your application.properties file:
spring.mvc.hiddenmethod.filter.enabled=true
My working code in my application looks like this:
Form:
<form action="#" th:action="#{'/books/delete/{id}'(id=${book.id})}" th:method="delete" >
<button type="submit" class="btn">
Delete
</button>
</form>
Controller:
#RequestMapping(value="/books/delete/{id}", method = RequestMethod.DELETE)
public String deleteBook(#PathVariable Long id) {
bookService.deleteBook(id);
return "books";
}

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";

Thymeleaf th:object does not work with controller?

I am new to Thymeleaf. I am trying to create a search form but it doesn't work. But when I tried manually entering localhost:8080/searchMovies/name and it works fine, so whats wrong with my code?
MovieController.java
#GetMapping("/searchMovies/{name}")
public ModelAndView searchMoviesByNameLike(#PathVariable("name") String name) {
List<Movie> searchMovies = movieService.findMovieByNameContaining(name);
ModelAndView modelAndView = new ModelAndView("searchMovies");
modelAndView.addObject("searchMovies", searchMovies);
modelAndView.addObject("searchMoviesList", movieService.findMovieByNameContaining(name));
return modelAndView;
}
header.html
<form th:object="${searchMovies}" th:action="#{/searchMovies}" method="get" class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="" aria-label="Search" th:value="${name}">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
th:object (generally) isn't used for get requests. You use th:object when you're submitting (w/POST) a form, and you want Spring to populate the properties of a Java object with the fields on that form.
Since Thymeleaf is a server side processed language, and normal html doesn't support building/forwarding to the kind of url you want you're going to have to use JavaScript to accomplish what you want.
For example, a normal GET request when submitted through a form looks like this:
/searchMovies?property1=value1&property2=value2
if you want your url to look like this:
/searchMovies/value1
then you need to use JavaScript to build that url when the user clicks the button and forward to that url.
you need a name at the end of url but in you didn't set it. in this case you can't set it. you must do it by a different approach. another thing is that you need an object in your form not a list. try the following code :
#GetMapping("/searchMovies")
public String sendSearchForm(Model model) {
model.addAttribute("movie", new Movie());
return "search";
}
<form th:object="${movie}" th:action="#{/searchMovies}" method="post" class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="" aria-label="Search" th:field="*{name}">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
#PostMapping("/searchMovie")
public String searchAccounts(#ModelAttribute Movie movie) {
List<Movie> searchMovies = movieService.findMovieByNameContaining(movie.getName());
.
.
.
return modelAndView;

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";
}

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