Jquery validation spring mvc - spring

I have a "Create an account" form that is handled by spring. I am using jquery to auto-update some of the fields.
<script type="text/javascript">
$().ready(
function() {
$("#item1").keyup(function() {
var text= (this).value;
//modify text
$("#item4").val(text);
});
});
</script>
<form:form action="${form_url}" method="POST" modelAttribute="object" enctype="${enctype}">
<label for="Item1">Item1:</label>
<input type="text" id="item1" name="item_1"/>
<br></br>
<br></br>
<label for="Item2">Item2:</label>
<input type="text" id="item2" name="item_2"/>
<br></br>
<br></br>
<label for="Item3">Item3:</label>
<input type="text" id="item3" name="item_3"/>
<br></br>
<br></br>
<label for="Item4">Item4:</label>
<input type="text" id="item4" name="item_4"/>
</form:create>
<input id="proceed" type="submit" value="Save"/>
Upon pressing the submit button I need to make sure the first field "item1" is not empty. I haven't found a solution to this uses spring forms. Thanks in advance!

There are many ways to implement such validation. It is recommended you do both client and server side.
For client side you can simple create a click listener to the submit button
$('.submitbutton').click(function(e) {
e.preventDefault();
if($('#item1').val().trim() != '') $('.myform').submit()
else { $('.item1_error').show();
}
Or (even better) use 3rd party validation library
For the server side you can use hibernate-validator and add #NotEmpty annotation to your form bean
public class MyForm {
#NotEmpty private String item1;
// ...
}
Then on your controller handler method just decorate the parameter with #Valid. Any errors can be checked through the BindingResult object
#RequestMapping(..)
public String myhandler(#Valid #ModelAttribute("object") MyForm myForm, BindingResult binding) {
if(binding.hasErrors()) {
// ...
}
}

Related

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

AJAX form $('form')[0].reset(); on submit not clearing values. What am I missing?

thank you in advance for any help given. I'm just learning jQuery and AJAX and would appreciate some help with the following code. All validation rules work, the form submits and the page does not refresh. The problem is that the form values are not clearing/resetting to default after the submit has triggered. Thoughts?
**********EDITED to include HTML markup*************
<div id="form">
<h1 class="title">Contact Us</h1><!-- title ends -->
<p class="contactUs">Ask about our services and request a quote today!</p><!-- contactUs ends -->
<div id="success"><p>Your message was sent successfully. Thank you.</p></div>
<p id="required">* All fields required.</p>
<form name="form" id="contactMe" method="post" action="process.php" onSubmit="return validateForm()" enctype="multipart/form-data">
<input class="txt" type="text" maxlength="50" size="50" required name="name" value="<?php echo $_GET['name'];?>" placeholder="Name" />
<div id="nameError"><p>Your name is required.</p></div>
<input class="txt" type="text" maxlength="50" size="50" required name="email" value="<?php echo $_GET['email'];?>" placeholder="Email Address" />
<div id="emailError"><p>A valid email address is required.</p></div>
<textarea name="message" rows="6" cols="40" required placeholder="Message"></textarea>
<div id="messageError"><p>A message is required.</p></div>
<input type="hidden" maxlength="80" size="50" id="complete" name="complete" placeholder="Please Keep This Field Empty" />
<input type="submit" value="SUBMIT" name="submit" />
<input type="reset" value="RESET" name="reset" />
</form>
</div><!-- form ends -->
//hide form submit success message by default. to be shown on successfull ajax submission only.
$(document).ready(function() {
if ($('#success').is(':visible')){
$(this).hide()
}
});
//form validation
function validateForm() {
//name
var a=document.forms["form"]["name"].value;
if (a==null || a=="")
{
$('#nameError').fadeIn(250);
return false;
}
//email address
var c=document.forms["form"]["email"].value;
var atpos=c.indexOf("#");
var dotpos=c.lastIndexOf(".");
if (atpos<1 || dotpos<atpos+2 || dotpos+2>=c.length)
{
$('#emailError').fadeIn(250);
return false;
}
//message
var e=document.forms["form"]["message"].value;
if (e==null || e=="")
{
$('#messageError').fadeIn(250);
return false;
}
}//javascript form validation ends
//ajax submit and clear form on success
$(function () {
$('form').on('submit', function (e) {
var myForm = validateForm();
if (myForm == false){
e.preventDefault();//stop submission for safari if fields empty
}
else{
$.ajax({
type: 'post',
url: 'process.php',
data: $('form').serialize(),
success: function () {
$('#success').fadeIn(250);
if ($('#nameError, #emailError, #messageError').is(':visible')) {
$('#nameError, #emailError, #messageError').fadeOut(250);
}
$('form')[0].reset();//clear form after submit success
}//success ends
});//ajax ends
e.preventDefault();//prevent default page refresh
}//else ends
});//submit ends
});//function ends
//if reset button is clicked AND messages displayed, remove all form html messages
$(document).ready(function() {
$('#form input[type="reset"]').click(function() {
if ($('#success, #nameError, #emailError, #messageError').is(':visible')) {
$('#success, #nameError, #emailError, #messageError').fadeOut(250);
}
});
});
By giving your input id="reset" and/or name="reset", you effectively overwrote the form.reset method of the form because by doing so you made form.reset target the reset button. Simply give it a different id and name value.
Never give elements name or id attributes that equal the name of a property of a dom node.

Hot Towel Angular data-ng-show not working during validation

Hello anyone has anyone tried doing a validation using angularjs in a with Hot Towel template?
Basically i have a property in my angular controller which is binded(two way) in my view.
I just want to do a simple required validation, and then show a <span> element with the message.
here is my controller code
(function () {
'use strict';
var controllerId = 'login';
angular.module('app').controller(controllerId, ['$scope', 'common', 'userservice','$location', login]);
function login($scope, common, userservice, $location) {
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
var vm = this;
vm.title = 'Login';
//view model for credentials
vm.email = null;
activate();
function activate() {
common.activateController([], controllerId)
.then(function () { log('Activated Login View'); });
}
}
})();
and this is my view
<div data-ng-controller="login as vm">
<form name="loginform" id="loginform" novalidate data-ng-submit="loginuser()">
<fieldset>
<legend>Login</legend>
<p>
<label>Email</label>
<input type="email" data-ng-model="email" placeholder="Email" required />
<span data-ng-show="loginform.email.$error.required">*</span>
</p>
</fieldset>
</form>
</div>
i dont know what the problem is, but the <span> just wont show. am i missing something?
You have to set 'name' attribute to your input email :
<input type="email" name="email" data-ng-model="email" placeholder="Email" required />
For each field of your form, angularjs will set a value like: loginform[name-attribute].
For your information, your span will be visible only when required error is triggered (when your email is not empty, your span will be hidden).
[EDIT] See this fiddle: http://jsfiddle.net/k82at

how to differenciate between onchange submit and button submit in spring controller

I have the jsp code as :
<s:url value="add" var="addUrl"/>
<form:form name="add" action="${addUrl}" modelAttribute="content" method="post">
<input type="hidden" name="add" value="" />
<form:select path="id" class="dClass" onchange="submit()">
<form:options items="${list}" /></form:select>
<input type="submit" class="btn" value="Refresh Content" />
</form:form>
And I have one controller method for both this call, is there any way to differentiate that from where the form is submitted? Either from the drop down or from the submit button?
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String getContentById(Model model, String id,Content content,HttpServletRequest request) {
if(call by onChange)
else if(call by submit button)
}
Kindly note that, onchange="submit()" will not submit your page. It will look for the function with name submit. Inside that function you can use code like this $('form#form_id').submit(); to submit. Check submit-a-form-using-jquery for more details.
#Vinoth Krishnan Thanks for your answer , its working now :) added a filed in my form as "dropDownSubmit"
function submitForm(formId){
var input = $("<input>").attr("type", "hidden").attr("name", "dropDownSubmit").val("true");
$("#" + formId).append($(input));
$("#" + formId).submit();
}
Then in controller:
if("true".equalsIgnoreCase(form.getDropDownSubmit()){
..
}
else{
.. button submit
}

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