How to do javascript bootstrap form validation? - javascript

There is a standard bootstrap validation script:
'use strict'
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
But it only checks if the values ​​are empty. And I need to additionally check, for example, that the input field with id=year has four digits.
I know about "pattern" attribute, but Safari doesn't support it. I need a javascript solution with a code example.

Related

jQuery validate not working for two fields

I need to validate that both the domain field is correct and that the placeholder field has a value. Once both are true, the Submit button will show. Using jQuery validate, I can check that the domain is correct, but its not validating the placeholder field. The playerClass rule is not being applied:
$(function() {
$("#form").validate({
rules: {
playerClass: {
required: true
}
},
submitHandler: function() {
$("body").append("<p>Validation Complete!</p>");
}
});
});
jQuery.validator.addMethod("domainChk", function(value, element, params) {
$(".submit").show();
if (this.optional(element)) return true;
var regExp = new RegExp("^(?!www\\.|http:\/\/www\.)(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$");
return regExp.test(value);
},
function errmess(params, element) {
$(".submit").hide();
return "Valid hostname required for player code";
});
jQuery.validator.addClassRules({
domainChk: {
domainChk: true
}
});
jsFiddle: Link
The playerClass rule is not being applied
Your second field, with name="playerClass" is not being validated because you've applied no validation rules to it. There is no such rule called playerClass in your jsFiddle or in your OP, and you've applied no rules to the playerClass field in your jsFiddle.
Even if playerClass was a custom rule, the form is considered valid because the playerClass field is optional in your jsFiddle. Without the required rule, when the field is left blank, it's valid.
You've also failed to close your <form> element in the jsFiddle. There is no </form> tag.
EDIT:
As per documentation, any ajax() should go inside the submitHandler function within the .validate() method.
In other words, you are breaking the validation plugin with your click handler.
I need to validate that both the domain field is correct and that the placeholder field has a value. Once both are true, the Submit button will show.
Then why are you showing the submit button from within the domainChk rule? Once this rule is passed, you're showing the button with $(".submit").show().
You would typically use the .valid() method to test the form and show/hide the button.
$('input[type="text"]').on('click keyup blur', function() {
if ($('#form').valid()) {
$(".submit").show();
} else {
$(".submit").hide();
}
});
This is much closer to how it should be: http://jsfiddle.net/e04rca0t/2/

How do I use JavaScript or jQuery to submit a form by using the Enter key, when not the default form action

I have a page that has three "forms" that are apparent to the user. Under the hood, the page has only ONE form, using html:form as the JSP object controlling the entire page. When a user clicks on the image that is used for the individual submit buttons, it triggers an onClick() function, which bypasses the form's action and executes another action instead.
<html:form action="foo.do">
<html:text property="name" styleClass="input" />
<img src="bar.jpg" onClick="myFunction();" />
</html:form>
<script>
function myFunction(){
document.forms[0].action = "realPage.do";
document.forms[0].submit();
}
</script>
This script works, sending the user not to the default "foo.do" but rather to the destination of the function (realPage.do)
However, the problem is my users want to be able to submit the form just by hitting 'Enter' on their keyboard when in any one of the fields, of the particular "form" they want to submit. How can I use JavaScript or jQuery to recognize which "form" and, hence, which input field the user is in, detect the press of the 'Enter' key and submit using the same function as the button?
This should solve your problem
$(document).ready(function(){
$("input").keyup(function (e) {
if (e.keyCode == 13) {
// Submit your form here
}
});
});
I would probably arrest the form submit and detect which element has focus. Something like this, where each pseudo-form has an identified wrapper element:
$(function() { // document.ready
$('#myform').submit(function(event) {
event.preventDefault();
if ( $('#pseudoForm1 input').is(':focus') ) { ... }
else if ( $('#pseudoForm2 input').is(':focus') ) { ... }
else if ( $('#pseudoForm3 input').is(':focus') ) { ... }
});
});
You could start with this -
$('input').keypress(function(e) {
if(13 == e.keyCode) {
var closestForm = $(this).closest('form');
$(closestForm).submit();
}
});

How to get reference to submit button using jQuery validation plugin?

