Multiple submit button in one form - java

I have a controller with request mapping and view where located two buttons "save" and "delete", but they don't do anything. I tried to debug it< but nothing
I used a Spring mvc with thymleaf, I tried a lot of variants, for example : action, individual controller for it, but nothing
<h:form method="post" data-th-action="#{/admin/edit-page/edit}"
th:object="${product}">
<button type="submit" name="action"
value="save">save</button>
<button type="submit" name="action"
value="cancel">cancel</button>
</h:form>
#RequestMapping(value="/admin/edit-page/edit", method=RequestMethod.POST, params="action=save")
public ModelAndView save() {
return null;
}
#RequestMapping(value="/admin/edit-page/edit", method=RequestMethod.POST, params="action=cancel")
public ModelAndView cancel() {
return null;
}
I want to perform an action based on what button was pressed

In the controller methods, your model parameter is missing.
try like bellow
#RequestMapping(value="/admin/edit-page/edit", method=RequestMethod.POST, params="action=save")
public ModelAndView save(#ModelAttribute Product product) {
//assuming Product is your class
return null;
}
// same for delete

Related

Request method GET not supported when deleting

I have a table for adding one object to another and deleting one object from another.
This is my controller:
#Controller
#RequestMapping("/proj/{pid}/coupling/{r1}")
public class CouplingController {
#RequestMapping(method = RequestMethod.GET)
public String getAllCouplings( ){
return "riskCoupling";
}
#RequestMapping(value = "/{r1}", method = RequestMethod.POST)
public String saveCoupling( ){
return "/projects";
}
#RequestMapping(value = "/{r2}", method = RequestMethod.DELETE)
public String removeCoupling(){
return "/projects";
}
}
This is my Thymeleaf view
<td>
<form action = "#" th:action="#{/proj/{pid}/coupling/{r1}/{r2} (pid=${projectID},r1=${r1ID},r2=${r2.id})}" method = "post">
<input type="submit" name="Couple" value="Couple" class="btn btn-info" />
</form>
</td>
<td">
<form action = "#" th:action="#{/proj/{pid}/coupling/{r1}/{r2} (pid=${projectID},r1=${r1ID},r2=${r2.id})}" method = "delete">
<input type="submit" name="RemoveCoupling" value="RemoveCoupling" class="btn btn-info" />
</form>
</td>
When I go to the url /proj/{pid}/coupling/{r1} I get the overview so the GET works.
When I press the Couple button it works. So the POST works.
When I press the RemoveCoupling button I get the error:
Request method "Get" not supported.
I really don't know why I get this error.
Since browsers unfortunately do not support any other verbs than POST and GET in HTML forms, they will just send POST/GET requests instead. This might be the reason why only that one does not work.
See more:
http://martinfowler.com/articles/richardsonMaturityModel.html
http://amundsen.com/examples/put-delete-forms/
http://www.quora.com/HTTP/Why-are-PUT-and-DELETE-no-longer-supported-in-HTML5-forms
I fixed this with Thymeleaf - Button click to call http delete method.
Basically putting a hidden field in my form.

Spring - form with 2 buttons sending to 2 different controllers

I have Spring 4 MVC form with 2 submit buttons. I want these buttons to point to two different controllers. The problem is that one form should have fixed action parameter set.
This is my form:
<form:form method="post" action="pageAction" commandName="id">
<button type="submit" class="btn btn-primary" name="addBasket">
Add Basket
</button>
<button type="submit" class="btn btn-danger" name="addProduct">
Add Product
</button>
</form:form>
Is it possible that these button will reach two different controllers? I am going to send only ID, in addBasket it would be basketId, in addProduct it would be productId. These are the controllers:
#Controller
public class BasketController {
#RequestMapping(value = "/addBasket", method = RequestMethod.POST)
public ModelAndView addBasket(#ModelAttribute("id") Integer id) {
//method - addBasket(id);
}
}
#Controller
public class ProductController {
#RequestMapping(value = "/addProduct", method = RequestMethod.POST)
public ModelAndView addProduct(#ModelAttribute("id") Integer id) {
//method - addProduct(id);
}
}
If you are using html 5 and compatible browsers, you can use form and formaction attributes of buttons to target according to your needs. See details at w3schools
I am not sure if there is a solution you want, but an alternative might be to use an if statement in /addItem checking the value of name:
#Controller
public class ItemController {
#RequestMapping(value = "/addItem", method = RequestMethod.POST)
public ModelAndView addItem(#ModelAttribute("id") Integer id, #ModelAttribute("name") String name) {
if ("basket" == name) {
basketController.addBasket(id);
} else {
productController.addProduct(id);
}
}
}
You can add an onclick event on the submit button, which would call the a javascript function wherein you could decide/change the url as per the requirement.
<button type="submit" class="btn btn-primary" name="addBasket" onClick="javascript:addBasket()">
<button type="submit" class="btn btn-primary" name="addProduct" onclick="javascript:addProduct()">
Add any number of javascript functions like:
function addBasket() {
var requestURL = '/addBasket';
var formData = $("#formName").serialize();
$.ajax({
type: 'POST',
data: formData,
url: requestURL,
success: function (data1) {
//do what is required after success
},
error: function (xhr) {
//in case of failure
}
});
}

