Spring MVC and html input - spring-mvc

In Spring 3.1 Web MVC form I am using following field take the date from datepicker and the field defined in form as String. I am getting all the values but I am not getting the date field.
First Try
<form:input id="fromDate" class="mydate" path="fromDate" size="10" maxlength="10" />
<script type="text/javascript">
Spring.addDecoration(new Spring.ElementDecoration({elementId : 'fromDate', widgetType : 'dijit.form.DateTextBox', widgetAttrs : {promptMessage: 'Enter From Date', invalidMessage: 'Please enter valid From Date', required: false, constraints: {datePattern : 'dd/MM/yyyy', required : false}, datePattern : 'dd/MM/yyyy'}}));
</script>
Second Try
<input id="toDate" class="mydate" path="toDate" size="10" maxlength="10" />
<spring:bind path="schemeQuantity.toDate">
${status.value}
</spring:bind>
<script type="text/javascript">
Is it possible to use simple HTML input tag and bound with Spring MVC.

Yes it is possible to use simple html input tag.
In the form tag add a commandName attribute like this
<form:form commandName="attribute" name="createForm" id="createForm" acceptCharset="UTF-8" method="post" action="create">
Now in your controller class add #ModelAttribute like this.
#RequestMapping(value="create" , method=RequestMethod.POST)
public String createAttribute( Model model , #ModelAttribute YourPojoClass attribute,Errors errors)

Related

Access value outside form using thymeleaf

I need to obtain vaulue of an input using thymeleaf and spring but haven't been able to do so. Since I need that value in a lot of the methods in the controller I can't put that input inside of one of the forms.
I tried to use javascript to pass on the value to a hidden input in the forms, however since I'm using th:each I'm only getting the value of the first input.
I also tried adding a string to the model and then trying to access that string with #ModelAttribute, but it didn't workout either.
This is the html:
<tr th:each="pro:${productos}">
<td th:text="${pro.id}">id</td>
<!-- More code here omitted for brevity-->
<td>
<div>
<form th:action="#{|/actualizarMas/${pro.id}|}" method="post">
<button type="submit" id="mas">+</button>
</form>
<form th:action="#{|/actualizarMenos/${pro.id}|}" method="post">
<button type="submit" id="menos">-</button>
</form>
<input name="masomenos"/>
<form th:action="#{|/${pro.id}|}" method="post">
<button type="submit">Borrar</button>
</form>
</div>
</td>
</tr>
This is the controller:
#RequestMapping(value = "/actualizarMenos/{productosId}", method = RequestMethod.POST)
public String eliminarUno(#PathVariable int productosId, RedirectAttributes redirectAttributes, #RequestParam("masomenos") String masomenos) {
//Code here using that string omitted for brevity
return "redirect:/";
}
I need to access the input with the name "masomenos", if that is posible, how could I do it?, if not, what options do I have? besides creating inputs inside all the forms.
Thank you very much.

Strange behavior of ASP.NET MVC Razor engine with unobtrusive validation attributes

I've just faced a really strange behavior of Razor engine regarding adding unobtrusive validation attributes to inputs in forms. In some cases attributes are not added.
So, I have two similar forms on the same page with similar input elements. They must be submitted to different url's.
From model side, I have a few DataAnnotations Attributes, applied to properties to have a client-side validation.
Here is my a bit simplified code of ViewModel:
public class ApplicantPersonalInfo
{
[Required]
[Display(Name = "First Name")]
[StringLength(20, MinimumLength = 2)]
[RegularExpression(#"^[ÀàÂâÆæÇçÉéÈèÊêËëÎîÏïÔôŒœÙùÛûÜüŸÿa-zA-Z \.‘'`-]+$", ErrorMessage = "First Name is in incorrect format")]
public string FirstName { get; set; }
}
Now I want to create two forms. For every of them action url can differ dynamically (I submit them using ajaxSubmit from jQuery Form Plugin), that's why I decided not to use Html.BeginForm helper method, instead creating them with simple <form> tag. So my code is:
<form id="form1">
#Html.TextBoxFor(m => Model.FirstName, new { id = "firstName1" })
</form>
<form id="form2">
#Html.TextBoxFor(m => Model.FirstName, new { id = "firstName2" })
</form>
And the most interesting is the resulting html code:
<form id="form1">
<input data-val="true" data-val-length="The field First Name must be a string with a minimum length of 2 and a maximum length of 20." data-val-length-max="20" data-val-length-min="2" data-val-regex="First Name is in incorrect format" data-val-regex-pattern="^[ÀàÂâÆæÇçÉéÈèÊêËëÎîÏïÔôŒœÙùÛûÜüŸÿa-zA-Z \.‘'`-]+$" data-val-required="The First Name field is required." id="firstName1" name="FirstName" type="text" value=""/>
</form>
<form id="form2">
<input id="firstName2" name="FirstName" type="text" value=""/>
</form>
See? All those validation attributes are not applied to the second input!
BUT if the form is generated using Html.BeginForm, like this:
#using (Html.BeginForm("NotExistingController", "NotExisitngAtion", FormMethod.Post, new { id = "form1" }))
{
#Html.TextBoxFor(m => Model.HomeOwner.FirstName, new { id = "firstName1" })
}
<form id="form2">
#Html.TextBoxFor(m => Model.HomeOwner.FirstName, new { id = "firstName2" })
</form>
the resulting html code is with attributes in both inputs:
<form action="/NotExisitngAtion/NotExistingController" id="form1" method="post">
<input data-val="true" data-val-length="The field First Name must be a string with a minimum length of 2 and a maximum length of 20." data-val-length-max="20" data-val-length-min="2" data-val-regex="First Name is in incorrect format" data-val-regex-pattern="^[ÀàÂâÆæÇçÉéÈèÊêËëÎîÏïÔôŒœÙùÛûÜüŸÿa-zA-Z \.‘'`-]+$" data-val-required="The First Name field is required." id="firstName1" name="FirstName" type="text" value="" />
</form>
<form id="form2">
<input data-val="true" data-val-length="The field First Name must be a string with a minimum length of 2 and a maximum length of 20." data-val-length-max="20" data-val-length-min="2" data-val-regex="First Name is in incorrect format" data-val-regex-pattern="^[ÀàÂâÆæÇçÉéÈèÊêËëÎîÏïÔôŒœÙùÛûÜüŸÿa-zA-Z \.‘'`-]+$" data-val-required="The First Name field is required." id="firstName2" name="FirstName" type="text" value="" />
</form>
I'm really confused by this behavior. And I've tried - you can add as much forms as you want using Html.BeginForm - every of them will have set of validation attributes; but if you add >1 form using simple <form> tag, starting from the second one attributes are missing.
So am I missing something or it's a bug in Razor engine?

ASP.NET MVC - prevent submit of invalid form using jQuery unobtrusive validation

I have an ASP.NET project that automatically wires up client side validation using jQuery.Validate and the unobtrusive wrapper built by ASP.NET.
a) I definitely have the appropriate libraries: jquery.js, jquery.validate.js, & jquery.validate.unobtrusive.js
b) And the MVC rendering engine is definitely turned on (ClientValidationEnabled & UnobtrusiveJavaScriptEnabled in the appSettings section of the web.config)
Here's a trivial example where things are broken:
Model:
public class Person
{
[Required]
public string Name { get; set; }
}
Controller:
public ActionResult Edit()
{
Person p = new Person();
return View(p);
}
View:
#model validation.Models.Person
#using (Html.BeginForm()) {
#Html.ValidationSummary(false)
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name)
}
This generates the following client side markup:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/jquery.validate.js"></script>
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js"></script>
<form action="/Person" method="post">
<div class="validation-summary-valid" data-valmsg-summary="true">
<ul><li style="display:none"></li></ul>
</div>
<label for="Name">Name</label>
<input data-val="true" data-val-required="The Name field is required." id="Name" name="Name" type="text" value="" />
<input type="submit" value="Save" />
</form>
When run it will perform the client side validation, noting that some form elements are invalid, but then also post back to the server.
Why is it not preventing postback on a form with an invalid state?
The Problem
It turns out this happens when you don't include a #Html.ValidationMessageFor placeholder for a given form element.
Here's a deeper dive into where the problem occurs:
When a form submits, jquery.validate.js will call the following methods:
validate: function( options ) {
form: function() {
showErrors: function(errors) {
defaultShowErrors: function() {
showLabel: function(element, message) {
this.settings.errorPlacement(label, $(element) )
Where errorPlacement will call this method in jquery.validate.unobtrusive.js:
function onError(error, inputElement) {
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false;
When we don't add a placeholder for the validation message, $(this).find(...) won't find anything.
Meaning container.attr("data-valmsg-replace") will return undefined
This poses a problem is when we try to call $.parseJSON on an undefined value. If an error is thrown (and not caught), JavaScript will stop dead in its tracks and never reach the final line of code in the original method (return false) which prevents the form from submitting.
The Solution
Upgrade jQuery Validate Unobtrusive
Newer versions of jQuery Validate handle this better and check for nulls before passing them to $.parseJSON
function onError(error, inputElement) { // 'this' is the form element
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
Add ValidationMessageFor
To address the core problem, for every input on your form, make sure to include:
#Html.ValidationMessageFor(model => model.Name)
Which will render the following client side markup
<span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/jquery.validate.js"></script>
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js"></script>
<form action="/Person" method="post">
<div class="validation-summary-valid" data-valmsg-summary="true">
<ul><li style="display:none"></li></ul>
</div>
<label for="Name">Name</label>
<input data-val="true" data-val-required="The Name field is required." id="Name" name="Name" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
<input type="submit" value="Save" />
</form>

Retrieve non-form-element value through form post in Spring 3 MVC Controller Class

When I submit this:
<form:form action='/controller.do' method='POST'>
<input type='text' value='test' name='myName" />
<input type='submit'/>
</form:form>
How can I retrieve the value of 'myName' in Spring 3 MVC Controller without using form tag?
If I understand your question correctly, you put some plain HTML <input> tags inside Spring MVC tag library's <form:form> tag.
Though it may work, it probably would be a better idea to use (depending on your situation) either plain HTML:
<form action='/controller.do' method='POST'>
<input type='text' value='' name='myName" />
<input type='submit'/>
</form>
or Spring MVC tags only:
<form:form action='/controller.do' method='POST' modelAttribute='fooModelAttribute'>
<form:input path='myName' />
<input type='submit'/>
</form>
You can retrieve the myName value by declaring the following parameter in your controller method:
#RequestParam("myName") String myNameVal
Alternatively, you can declare a class which has a myName field with a getter and setter (say, FooClass). And then you can declare the following parameter in the controller:
FooClass foo
This parameter may have an optional #ModelAttribute("fooModelAttribute") annotation.
See the Spring Reference for more details on #RequestParam, #ModelAttribute, and <form:form>.

Spring mvc tag question

What is the significance 'label' and 'path' in the spring mvc jsp tag:
form:label path="someName"
label simply defines the text of the field within the page, for example:
<form:select path="dataVisArray"><br />
<form:option label="Select..." value=""/>
<form:options items="${dataVisArray} itemLabel="label" itemValue="value"/>
</form:select>
shows a dropdown, where the first element is "Select..." and the rest is defined in ${dataVisArray}
path links to a form backing object where you can save the input. In the example above, there would be a variable called "dataVisArray" within the backing object to save the value of the selected item once the form is submitted.
The label attribute is for displaying text corresponding to the form element for which we are using the label attribute
<label for="FirstName" >First Name :</label>
For Path attribute can be also used in validation of form element by jquery
<form:input path="name" id="name" name="name"/>
The path value name then can be used for validation purpose:
$("#ajaxForm").validate({
rules: {
name: {
required:true,
minlenght:3
},
messages: {
name : {
required : 'Enter Username',
maxlength :'Not more than 30 Charachters',
minlength :'Should be more than 3 characters'
},
Hope this helps.
In Spring MVC JSP tag lable signifies the value to be displayed as part of the tag and path is used to signify path to property for data binding.
<form:label path="company"> Enter company name: </form:label>

Resources