How can I get a reference to the submit button using the jQuery validation plugin?
function defSubmHendler(){
$myform.validate({
rules: rules,
messages: messages,
submitHandler: function() {
event.preventDefault();
if (~this form id == A){
condition1;
}
else if (~this form id == B){
condition2;
} else {}
...
$.ajax({
...
});
}
});
}
In this case this == $.validator. I need a reference to the submit button / form in submitHandler.
Consider giving an id to your submit button and referencing it like so:
submitHandler: function() {
//Your submit button referenced by its ID
$("#mySubmitButton").doStuff();
}
Or, use the form element from your submitHandler function and find the submit button contained on that form:
submitHandler: function(form) {
//Via the form argument passed to the submitHandler
var btnSubmit = form.find(":submit");
}

Modify jQuery autocomplete not to submit eagerly on Enter

Our users complain that when they press the enter key after pasting or typing values in a jQuery autocomplete widget the form is submitted.
It's extremely annoying them when they copy-paste a value that exists in the autocomplete options the autocomplete widget opens to show that single value, they press Enter to accept that value but then the form is submitted before they finished filling all the fields because (by default and we don't want to change it) the widget won't select the first option in the menu.
<form>Type C and press Enter:
<input id="autocomplete" />
<input type="submit" value="submit" />
</form>
$('form').submit(function () {
alert('You submitted the form');
return false;
});
$('#autocomplete').autocomplete({
source: ["c#", "c", "c++", "java", "php", "coldfusion"]
});
DEMO of the problem
How can we change that clicking Enter will only close the autocomplete suggestions?
It seems like jQuery UI didn't left a backdoor to customize the widget out of the box, so what you can do is override the autocomplete function to register a callback for the onkeypress event, capture the Enter and stop the propagation so it won't submit the form if the widget is open=visible.
Here how it goes:
function cancelAutocompleteSumbission(e) {
// Make sure this is a nodeElement and the button pressed was Enter-Return
if (!this.nodeType || e.which != 13)
return;
// If the widget is visible we simply want to close the widget.
if ($(this).autocomplete('widget').is(':visible')) {
$(this).autocomplete('close');
return false;
}
}
// Making a private scope to avoid naming collision.
$.fn.autocomplete = (function () {
// Cache the old autocomplete function.
var oldAutocomplete = $.fn.autocomplete;
// This will be the new autocomplete function.
return function () {
// If the first argument isn't "destroy" which
// should restore the input to it's initial state.
if (!/^destroy$/i.test(arguments[0]))
// Attach event to the input which will prevent Enter submission as
// explained above.
this.keypress(cancelAutocompleteSumbission);
// We need to restore the input to it's initial state,
// detach the keypress callback.
else
this.off('keypress', cancelAutocompleteSumbission);
// Call the cached function with the give "this" scope and paramteres.
return oldAutocomplete.apply(this, arguments);
};
})();
Live DEMO
Notes:
To change all the autocomplete widgets you need to use jQuery's prototype, $.fn is an alias to $.prototype.
Also you need to change $.fn.autocomplete before you use it it or the changes you made won't apply to those widget.
this inside the autocomplete function is actually a jQuery object so you don't need to wrap it with $(this)
You might say, Hey you keep register the very same callback for the keypress event. Well, that's exactly what I'm doing and why I wrote the callback as a named function. If you pass the same callback to addEventListener it will register it only once. MDN, Specifications
Adding code to a javascript function programmatically
I might have a simpler solution by using jQuery autocomplete's autocompleteclose and autocompleteopen events.
See the code below:
var flag = 0; //global variable
$("#autocomplete").on({
autocompleteclose: function (event, ui) {
flag = 1;
//set flag back to 0 with a short delay so the next keypress can submit form
setTimeout(function () {
flag = 0;
}, 100);
},
//if the autocomplete widget is open, don't submit form on keypress
autocompleteopen: function (event, ui) {
flag = 1;
}
});
$('body').keypress(function(e) {
if (e.keyCode == '13') {
if (flag != 0) {
e.preventDefault();
} else {
//submit form
}
}
});​
var flag = 0; //global variable
$("#autocomplete").on({
autocompleteclose: function (event, ui) {
flag = 1;
//set flag back to 0 with a short delay so the next keypress can submit form
setTimeout(function () {
flag = 0;
}, 100);
},
//if the autocomplete widget is open, don't submit form on keypress
autocompleteopen: function (event, ui) {
flag = 1;
}
});
$('body').keypress(function (e) {
if (e.keyCode == '13') {
if (flag != 0) {
e.preventDefault();
} else {
//submit form
}
}
});
$('form').submit(function () {
alert('You submitted the form');
return false;
});
$('#autocomplete').autocomplete({
source: ["c#", "c", "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby"]
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<form>Type C and press Enter:
<input id="autocomplete" />
<input type="submit" value="submit" />
</form>
I was somehow against overriding the jqueryui implementation and did the following:
in the close event of the autocomplete i set a flag "doNotSubmit" when enter was pressed
in your case then i'd bound a submit event listener to the form which checks the doNotSubmit flag and acts accordingly.
The basic idea behind it, is that jqueryui's close event is triggered before keyup or submit events and gives you the keycode. So you can in another place (keyup, submit, etc.) consume that one unwanted enter or other keypress.
This question is similar to this one. While the solutions on that page are straight forward, they depend on the ID's of elements on the page. I use autocomplete on lots of pages so I prefer gdoron's approach (on this page). Thanks to him for doing the heavy lifting.
However, I think there is a bug in his code. If you go to an autocomplete field that already has content and type a return, it will submit the form. Here is a fix (the change is the second "if block in cancelAutocompleteSumbission):
function cancelAutocompleteSumbission(e) {
// Make sure this is a nodeElement and the button pressed was Enter-Return
if (!this.nodeType || e.which != 13)
return;
if (!$(this).autocomplete('widget').is(':visible') && e.which === 13){
return false;
}
// If the widget is visible we simply want to close the widget.
if ($(this).autocomplete('widget').is(':visible')) {
$(this).autocomplete('close');
return false;
}
}
// Making a private scope to avoid naming collision.
$.fn.autocomplete = (function () {
// Cache the old autocomplete function.
var oldAutocomplete = $.fn.autocomplete;
// This will be the new autocomplete function.
return function () {
// If the first argument isn't "destroy" which
// should restore the input to it's initial state.
if (!/^destroy$/i.test(arguments[0]))
// Attach event to the input which will prevent Enter submission as
// explained above.
this.keypress(cancelAutocompleteSumbission);
// We need to restore the input to it's initial state,
// detach the keypress callback.
else
this.off('keypress', cancelAutocompleteSumbission);
// Call the cached function with the give "this" scope and paramteres.
return oldAutocomplete.apply(this, arguments);
};
})();
Live Demo

Custom form validation using jquery plugin, based on attributes

I am using Jquery valdiation plugin for validating the form at client side. But I want to do the validation like.
<input type="text" id="txtInf" regex="/some regular expression/" error="Inf is mandatory"></inf>
here regex and error are custom attributes. Field will be validated against the given regular expression in regex and if the regular expression text fails then error meessage should be shown.
I tried to add a method to validator like this.
$("*[regex]").each(function () {
$.validator.addMethod($(this).attr('id'), function () {
return this.optional($(this)) || $(this).attr('regex').test($(this).text());
}, $(this).attr('error'));
});
But there is some issue, with the approach. Please let me know, if I am thinking it right.
If there is some other approach in your mind, please let me know. Any thought process is welcomed.
I haven't used that plugin, but it looks like you'll get an error from the use of test().
$(this).attr('regex').test($(this).text());
should be
var regEx = new RegExp($(this).attr('regex'));
regEx.test($(this).text());
custom form validation in bootstrap is possible using few lines of code
// Add below code in html
<form id="addForm" action=" " method="post" class="needs-validation" novalidate> </form>
// add this in script tag
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
document.getElementById("btn_inject").addEventListener("click", function(event) {
//form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})
();
//you will also need this to make the text boxes back to dismiss the validation
$("#Modalidname").on('hide.bs.modal', function() {
$("#Formidname").removeClass('was-validated');
});

Categories

Resources