Spring Boot with Thymeleaf post list - spring-mvc

I want to post a list of strings to my controller.
But it always only take the first selected value.
my thymeleaf html form:
<form action="/add" method="post">
<div class="form-group">
<label for="roleId">ID</label> <input type="text" class="form-control" id="roleId" name="id" required="required" />
</div>
<div class="form-group">
<label for="rolePrivileges">Privileges</label>
<select class="form-control" id="rolePrivileges" name="privileges" multiple="multiple" size="10" required="required">
<option th:each="type : ${privilegesList}" th:value="${type}" th:text="${type}">Privilege</option>
</select>
</div>
<button type="submit" class="btn btn-default">Create</button>
</form>
my controller:
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addSomething(Model model, #ModelAttribute("id") String id,
#ModelAttribute("privileges") List<String> privileges) {
// add something with a service
return "redirect:/roles";
}

I think you have to Annotate the privilges with
#RequestParam("privileges")
It is not a ModelAttribute but you receive it from the request
Edit: two SO threads to better understand the difference between #RequestParam and #ModelAttribute.

Related

How to pass a js variable to the controller in ASP.NET Core

I am sending an id in my js code and I want to pass that variable to my controller. Any advice on how I can do that?
<input class="btn_confirm" type="submit" id={i}
onclick="id_click(this.id)" value="Delete" />
var id;
function id_click(clicked_id) {
id = clicked_id;
}
I tried different things but nothing worked out.
I tried as below:
Model:
public class ReceiveModel
{
public int Id { get; set; }
public string Name { get; set; }
public string SomeKey { get; set; }
}
View:
<div class="row">
<div class="col-md-4">
<form id="form" asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<input id="1" type="submit" value="Create" class="btn btn-primary" />
</div>
<div class="form-group">
<input id="2" type="submit" value="Create" class="btn btn-primary" />
</div>
<div class="form-group">
<input id="3" type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
$("input[type='submit']").click(function ()
{
var tempid = this.id
var tmpInput = $("<input type='text' name='SomeKey' hidden/>");
tmpInput.attr("value", tempid );
var form = $("#form")
form.append(tmpInput)
form.submit()
})
</script>
Result:
You can lookup API requests. If you want to send one parameter as a primitive type (string, integer, etc.) you can use query strings in your API calls. For example, let's assume you have an API endpoint like this: localhost:5000/api/YourController. You can send params via API get calls like this localhost:5000/api/YourController?yourParam=<param-value>. In this example your API call type is GET.
If you want to send complex types (like classes, objects) to your controller you can lookup POST API requests.
You can find more details in this documentation.

Spring ModelAttribute not biding values Tomcat 9, Spring 5 MVC

I migrated from Spring 3 to 5, upgraded to Tomcat 9. After upgrading not able to get the values from JSP to Controller. #ModelAttribute is not binding the values entered in JSP, while submitting the form.
JSP Code:
<form:form action="/login" modelAttribute="identity" id="loginForm" cssClass="clearfix nodisplay">
<div class="grouping text">
<label for="email">E-mail Address</label>
<form:input path="email" id="email" cssClass="regInput" cssErrorClass="error" />
<form:errors path="email" cssClass="errors" />
</div>
<div class="grouping text">
<label for="pwd">Password</label>
<form:password path="pwd" id="pwd" cssClass="regInput" cssErrorClass="error" autocomplete="off" />
<form:errors path="pwd" cssClass="errors" />
</div>
<div class="grouping remember">
<input type="checkbox" name="remember" id="remember" />
<label for="remember">Remember Me</label>
</div>
<div class="btns clearfix">
<span class="login-btn">
<input type="hidden" name="cookieExist" id="cookieExist" value="false" />
<button type="button" name="login" class="btn js-login-btn"><span class="pictos">K</span> Login</button>
</span>
<span class="password-forget">
I forgot my password
</span>
</div>
</form:form>
Controller Code
#Controller
public class LoginController {
#RequestMapping(method=RequestMethod.GET, value="/login")
public String loginGet(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap,
#ModelAttribute Identity identity){
// commented business logic code
return "login";
}
#RequestMapping(method=RequestMethod.POST, value="/login")
public String loginPost(HttpServletRequest request, HttpServletResponse response,
ModelMap modelMap, #ModelAttribute("identity") Identity identity, BindingResult bindingResult) {
//commented out business logic
return "dashboard";
}
#ModelAttribute("identity")
public Identity formBackingObject() {
return new Identity();
}
}
I have migrated with no webxml way, not sure what else i'm missing here?
No need of action here in the form tag. Mention method in the form tag. So chnage to:
<form:form modelAttribute="identity" method="post" id="loginForm" cssClass="clearfix nodisplay">
And also change your primary action button to:
<input type="submit" ... />

pass value attribute from view to controller asp.net mvc

here was my code from view
#{ var companies = (IEnumerable<Company>)ViewData["companylist"]; }
#foreach (var item in companies)
{
//post the form to upload actions, index2 for testing
<form id="submitfinal" method="post" asp-action="Upload" asp-controller="report" enctype="multipart/form-data">
<input type="hidden" name="companyid" value="#item.Id" />
#item.Name (#item.Status)
<input type="file" name="files" />
<input name="submit" type="submit" value="upload final report" />
</form>
}
Question here was how can i take the data from input tag attribute to controller?
let say the #item.Id is 1234, how i get that in controller?
you can use
#Html.HiddenFor(m => m.yourPropertyname)
or using jquery ajax you can send the value to controller.
Maybe it's too late, but I would use asp-route-Id like:
<form id="submitfinal" method="post" asp-route-Id="#item.Id" asp-action="Upload" asp-controller="report" enctype="multipart/form-data">