Spring MVC, make a button, upon click, return a string value

I am still relatively new to springMVC, I currently have some code, that will take an input from a <form:input> on a jsp page, and create different lists depending on the input(providing I enter the correct String). I would like to transition this into a button instead, so I could have four buttons that will return a different String, for example "one", "two", "three" and "four". That way there is no typing needed from the user.
I see that there is a <form:button> available but I do not know how I could return the String value from this. Also I have looked into angularJS and seen that you can call a function onClick. But again, I don't know what the implementation would have to be to tie it into my Controller. I am just not really sure how I can implement this. Any help would be appreciated.
This is what I have being implemented at the moment :
<form:form commandName="input">
<label>Enter Value</label>
<form:input path="listType" class="inputbox" />
<br>
<input type="submit" class="button" value="Enter" />
</form:form>
This takes the input and stores it in an object :
#Controller
#SessionAttributes("input")
public class EventController {
#RequestMapping(value = "/event", method= RequestMethod.GET)
public String displayEvent (Model model) {
AccessInput userInput = new AccessInput();
model.addAttribute("input", userInput);
System.out.println("finished get method");
return "event";
}
#RequestMapping(value = "/event", method= RequestMethod.POST)
public String processEvent(#ModelAttribute("input")AccessInput userInput) {
System.out.println(userInput.getListType()); //just so I know what value it has
return "redirect:results.html";
}
This is the controller that creates my list based on the string that I pass through to the object
#RestController
#SessionAttributes("input")
public class ReportController {
#RequestMapping(value="/events")
public List<Appliance> getEvents(#ModelAttribute("input")AccessInput userInput) {
List<Appliance> events = new ArrayList<>();
events = ProcessChoice.ofList(userInput.getListType());
System.out.println(userInput.getListType());
return events;
}
}
Edit:
Just to note I have resolved this, I followed the example given by Vipin Dubey, I had to change my controller. I removed the POST method and added in a #RequestParam as a parameter, and redirected the buttons on the event.jsp to "results.html?input=one" then took this value and added it to my model to store it in the session.
#Controller
#SessionAttributes("URLparam")
public class ResultController {
#RequestMapping(value = "/results.html", method = RequestMethod.GET)
public String buttonSelect(Model model, #RequestParam("input")String input) {
model.addAttribute("URLparam", input);
System.out.println(input);
return "result";
}
}
You have two options :
1. Short and recommended way :
Use a link and style it as a button and you can directly call your controller
<a class="btn" href="/events?input=one">One</a>
<a class="btn" href="/events?input=two">two</a>
<a class="btn" href="/events?input=three">three</a>
<a class="btn" href="/events?input=four">four</a>
2. Use jQuery or JavaScript to submit the form based on clicked button using a hidden input field in your form
<!-- Buttons with classes -->
<div id="target">
<button class="one">One</button>
<button class="two">two</button>
<button class="three">three</button>
<button class="four">four</button>
</div>
<!-- Your form -->
<form:form commandName="input" id="myForm">
<input type="hidden" name="inputbox" id="inputbox" value=""/>
</form:form>
// You will have to do this for each of the button which is not a recommended way
$( ".one" ).click(function() {
$('input[name="inputbox"]').val("one");
//var a = $('input[name="inputbox"]').val();
//alert(a);
$( "#myForm" ).submit();
});

Dropdown menu in spring

Ive checked many similar questions but none of them has a working solution in my case.
I'm trying to make a dropdown selection for my user registration form using spring form:select tag. In my bean, country is set as ManyToOne so I pass a map for selecting the value.
Im bouncing between: Neither BindingResult nor plain target object for bean name 'register' available as request attribute. And: commandName not found blabla...
Help me understand what is going on and how to fix it.
It migth be interesting to know that I'm mounting my views through a MergedOutputModel (uses two redirects to mount the view), hence the Session variables.
Code below(simplified to where the problem is appearing).
Controller class:
#Transactional
#Controller
public class RegisterController {
#Autowired
public CountryDao cDao;
#RequestMapping("register")
public String register(Model model, #ModelAttribute("user") User user, BindingResult result, HttpSession session) {
session.setAttribute("user", user);
session.setAttribute("countryList", cDao.getCountryMap());
return "login/registerForm";
}}
View:
<body>
<h1>
<spring:message code="register.message" />
</h1>
[...]
<form:form action="addUser" commandName="register" method="post">
[...]
<spring:message code="register.country" />
<form:select path="country" items="${countryList}" />
[...]
<input type="submit" value="<spring:message code='register.submit'/>" />
</form:form>
</body>
This may get you closer to what you need. Your flow could be slightly different, so you can adjust the page names as needed.
#Controller
#SessionAttributes("countryList") //add whatever session attributes as needed
public class RegisterController {
#RequestMapping("/registerForm", method = RequestMethod.GET)
public String registerGet(Model model) {
model.addAttribute("user", myUserService.createUser());
model.addAttribute("countryList", countryDao.getCountryMap());
return "login/registerForm";
}
#RequestMapping("/registerVerify", method = RequestMethod.POST)
public String registerPost(#ModelAttribute("user") User user,
Errors result) {
if (result.hasErrors()) {
FormValidationLogger.log(log, result);
return "login/registerForm";
}
//persist, send emails, or do whatever
return "registerVerify"; //or whatever page
}
#Autowired
private CountryDao countryDao; //put these at the bottom so we don't have to scroll as much to get to the meat of the code
}
I don't readily see the need for #Transactional in the code you posted. I would expect that in your service or DAO layer.
<body>
<h1>
<spring:message code="register.message" />
</h1>
[...]
<form:form modelAttribute="user" action="/registerVerify" method="post">
[...]
<spring:message code="register.country" />
<form:select path="country" items="${countryList}" />
[...]
<input type="submit" value="<spring:message code='register.submit'/>" />
</form:form>
</body>
This assumes that country is a property of user. You also may want to change the method name to something like getCountries() instead of getCountryMap().

How to have multiple buttons and treat them accordingly in a Spring MVC form?

By using Spring MVC + Maven + Hibernate I'm trying to build a Spring MVC form that has both an "Add To Cart" button, as well as a "Add to Favourites" button. Whenever one button is pressed, the other one returns null as shown in the code below.
Both buttons are type=submit and I'm treating them in the code below. The problem I'm having is that the "Add to Favourites" case is always resulting into an uncaught exception (redirecting me to the "Internal Error" page).
I'm wondering if maybe there's an elegant way to treat each button press in a form separately, without having lots of if - statements for each button.
The HTML file has the following items declared in the form's structure:
<c:if test="${empty readOnly}">
<input type="number" value="1" name="quantity" class="input-mini"/>
<button class="btn btn-primary" type="submit" name="addToCart"><i class="icon-shopping-cart icon-white"><jsp:text /></i> Add</button>
<button class="btn btn-secondary" type="submit" name="favourite"><jsp:text /> Favourite This!</button>
</c:if>
And I'm using the following Controller method:
#RequestMapping(value = "/submit", method = RequestMethod.POST, produces = "text/html")
public String submit(HttpServletRequest request, Model uiModel) {
init(uiModel);
String id = request.getParameter("product-id");
String quantity = request.getParameter("quantity");
if(!request.getParameter("addToCart").toString().equals(null))
{
if (StringUtils.isNotBlank(id) && StringUtils.isNotBlank(quantity)) {
shoppingCartServiceLocal.addToShoppingCart(shoppingCart, id, quantity);
}
}
if(!request.getParameter("favourite").equals(null))
{
//ADD TO FAVOURITE
}
return "redirect:/items/" + id;
}
I might be missing something obvious as I'm still learning these. Any help would be greatly appreciated.
Use the param attribute to specify which method to use for which button.
#RequestMapping(value = "/submit", method = RequestMethod.POST, params = "addToCart")
public String addToCart(HttpServletRequest request, Model uiModel) {
//your code
}
#RequestMapping(value = "/submit", method = RequestMethod.POST, params = "favourite")
public String addToFavorites(HttpServletRequest request, Model uiModel) {
//your code
}

Categories