Do not submit form before jquery validate is okay - javascript

I am looking for a way, so that my FormMethod.Post Dosen't submit, before jquery validation is done. I have tried by making it so that the button just is at disabled, and then remove disable on keydown, if form is okay. But that didn't work, and neither isn't secure. What can i do?
Html
#using (Html.BeginForm("_Kontakt", "Home", FormMethod.Post))
{
<div class="row">
<div class="col-sm-6">
<div class="col-sm-12">
<b>Facebook Url</b>
<input id="FacebookUrl" name="FacebookUrl" type="text" class="form-control" />
</div>
<div class="col-sm-12">
<b>Steam Url</b>
<input id="SteamUrl" name="SteamUrl" type="text" class="form-control" />
</div>
<div class="col-sm-12">
<button id="SendBtn" class="btn btn-success pull-right" onclick="return validateUrl();">Send</button>
</div>
</div>
</div>
}
Jquery/Javascript
function validateUrl() {
facebookURL = $("#FacebookUrl").val();
steamURL = $("#SteamUrl").val();
var facebook = /^(?:(?:http|https):\/\/)?(?:www.)?facebook.com\/(?:(?:\w)*#!\/)?(?:pages\/)?(?:[?\w\-]*\/)?(?:profile.php\?id=(?=\d.*))?([\w\-]*)?$/;
var steam = /(?:https?:\/\/)?steamcommunity\.com\/(?:profiles|id)\/[a-zA-Z0-9]+/;
if (facebook.test(facebookURL)) {
}
else {
alert("Ikke et facebook gyldigt url!");
}
if (steam.test(steamURL)) {
}
else {
alert("Ikke et steam gyldigt url!");
}
return facebook.test(facebookURL);
return steam.test(steamURL);
}
ANSWERE
return facebook.test(facebookURL) && steam.test(steamURL);

There is an "onsubmit" event that allows you to control form submission http://www.w3schools.com/tags/ev_onsubmit.asp

If you put the inputs and button in a form element and use the pattern and required attributes in combination with the :invalid selector the browser can do the validation for you:
/* Add the .focused class when the user focuses
an input to only show the error message once */
$("#the-form input").focus(function(){
this.classList.add("focused");
});
.input-error-message {
color: red;
}
/* Show elements with the class .input-error-message
if they come after an input with invalid data if the
user isn't typing or if it has not been focused yet */
:invalid:not(:focus).focused + .input-error-message {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<form class="col-sm-6" id="the-form" onsubmit="return isValid()">
<div class="col-sm-12">
<b>Facebook Url</b>
<input id="FacebookUrl" name="FacebookUrl" type="text" class="form-control" pattern="^(?:(?:http|https):\/\/)?(?:www.)?facebook.com\/(?:(?:\w)*#!\/)?(?:pages\/)?(?:[?\w\-]*\/)?(?:profile.php\?id=(?=\d.*))?([\w\-]*)?$" required/>
<div class="input-error-message" hidden>Ikke et facebook gyldigt url!</div>
</div>
<div class="col-sm-12">
<b>Steam Url</b>
<input id="SteamUrl" name="SteamUrl" type="text" class="form-control" pattern="(?:https?:\/\/)?steamcommunity\.com\/(?:profiles|id)\/[a-zA-Z0-9]+" required/>
<div class="input-error-message" hidden>Ikke et steam gyldigt url!</div>
</div>
<div class="col-sm-12">
<button id="SendBtn" class="btn btn-success pull-right">Send</button>
</div>
</form>
</div>

Related

How can I validate form fields using JavaScript in Multi-step HTML Form?

I'm working on registration form that has three sections. A user moves to the next section of the form when the button "Next" is clicked. Everything is working well except that validation errors are only showing on the last section of the Form. I would like to validate the form before moving to the next section. For now, when "Next" button is clicked, the user can move to the next section even without filling the fields. I'm not so experienced in JavaScript, please help.
HTML:
<section>
<div class="container">
<form>
<div class="step step-1 active">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" id="firstName" name="first-name">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" id="lastName" name="last-name">
</div>
<div class="form-group">
<label for="nickName">Nick Name</label>
<input type="text" id="nickName" name="nick-name">
</div>
<button type="button" class="next-btn">Next</button>
</div>
<div class="step step-2">
<div class="form-group">
<label for="email">Email</label>
<input type="text" id="email" name="email">
</div>
<div class="form-group">
<label for="phone">Phone</label>
<input type="number" id="phone" name="phone-number">
</div>
<button type="button" class="previous-btn">Prev</button>
<button type="button" class="next-btn">Next</button>
</div>
<div class="step step-3">
<div class="form-group">
<label for="country">country</label>
<input type="text" id="country" name="country">
</div>
<div class="form-group">
<label for="city">City</label>
<input type="text" id="city" name="city">
</div>
<div class="form-group">
<label for="postCode">Post Code</label>
<input type="text" id="postCode" name="post-code">
</div>
<button type="button" class="previous-btn">Prev</button>
<button type="submit" class="submit-btn">Submit</button>
</div>
</form>
</div>
</section>
JavaScript:
const steps = Array.from(document.querySelectorAll("form .step"));
const nextBtn = document.querySelectorAll("form .next-btn");
const prevBtn = document.querySelectorAll("form .previous-btn");
const form = document.querySelector("form");
nextBtn.forEach((button) => {
button.addEventListener("click", () => {
changeStep("next");
});
});
prevBtn.forEach((button) => {
button.addEventListener("click", () => {
changeStep("prev");
});
});
form.addEventListener("submit", (e) => {
e.preventDefault();
const inputs = [];
form.querySelectorAll("input").forEach((input) => {
const { name, value } = input;
inputs.push({ name, value });
});
console.log(inputs);
form.reset();
});
function changeStep(btn) {
let index = 0;
const active = document.querySelector(".active");
index = steps.indexOf(active);
steps[index].classList.remove("active");
if (btn === "next") {
index++;
} else if (btn === "prev") {
index--;
}
steps[index].classList.add("active");
}
If you want to validate one section of the form before moving on to the next one you should do something like this:
nextBtn.forEach(button => {
button.addEventListener("click", () => {
handleEvent("next")
})
})
prevBtn.forEach(button => {
button.addEventListener("click", () => {
handleEvent("prev")
})
})
where handleEvent is:
function handleEvent(btn) {
if (!handleFormValidation(btn)) return "error message here";
changeStep(btn)
}
Here handleFormValidation would be a function that checks weather the input is correct and returns true if it is and false if it isn't
If you want to make sure the user fills in the first form first before going to the second you can do it by making the second form appear only after the next button is pressed, but that would require a major rework of your system. (i do however advise it because when i copied your code to test it i noticed quite a lot of bugs)
Here are some mdn articles describing how to make, delete and append elements using javascript:
making an element
removing an element
removing an element
appending an element to another element
appending an element to another element
I highly encourage you to do your own research as well.
I also just want to apologise if anything in my answer isn't understandable. I'm new at contributing to this community so there will likely be mistakes I've made.

Required field validation on group of text box Not working

I want to apply required field validation on text box group in which at least one text box group must contain value.
in bellow image, details of at least one bank must be filled.
I have used jquery-form-validator plugin from http://www.formvalidator.net/#custom-validators and created custome validator as bellow, but Its not working.
$("#txtBankDetails")
.valAttr('error-msg', 'select atlest 1 bankname.');
$.formUtils.addValidator({
name: 'data-text-group',
validatorFunction: function (value, $el, config, language, $form) {
debugger
var isValid = true,
// get name of element. since it is a checkbox group, all checkboxes will have same name
elname = $el.attr('data-text-group'),
// get checkboxes and count the checked ones
$textBoxes = $('input[type=textbox][data-text-group^="' + elname + '"]', $form),
nonEmptyCount = $textBoxes.filter(function () {
return !!this.value;
}).length;
alert(nonEmptyCount);
if (nonEmptyCount == 0) {
isValid = false;
}
}
});
// Setup form validation only on the form having id "registration"
$.validate({
form: '#registration',
modules: 'date, security, file, logic',
validateOnBlur: true,
showHelpOnFocus: true,
addSuggestions: true,
onModulesLoaded: function () {
console.log('All modules loaded!');
},
onSuccess: function ($form) {
form.submit();
alert("sucess")
return false;
},
onError: function () {
alert("Error")
}
});
html code is,
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/jquery-form-validator/2.3.26/theme-default.min.css"
rel="stylesheet" type="text/css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-form-validator/2.3.26/jquery.form-validator.min.js"></script>
<form id="registration" method="post" action="#Url.Action("NewRegistration", "StaticPage")" enctype="multipart/form-data" class='has-validation-callback'>
<div class="container">
<div class="row">
<div class="col-md-4">
<input id="txtBankDetails" name="Bankname1" data-text-group="BankName" placeholder="01. BANK NAME" data-validation-error-msg="select atlest 1 bankname.">
</div>
<div class="col-md-4">
<input class="nwresmainfild" name="BankACNo1" placeholder="BANK A/C NO.">
</div>
<div class="col-md-4">
<input class="nwresmainfild" name="BankAddress1" placeholder="BANK ADDRESS">
</div>
</div>
<div class="row">
<div class="col-md-4">
<input id="txtBankDetails" name="Bankname2" data-text-group="BankName" placeholder="01. BANK NAME" data-validation-error-msg="select atlest 1 bankname.">
</div>
<div class="col-md-4">
<input name="BankACNo2" placeholder="BANK A/C NO.">
</div>
<div class="col-md-4">
<input name="BankAddress2" placeholder="BANK ADDRESS">
</div>
</div>
<div class="row">
<div class="col-md-4">
<input id="txtBankDetails" name="Bankname3" data-text-group="BankName" placeholder="03. BANK NAME" >
</div>
<div class="col-md-4">
<input name="BankACNo3" placeholder="BANK A/C NO.">
</div>
<div class="col-md-4">
<input name="BankAddress3" placeholder="BANK ADDRESS">
</div>
</div>
</div>
<input value="PROCESS & PRINT" class="green-btn uppercase" type="submit" id="btnSubmit" />
</form>

Send vote after click radio button

On my website I have a form that allows you to send select a vote and after that the choice of the vote allows you to send (optional) a comment or photo or audio, this button allows you to send everything.
The form of the vote appears after searching for a specific location.
Now I would like to change the functionality, I wish that after clicking on the vote is saved directly right away, and afterwards appear as always the ability to send comments and photos.
This is my form:
<script type="text/javascript">
$(".sinButtonVote > img").click(function(e){
$(this).parents("div.sinWebQuestion").addClass("voteChosen");
$("#sendVoteButton").removeClass("hidden");
$("#sendOpinion").removeClass("hidden");
});
$("div.sinBottomVoteButton").click(function(e){
$("#sendVoteButton").removeClass("hidden");
});
function afterOpinionSent() {
$("#wsCompany").val("Select Location").change();
}
</script>
<form th:action="#{/opinion/vote}"
enctype="multipart/form-data" method="post"
data-successHandler="afterOpinionSent"
class="s_ajaxForm">
<input type="hidden" name="webLocationId" th:value="${webLocation.id}" th:if="${webLocation!=null}"/>
<div th:each="webQuestion : ${webQuestions}" class="row WebQuestion">
<div class="col-sm-6">
<div th:text="${webQuestion.question}" class="sinButtonVoteLabel">Question?</div>
</div>
<div class="col-sm-6">
<label th:each="vote : ${ {3, 2, 1, 0} }" class="radio-inline ButtonVote">
<input type="radio" th:name="|questionVote[${webQuestion.id}]|" th:value="${vote}"/>
<img yada:src="#{|/res/img/question/${webQuestion.iconName+vote}.png|}" th:alt-title="|Voto ${vote}|">
</label>
</div>
</div>
<div style="text-align: center; margin-top: 15px;" id="sendOpinion" class="s_ajaxForm hidden">
<div style="float: left; width: 35%;" class="BottomVoteButton">
<label class="btn btn-default" data-toggle="collapse" data-target="#voteComment">
<img yada:src="#{/res/img/question/comment.png}" title="Comment">
<span>Opinion</span>
</label>
</div>
<div style="float: left; width: 30%;" class="BottomVoteButton">
<label class="btn btn-default btn-file">
<img yada:src="#{/res/img/question/photo.png}" height="35px" title="Photo"><br />
<span>Photo</span>
<input type="file" accept="image/*" capture="camera" class="hidden" name="photo">
</label>
</div>
<div style="overflow: hidden; width: auto;" class="BottomVoteButton">
<label class="btn btn-default btn-file">
<img yada:src="#{/res/img/question/Audio.png}" title="Audio">
<span>Audio</span>
<input type="file" accept="audio/*" capture="microphone" class="hidden" name="audio">
</label>
</div>
<div id="voteComment" class="collapse" th:if="${webLocation!=null}">
<div class="form-group">
<textarea class="form-control" rows="5" maxlength="1024" name="comment" placeholder="Comment..."></textarea>
</div>
</div>
</div>
<button id="sendVoteButton" type="submit" class="s_ajaxForm btn btn-default btn-block hidden">Send</button>
</form>
And this is my opinionController.java:
#RequestMapping("/vote") // Ajax
public String voto(FormOpinioni formOpinioni, HttpServletRequest request, HttpServletResponse response, Model model) {
WebLocation webLocation = null;
if (formOpinioni.getWebLocationId() != null) {
webLocation = webLocationRepository.findOne(formOpinioni.getWebLocationId());
}
if (webLocation==null) {
return "/yada/ajaxError";
}
YadaBrowserId yadaBrowserId = yadaBrowserIdDao.ensureYadaBrowserId(COOKIE_UUIDNAME, COOKIE_EXPIRATIONSEC, request, response);
// Save WebResult
String ipAddress = request.getRemoteAddr();
for (Map.Entry<Long,String> idAndVote : formOpinioni.getQuestionVote().entrySet()) {
long questionId = idAndVote.getKey();
int vote = Integer.parseInt(idAndVote.getValue());
boolean stored = webResultDao.storeResult(questionId, vote, yadaBrowserId, ipAddress);
}
// Save il comment
String commento = formOpinioni.getCommento();
if (!StringUtils.isBlank(comment) && webLocation.isEnabled()) {
boolean stored = webAttachmentDao.storeAttachment(WebAttachment.TYPE_COMMENT, comment, ipAddress, webLocation, yadaBrowserId);
}
// Save photo
saveUpload(WebAttachment.TYPE_IMAGE, formOpinioni.getPhoto(), webLocation, yadaBrowserId, ipAddress, response, model);
// Save audio
saveUpload(WebAttachment.TYPE_AUDIO, formOpinioni.getAudio(), webLocation, yadaBrowserId, ipAddress, response, model);
return thanksForOpinion("Registered opiniono", model);
}
private String thanksForOpinion(String title, Model model) {
return YadaNotify.instance(model)
.yadaOk().yadaAutoclose(2000)
.yadaTitle(title)
.yadaMessage("<p style='text-align:center; min-height:60px;'>Thanks You for opinion</p>")
.yadaSave();
}
How do I change the code?
You have to make following changes
<script th:inline="javascript">
$(".sinButtonVote > img").click(function(e){
$(this).parents("div.sinWebQuestion").addClass("voteChosen");
$("#sendVoteButton").removeClass("hidden");
$("#sendOpinion").removeClass("hidden");
});
$("div.sinBottomVoteButton").click(function(e){
$("#sendVoteButton").removeClass("hidden");
});
function afterOpinionSent() {
$("#wsCompany").val("Select Location").change();
}
$(document).ready(function(){
$("input[#name='YOUR_RADIO_INPUTNAME']").click(function(){
$("#YOUR_FORM_ID").ajaxSubmit({url: '/vote', type: 'post'});
});
});
</script>
Make a Action method which will can process only vote entry .

How do I trigger all validations when submit button is clicked?

I've added validations for my form and I wanted it to trigger each and every validation when submit button is clicked. I tried googling for how to trigger them but it seems they are not working for me.
Here's my code for the form
<form id="CustomerForm" class="form-horizontal group-border stripped" name="CustomerDetails" novalidate ng-submit="CustomerDetails.$valid && AddCustomer()">
<div class="form-group" ng-class="{'has-error': CustomerDetails.cname.$invalid && !CustomerDetails.cname.$pristine}">
<label class="col-lg-2 col-md-3 control-label">Customer Name</label>
<div class="col-lg-10 col-md-9">
<input type="text" ng-model="CusDetails.cname" class="form-control" name="cname" id="cname" required />
<p ng-show="CustomerDetails.cname.$error.required && !CustomerDetails.cname.$pristine" class="help-block">Customer name required!</p>
</div>
</div>
<!--end of .form-group-->
<div class="form-group" ng-class="{'has-error': CustomerDetails.comname.$invalid && !CustomerDetails.comname.$pristine}">
<label class="col-lg-2 col-md-3 control-label">Company Name</label>
<div class="col-lg-10 col-md-9">
<input type="text" ng-model="CusDetails.comname" class="form-control" name="comname"id="comname" required />
<p ng-show="CustomerDetails.comname.$error.required && !CustomerDetails.comname.$pristine" class="help-block">Comapany name required!</p>
</div>
</div>
<!--end of .form-group-->
<div class="form-group" ng-class="{'has-error': CustomerDetails.ctel.$invalid && !CustomerDetails.ctel.$pristine}">
<label class="col-lg-2 col-md-3 control-label" for="">Telephone Number</label>
<div class="col-lg-10 col-md-9">
<div class="input-group input-icon">
<span class="input-group-addon"><i class="fa fa-phone s16"></i></span>
<input ng-model="CusDetails.tel" class="form-control" name="ctel" type="text" placeholder="(999) 999-9999" id="ctel" required >
<p ng-show="CustomerDetails.ctel.$error.required && !CustomerDetails.ctel.$pristine" class="help-block">Telephone number required!</p>
</div>
</div>
</div>
<!-- End .form-group -->
<div class="form-group" ng-class="{'has-error': CustomerDetails.email.$invalid && !CustomerDetails.email.$pristine}">
<label class="col-lg-2 col-md-3 control-label" for="">Email address</label>
<div class="col-lg-10 col-md-9">
<input ng-model="CusDetails.email" type="email" class="form-control" name="email" placeholder="someone#example.com" id="email" required >
<p ng-show="CustomerDetails.email.$error.required && !CustomerDetails.email.$pristine" class="help-block">Email is required!</p>
<p ng-show="CustomerDetails.email.$error.email && !CustomerDetails.email.$pristine" class="help-block">Please Enter valid email address.</p>
</div>
</div>
<!-- End .form-group -->
<div class="form-group">
<div class="col-lg-9 col-sm-9 col-xs-12">
<button name="btnSubmit" type="submit" class="btn btn-info pad"><span class="fa fa-user-plus"></span> Add Customer</button>
<button type="button" id="cancel" class="btn btn-default pad">Cancel</button>
</div>
</div>
</form>
UPDATE: I have change the code according to Adrian Brand but still no trigger. What am I doing wrong?
Here's my angularjs for the form. (controller)
(function () {
'use strict';
angular
.module('efutures.hr.controllers.customer', [])
.controller('AddCustomerController', AddCustomerController);
AddCustomerController.$inject = ['$scope', '$location', '$rootScope', '$http', 'CustService'];
function AddCustomerController($scope, $location, $rootScope, $http, CustService) {
(function initController() {
})();
$scope.AddCustomer = function () {
var CustomerDetails = {
cname: $scope.CusDetails.cname,
comname: $scope.CusDetails.comname,
tel: $scope.CusDetails.tel,
email: $scope.CusDetails.email
};
if ($scope.CustomerDetails.$valid) {
CustService.Customer(CustomerDetails, function (res) {
console.log(res);
$.extend($.gritter.options, {
position: 'bottom-right',
});
if (res.data == 'success') {
$.gritter.add({
title: 'Success!',
text: 'Successfully added the new customer ' + '<h4><span class="label label-primary">' + CustomerDetails.cname + '</span></h4>',
time: '',
close_icon: 'l-arrows-remove s16',
icon: 'glyphicon glyphicon-ok-circle',
class_name: 'success-notice'
});
$scope.CusDetails = {};
$scope.CustomerDetails.$setPristine();
}
else {
$.gritter.add({
title: 'Failed!',
text: 'Failed to add a new customer. Please retry.',
time: '',
close_icon: 'l-arrows-remove s16',
icon: 'glyphicon glyphicon-remove-circle',
class_name: 'error-notice'
});
}
});
}
}
}
})();
I even tried making the form submitted true, still didn't work.
The only thing that worked for me is the disabling the button until its validated but that isn't the requirement. I want it to trigger when the submit form is clicked. Help would be greatly appreciated.
In the click event where you wanted to trigger the validation, add the following:
vm.triggerSubmit = function() {
vm.homeForm.$setSubmitted();
...
}
This works for me. To know more about this click here : https://code.angularjs.org/1.3.20/docs/api/ng/type/form.FormController
Your problem lies in the fact that your submit button is not contained in the form so the form never gets submitted. You are just running the controller method via a click handler.
Form validation is not a controller concern and has no place in the controller. It is purely a view concern.
In your form you put a ng-submit="CustomerDetails.$valid && AddCustomer()" and take the click handler off the submit button and place the button row within the form. This way the view will only submit if the form is valid. Do not pollute your controllers with form validation and keep it all contained in your view. You should look into the controller as syntax and then you will not even have access to the $scope in your controllers.

Checking whether a input element value contains a certain string

I need to check whether or not a input element's value(typed by the user into the box) returned from
$("#emailInput").css("value")
contains a certain string.
I have tried various methods seen on google but none have worked.
The HTML:
<form class="form-horizontal" role="form">
<div id="emailBorder">
<label id="emailStyle">Email address:</label>
<div id="emailInputStyle">
<input class="form-control" id="emailInput" type="text">
<span id="emailGlyphicon"></span>
</div>
</div>
<div class="form-group">
<label id="contentStyle">Content:</label>
<div id="contentInputStyle">
<textarea class="form-control" rows="5" id="contentInput"></textarea>
</div>
</div>
<button type="submit" id="sendStyle" class="btn btn-default">Send</button>
</form>
The Javascript (My Attempt):
$("#emailInput").change(function () {
if ($("#emailInput").css("value").contains("#") && $("#emailInput").css("value").contains(".")) {
// do something
} else {
// do something else
}
});
Instead of css(), use val(). Also, instead of contains() use indexOf() because contains() works on jQuery DOM objects, not strings
$("#emailInput").change(function() {
if ($("#emailInput").val().indexOf("#") > -1 && $("#emailInput").val().indexOf(".") > -1) {
console.log('It contains # and .');
} else {
// do something else
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form class="form-horizontal" role="form">
<div id="emailBorder">
<label id="emailStyle">Email address:</label>
<div id="emailInputStyle">
<input class="form-control" id="emailInput" type="text">
<span id="emailGlyphicon"></span>
</div>
</div>
<div class="form-group">
<label id="contentStyle">Content:</label>
<div id="contentInputStyle">
<textarea class="form-control" rows="5" id="contentInput"></textarea>
</div>
</div>
<button type="submit" id="sendStyle" class="btn btn-default">Send</button>
</form>
css() will get/set the inline style of an element. val() will get/set the value of an input type element
You can try this:
$("#emailInput").change(function () {
if ($this.contains("#") && $this.contains(".")) {
// do something
} else {
// do something else
}
});

Categories