spring+ thymeleaf unable to update

Hi I am working with spring MVC and thymeleaf and I am not able to update data from my controller as I have following code.The main problem I am facing is that my put method is not getting called.
#GetMapping("/{id}/edit")
public String editUser(#PathVariable("id") int id, Model model) {
logger.info("++++++++++++[edit User]\n\n" + userService.findById(id));
model.addAttribute("user", userService.findById(id));
return "user/edit";
}
#PutMapping("/{id}/edit")
public String updateUser(#PathVariable("id") int id, #ModelAttribute("user") User user, Model model) {
logger.info("\n\n+++++++++++++++++inside Update");
User toUpdate = userService.findById(user.getId());
user.setUserName(user.getUserName() != null ? user.getUserName() : toUpdate.getUserName());
user.setName(user.getName() != null ? user.getName() : toUpdate.getName());
logger.info(user.toString());
userService.updateUser(user);
model.addAttribute("user", userService.findById(user.getId()));
return "redirect:/user/" + id;
}
and my html page
<form action="#" th:action="#{/user/__${user.id}__}" method="put"
th:object="${user}">
<div class="form-group">
<label for="txtUserName">User-name</label> <input
class="form-control" id="txtUserName" placeholder="User Name"
th:feild="${user.userName}" />
</div>
<div class="form-group">
<label for="txtName">First Name</label> <input
class="form-control" id="txtName" placeholder="Full Name"
th:feild="${user.name}" />
</div>
<div class="form-group">
<label for="calDob">Date of Birth</label> <input
class="form-control" id="calDob" placeholder="dd/MM/yyyy" />
</div>
<button type="submit" th:method="put" class="btn btn-success">Update</button>
<a href="#" th:href="#{/user/__${user.id}__}"
class="btn btn-primary">Cancel</a> <a th:method="delete"
href="javascript:deleteUser('${user.id}');" class="btn btn-danger">Delete</a>
</form>
any help will be usefull thanks
PUT is not a valid argument for method attibute of the form tag. See HTML specification.
Valid methods are GET and POST. And as it's not a REST API, you can use POST method to update.
So just update your mapping from:
#PutMapping("/{id}/edit")
to
#PostMapping("/{id}/edit")
And form tag to:
<form action="#" th:action="#{/user/__${user.id}__}/edit" method="post" th:object="${user}">

add custom data to POST

I have a webpage that has 3 file inputs. There are specific fields on the form that needs to be sent when user uploads the file. I am not able to figure out how do i add custom data to my POST and how do i retrieve it back on the server. This is how my code looks like:
ASPX Page with 3 file inputs and other text boxes/dropdowns:
<form action="FilesUploader.ashx" method="post">
<div id="dvNewAttachment1">
<span>Attachment Type</span>
<select id="ddlAttachmentType1">
<option>T1</option>
<option>T2</option>
<option>T3</option>
</select>
<span>Description</span>
<input id="txtDesc1" />
<select id="ddlApproval1">
<option>Yes</option>
<option>No</option>
</select>
<input id="fileUploader1" type="file" runat="server" />
</div>
<br />
---------------
<div id="dvNewAttachment2">
<span>Attachment Type</span>
<select id="ddlAttachmentType2">
<option>T1</option>
<option>T2</option>
<option>T3</option>
</select>
<span>Description</span>
<input id="txtDesc2" />
<select id="ddlApproval2">
<option>Yes</option>
<option>No</option>
</select>
<input id="fileUploader2" type="file" runat="server" />
</div>
<br />
-------------------------------
<div id="dvNewAttachment3">
<span>Attachment Type</span>
<select id="ddlAttachmentType3">
<option>T1</option>
<option>T2</option>
<option>T3</option>
</select>
<span>Description</span>
<input id="txtDesc3" />
<select id="ddlApproval3">
<option>Yes</option>
<option>No</option>
</select>
<input id="fileUploader3" type="file" runat="server" />
</div>
<input type="submit" />
</form>
This is how my handler looks like:
public void ProcessRequest(HttpContext context)
{
HttpPostedFile myFile = context.Request.Files[0];
int nFileLen = myFile.ContentLength;
byte[] buffer = new byte[nFileLen];
using (BinaryReader br = new BinaryReader(myFile.InputStream))
{
br.Read(buffer, 0, buffer.Length);
}
}
As you can see i have 3 uploads and each has Attachment Type and description associated with it which i need to retrieve for each input file in my handler.
Right now i am just processing file from the first input but later i am going to loop thru the inputs and process them.
If your handler do not receive files that you place in file uploaders then your form needs to have additional attribute like this:
<form action="FilesUploader.ashx" method="post" enctype="multipart/form-data">
In order to get values from dropdowns on server you need to provide a name attribute to them:
<select id="ddlApproval1" name="ddlApproval1">
<option>Yes</option>
<option>No</option>
</select>

Resources