Form validation on blur - javascript

I have 5 input fields and I want them to validate on blur, and show either an error or success message, but through DOM scripting and not with an alert box. I've tried several different codes, even just small bits and pieces to see if it's correctly interacting with my html but it doesn't seem to work.
So far, I have a small code to test if it even runs, and it's supposed to show an alert box but it does not. I would prefer to not use any innerHTML and use all functions within the javascript only.
My html:
<div id=fNID>
<label for="firstNameID">First Name: </label>
<input id="firstNameID" type="text" name="firstNameA" value="" />
<span> </span>
</div>
<div id=lNID>
<label for="lastNameID">Last Name: </label>
<input id="lastNameID" type="text" name="lastNameA" value="" />
<span> </span>
</div>
My javascript:
firstNameID = document.surveyForm.getElementById("firstNameID");
document.surveyForm.getElementById(fN).addEventListener("blur", validateName);
function validateName() {
var nameRegEx = /[a-zA-Z]+/;
var firstNameID = document.getElementById("firstNameID");
if (fN.matches(nameRegEx)) {
alert("Success!")
} else {
alert("error")
}
}
window.addEventListener("load", setupForm, false);
}

Bootstrap has a nice pattern for input validation. They use divs following the input: one for valid input, one for invalid input, making the appropriate one visible:
<div class="form-group">
<label for="uname">Username:</label>
<input class="form-control" id="uname">
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
Bootstrap's CSS classes modify the display based on the input's pseudo-classes :valid and :invalid.
You can set these pseudo-classes in JavaScript with the setCustomValidity() method.
input.setCustomValidity("input is invalid")
will assign the :invalid pseudo-class to the input.
input.setCustomValidity("")
will assign the :valid pseudo class.
A working example:
const input = document.getElementById('uname');
function makeValid() {
input.setCustomValidity('');
}
function makeInvalid() {
input.setCustomValidity('a problem');
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<h3 class="m-2">Bootstrap input with validation</h3>
<form class="was-validated mx-2">
<div class="form-group">
<label for="uname">Username (required):</label>
<input type="text" class="form-control" id="uname" placeholder="Enter username" name="uname">
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">This field is invalid.</div>
</div>
</form>
<div class="m-2">
<p>Use setCustomValidity() to change input state:</p>
<button onclick="makeValid();">:valid</button>
<button onclick="makeInvalid();">:invalid</button>
</div>
It's also worth noting that most browsers have native support for displaying validation messages on inputs. Here's an example that doesn't use any Bootstrap features:
const input = document.getElementById('uname');
function makeValid() {
input.setCustomValidity('');
}
function makeInvalid() {
input.setCustomValidity('this is invalid');
}
body {
background-color: #aaa;
}
.m-2 {
margin: .5rem;
}
.mt-5 {
margin-top: 1rem;
}
<body>
<h3 class="m-2">Generic input with validation</h3>
<form class="mt-5">
<label for="uname">Username:</label>
<input type="text" id="uname" placeholder="Enter username" name="uname">
<p>Use setCustomValidity() to change input state:</p>
<button onclick="makeInvalid();">input:invalid</button>
</form>
<div class="m-2">
<button onclick="makeValid();">input:valid</button>
</div>
</body>

Related

Jquery autocomplete - add value in multiple input fields

I need help with jquery autocomplete. The autocomplete by itself works fine, but I need to fill a value in another input field depending on the value of the first input.
I created https://jsfiddle.net/peh9c20a/ to show this problem.
I have a form with three rows, each row has two input fields. Autocomplete is implemented on the first column of inputs.
When selecting a value from the autocomplete (first column), the desired behavior is to fill the input field next to it with a random number. I am unfortunately able to fill all the inputs with a number, not only the input in the same row.
To describe this problem with the text is a little bit complicated, but I hope that the fiddle will help to understand it.
The form is made dynamically with clone() function, I can´t use different ID attributes for each input.
$('.item-name').autocomplete({
lookup:sourceData,
onSelect: function (suggestion) {
var number = Math.floor(Math.random()*100);
$(this).closest($(".item-id").val(number)); //THIS ROW HAS TO BE MODIFIED
}
});
do that:
to access of the input number linked to the input text, you have to go up to the div which is the parent of both. (sorry for my english)
$(this) => input changed
.closest("div.row") => find the first parent with div.row
.find("input[type=number]") => find the input number linked to the text
$('.item-name').autocomplete({
lookup:sourceData,
onSelect: function (suggestion) {
var number = Math.floor(Math.random()*100);
$(this).closest("div.row").find("input[type=number]").val(number);
}
});
var sourceData = [
"Peter",
"John",
"Adam",
"Zack",
"George",
"Richard",
"Brian",
"Frank",
"Lars",
"Quentin",
"Will"
];
$('.item-name').autocomplete({
lookup: sourceData,
onSelect: function(suggestion) {
var number = Math.floor(Math.random() * 100);
$(this).closest("div.row").find("input[type=number]").val(number);
}
});
.row {
background: #f8f9fa;
margin-top: 20px;
}
.col {
border: solid 1px #6c757d;
padding: 10px;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.4.1.slim.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.devbridge-autocomplete/1.2.27/jquery.autocomplete.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<div id="meal-container">
<div class="col-12" id="meal-div">
<div class="form-group">
<div class="row">
<div class="col-7">
<input type="text" placeholder="Add name" class="form-control item-name" name="item-name[]" />
</div>
<div class="col-5">
<input type="number" class="form-control item-id" name="id[]" />
</div>
</div>
</div>
</div>
<div class="col-12" id="meal-div">
<div class="form-group">
<div class="row">
<div class="col-7">
<input type="text" placeholder="Add name" class="form-control item-name" name="item-name[]" />
</div>
<div class="col-5">
<input type="number" class="form-control item-id" name="id[]" />
</div>
</div>
</div>
</div>
<div class="col-12" id="meal-div">
<div class="form-group">
<div class="row">
<div class="col-7">
<input type="text" placeholder="Add name" class="form-control item-name" name="item-name[]" />
</div>
<div class="col-5">
<input type="number" class="form-control item-id" name="id[]" />
</div>
</div>
</div>
</div>
</div>

How can I listen to all inputs that have a "required" attribute?

EDIT :
I have an input field and a checkbox. Checkbox allow to win "required" on this input field. I want to listen required, i mean if required is true or not. I don't want to listen checkbox.
==> When input win/lose required attribute, it trigger function (without use checkbox).
$(document).ready(function() {
$('input[type=checkbox]').click(function() {
cible_required_on = $(this).closest('.panel').find('.required_on');
if(!cible_required_on.prop('required')){
cible_required_on.attr("required", true);
} else {
cible_required_on.attr("required", false);
}
});
// Here my new function listening required attribute
});
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
</head>
<body>
<div class="panel panel-default" >
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-4 changement_position_champ" id="bottom_left">
<div class="panel">
<label> Raison Sociale</label>
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-use" ></i></span>
<input type="text" class="form-control required_on" placeholder="Raison sociale"
aria-describedby="basic-addon1">
</div>
</div>
<div class="checkbox">
<label><input type="checkbox" ><p>Checkbox trigger required on input field</p></label>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
$('input[required]').change(function(){
alert('required')
});
$('input[required]').change(function(){
alert('required')
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" required/>
<input type="text" />
Knowing I'm late to the party, here's my contribution:
// ES6 supported - () => {} , arrow-function
$(':input[required]').change((e) => {
alert("Changed: " + e.target.value);
});
// Older compatibility
/*
$(':input[required]').change(function(e) {
alert("Changed: " + e.target.value);
});
*/
input {
width: 200px;
display: block;
margin-bottom: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Type something and unfocus from input.</p>
<form action="#">
<input type="text" required />
<input type="text" required />
<input type="checkbox" required />
<input type="text" />
<input type="submit" />
</form>
As mentioned in the question the user requires to select the input with some conditions like it is the checkbox and is required. So instead of running a loop which is more memory eating, we can use the jquery filter selectors to achieve the goal.
Below is the example.
var a = $('input[required][type="checkbox"]');
console.log(a)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='checkbox' required>

Additional input fields when filling up previous

Im trying to add additional fields in case when my user has filled up one group of inputs. So the idea is that when he finishes filling up the last input in that group, another group of inputs for same kind of items collapses/appears under existing one. One group of items consists of three inputs. After filling up that one, another group of inputs would appear under. I will present my code under. Hope someone can help me!
<div class="new-providers">
<div class="provider-append" id="toggleExtraProvider">
<div class="form-group">
<label>Provider</label>
<input type="text" class="form-control" id="practiceProvider" placeholder="Full provider name with coredentials" />
</div>
<div class="form-group">
<label>NPI</label>
<input type="text" class="form-control" id="providerNPI" placeholder=" NPI" />
</div>
<div class="form-group">
<label>MM #</label>
<input type="text" class="form-control" id="providerM" placeholder="M Provider #" />
</div>
<hr />
</div>
</div>
I tried appending the provider-append class on to the new-providers class
This is my jQuery script:
<script type="text/javascript">
$(document).ready(function() {
$("#toggleExtraProvider div.form-group input").each(function() {
if($(this).val() =! "") {
var target = $("new-providers");
target.append(".provider-append");
}
});
});​
</script>
You need to check for empty input box in a particular div use filter() for that
and use jQuery clone() to clone the parent div (input group) if all input box filled. And you should use change event instead of input, Since input will be overkill here it will run each time when you change a single character in text box on the other hand change event fires when user finish typing and input box loose focus.
$(document).ready(function () {
$(document).on("change",".provider-append input",function(){
var allHaveText;
var parentDiv = $(this).closest("div.provider-append");
emptyInputs=parentDiv.find("input[type=text]").filter(function () {
return !this.value;
});
if(emptyInputs.length==0)
{
newGroup = parentDiv.clone().appendTo(".new-providers");
newGroup.find("input[type=text]").each(function(){
$(this).val("");
});
}
});
});
Here is a working sample
$(document).ready(function () {
$(document).on("change",".provider-append input",function(){
var allHaveText;
var parentDiv = $(this).closest("div.provider-append");
emptyInputs=parentDiv.find("input[type=text]").filter(function () {
return !this.value;
});
if(emptyInputs.length==0)
{
newGroup = parentDiv.clone().appendTo(".new-providers");
newGroup.find("input[type=text]").each(function(){
$(this).val("");
});
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="new-providers">
<div class="provider-append">
<div class="form-group">
<label>Provider</label>
<input type="text" class="form-control" placeholder="Full provider name with coredentials" />
</div>
<div class="form-group">
<label>NPI</label>
<input type="text" class="form-control" placeholder=" NPI" />
</div>
<div class="form-group">
<label>MM #</label>
<input type="text" class="form-control" placeholder="M Provider #" />
</div>
<hr />
</div>
</div>
I hope it will help you.

Add a placeholder to several input fields (with the same class) using javascript

I have an HTML form with 4 inputs fields inside it. All these input fields have the same class and ID, the only differences are the "divs" surounding the inputs.
One form is in the header the other one in the content, and inside each of them, one field is a username field to login, and the other one to register.
<div class=theheader>
<h1> The Header</h1>
<div class="fullform">
<div class="container register">
<div class="form_group required">
<input class="input_text" id="username_field" name="username" size="30" value="" type="text">
</div>
</div>
<div class="container login">
<div class="form_group">
<input class="input_text" id="username_field" name="username" size="30" type="text" >
</div>
</div>
</div>
</div>
<div class=thecontent>
<h1> Form Content</h1>
<div class="fullform">
<div class="container register">
<div class="form_group required">
<input class="input_text" id="username_field" name="username" size="30" value="" type="text">
</div>
</div>
<div class="container login">
<div class="form_group">
<input class="input_text" id="username_field" name="username" size="30" type="text" >
</div>
</div>
</div>
</div>
Here is an example of what it looks like : http://jsfiddle.net/M6R7K/78/.
I need to add a placeholder inside each of these fields, but the tricky thing is, I don't have any direct access to this HTML code, because this one is automatically generated by a third party plugin. So I can only add javascript or css, using the existing classes and ids.
So I used the javascript :
document.getElementById("username_field").setAttribute("placeholder", "Username");
And it has indeed add the correct placeholder in the correct field. The problem is, it only add the placeholder in the 1st field found, not all of them. Even if I add several lines of javascript.
So the question : How to fill up all these field with a placeholder without touching the HTML code ? (With javascript or anything else) And at the best possible, having a different placeholder for each field ? (One needs to be "username and email", and the other one "username" only). We should be able to use the classes of the div's, just like we can do in CSS. But I wasn't able to figure it out.
Thanks !
Your code set placeholder one of them. Standard don't define which of them will get the placeholder because standard forces you tou use ID only once per page. You need to set placeholders for all elements with input_text class. You can do it by array with placeholders and iterating fields: In each iteration set i-th placeholder from array by this code
var placeholders = ["Username", "Email", "Phone", "Credit card"]
var elements = document.getElementsByClassName("input_text");
for (var i = 0; i < elements.length; i++) {
elements[i].setAttribute("placeholder", placeholders[i]);
}
Example: http://jsfiddle.net/M6R7K/81/
The best practice is set placeholders normally in HTML.
First of all you cannot use the same id for more then one element.
Second: try to use as input name attribute meaningful values. If you cannot touch the HTML you can always use the index parameter inside the forEach loop, this could be an idea. Another idea could be to look for the root element in order to distinguish the input fields.
I tried to do for you, right to give you an idea on how to solve your problem:
window.onload = function() {
Array.prototype.slice.call(document.getElementsByClassName("input_text")).forEach(function(currentValue, index) {
currentValue.setAttribute("placeholder", currentValue.getAttribute('name'));
});
}
<div class=theheader>
<h1> The Header</h1>
<div class="fullform">
<div class="container register">
<div class="form_group required">
<input class="input_text" id="username_field1" name="username" size="30" value="" type="text">
</div>
</div>
<div class="container login">
<div class="form_group">
<input class="input_text" id="username_field2" name="password" size="30" type="text" >
</div>
</div>
</div>
</div>
<div class=thecontent>
<h1> Form Content</h1>
<div class="fullform">
<div class="container register">
<div class="form_group required">
<input class="input_text" id="username_field3" name="email" size="30" value="" type="text">
</div>
</div>
<div class="container login">
<div class="form_group">
<input class="input_text" id="username_field4" name="other" size="30" type="text" >
</div>
</div>
</div>
</div>
I have been able to find the solution, using the "attr" function, and the Jquery framework.
This is the function that I applied to each of the inputs, in order to create a unique placeholder (example for the 1st field) :
$(".theheader .register input").attr('placeholder', 'Username Header')
This code allows to retrieve the DIV CLASS of each input field, and apply a customized field.
So for my example, it would be this :
$(".theheader .register input").attr('placeholder', 'Username Header')
$(".theheader .login input").attr('placeholder', 'Username or Email Header');
$(".thecontent .register input").attr('placeholder', 'Username Content');
$(".thecontent .login input").attr('placeholder', 'Username or Email Content');
And each field has his customized placeholder !
Here is the result : https://jsfiddle.net/3ddo465n/9/
Thank you all for the contribution !

run.google.script only if form is complete

I'm trying to create a form using the google scripts that will not allow submission unless all the fields are entered. Currently, I use the "onclick" command to run a google script that send the form data and files to my google drive. However, I only want the form to be submittable if certain fields are filled in (those marked required). If I remove the google.script.run command from the "onclick" portion of the submit button, then the form creates alerts/messages that say the user must fill in the required form. These messages do not appear when the google.script.run command is included. I haven't figured out a way to make it so that the google.script.run command only runs if all fields are completed.
<!-- Include the Google CSS package -->
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<!-- You can also include your own CSS styles -->
<style>
form { margin: 40px auto; }
input { display:inline-block; margin: 20px; }
</style>
<form id="myForm" name="myForm">
<label for="myFirstName"> First Name *</label>
<input type="text" name="myFirstName" placeholder="First name" style="width: 150px;" required>
<fieldset>
<legend> Personal Information </legend>
<div class="inline form-group">
</div>
<div class="inline form-group">
<label for="myLastName"> Last Name* </label>
<input type="text" name="myLastName" placeholder="Last Name" style="width: 150px;" required>
</div>
<div class="inline form-group">
<label for="myEmail"> Email* </label>
<input type="email" name="myEmail" placeholder="" style="width: 150px;" required>
</div>
<div class="inline form-group">
<label for="visa"> Check if you will require visa assistance. Otherwise, ignore. </label>
<input type="checkbox" name="visa" value="Yes">
</div>
</fieldset>
<fieldset>
<legend> Documents </legend>
<div class="inline form-group">
<label for="CV"> CV* </label>
<input type="file" name="CV" required>
</div>
<div class="inline form-group">
<label for="CoverLetter"> Cover Letter </label>
<input type="file" name="CoverLetter">
</div>
</fieldset>
<p> </p>
<input id="submitbutton" type="submit" style="margin-left:450px" value="Submit Application"
onclick="this.value='Submitting...';
google.script.run.withSuccessHandler(fileUploaded).uploadFiles(this.parentNode);
return false;">
</form>
<div id="output"></div>
<script>
function fileUploaded(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('output').innerHTML = status;
}
</script>
<style>
input { display:block; margin: 20px; }
</style>
The googlescript runs fine. I'm also aware of some similar questions about form validation. The google script specific ones do not use the same form format (they create the form in google script). I would like to make as minimal changes as possible to achieve the required functionality.
Any help would be appreciated.
Current code for jquery:
$('#submitbutton').on('click', function() {
$(this).val("Validating...");
//check for required fields
var emptyFields = $('[required]').filter(function() {
$(this).removeClass("warning");
if ($(this).val().length === 0){
$(this).addClass("warning")
return true
} else {
return false
}
});
if (emptyFields.length === 0) {
google.script.run.withSuccessHandler(fileUploaded).uploadFiles(this.parentNode);
} else{
$(this).val("Submit Application")
}
});
Your form is submitting before the messages can appear. One way to handle this is to change your button to a button (instead of type submit), and then trigger an event on click. Check for your validation, and if everything passes, submit your form.
example:
change your button to:
<input id="submitbutton" type="button" style="margin-left:450px" value="Submit Application" >
and the click event:
$('#submitbutton').on('click', function() {
$(this).val("Validating...");
//check for required fields
var emptyFields = $('[required]').filter(function() {
$(this).removeClass("warning");
return $(this).val().length === 0;
});
if (emptyFields.length > 0) {
emptyFields.addClass("warning");
} else {
google.script.run.withSuccessHandler(fileUploaded).uploadFiles(this.parentNode);
$('#myForm').submit();
}
});
and CSS
.warning {border: 1px solid red; }

Categories

Resources