Simple Form Validation to Check Empty Inputs and Display Message - javascript

I'm attempting a simple form validation where if the input field is empty, the user will see a message asking to fill out any fields that are empty.
I'm able to loop and find which fields are empty and display a message, but the message will only display the last input field that was looped. How do I get the message to display all input fields that are empty?
HTML:
<label>Name</label>
<input class=formInput" name="name" />
<label>Email</label>
<input class=formInput" name="email" />
<label>Message</label>
<textarea class=formInput" name="message" />
<span id="fail-message"></span>
JS:
let inputFields = document.getElementsByClassName('formInput');
for (var i = 0; i < inputFields.length; i++) {
if (inputFields[i].value === '') {
document.querySelector('#fail-message').innerHTML =
'Please fill out ' +
inputFields[i].getAttribute('name') +
' field(s)';
}
}
This currently outputs "Please fill out message field(s)"
Assuming all is empty, I'd like it to output "Please fill out name, email and message field(s)"

The code you have overwrites the innerHTML completely every time it finds an empty field. What you should do instead is keep an array of all the empty fields, then only write the innerHTML once after the loop, with the list of fields it found.
let inputFields = document.getElementsByClassName('formInput');
const emptyFieldNames = [];
for (var i = 0; i < inputFields.length; i++) {
if (inputFields[i].value === '') {
emptyFieldNames.push(inputFields[i].getAttribute('name'));
}
}
if (emptyFieldNames.length > 0) {
document.querySelector('#fail-message').innerHTML = 'Please fill out the following fields: ' + emptyFieldNames.join(', ');
}

You overwrite the innerHTML of the message span in every iteration. You should concatenate the new error to it or use separate spans.

You would have to build an array containing the fields name that are not valid ... right now, you "overwrite" the innerHTML of the #fail-message element with the latest field (aka, it is INSIDE your loop to be rewritten each time the condition is met in the loop).
Add the names of the field in array (do not rewrite the whole array) and then use "yourArray.join()" to output all the names in the innerHTML of the correct element, like you do inside your loop.

You are replacing the value in the span element everytime you go through the loop. So only the last empty form element will be shown as fail message. Instead, you have to concatenate each string and then show it together.
Here is the complete code that will work for you:
<html>
<head>
<script>
function myFunction() {
let inputFields = document.getElementsByClassName('formInput');
let message ='';
for (var i = 0; i < inputFields.length; i++) {
console.log(inputFields[i].value);
if (inputFields[i].value === '') {
message = message + inputFields[i].getAttribute('name') + ', ';
}
}
let n = message.lastIndexOf(",");
message = message.substring(0,n);
document.querySelector('#fail-message').innerHTML =
'Please fill out ' +
message +
' field(s)';
}
</script>
</head>
<body>
<label>Name</label>
<input class="formInput" name="name" />
<label>Email</label>
<input class="formInput" name="email" />
<label>Message</label>
<textarea class="formInput" name="message"> </textarea>
<button onclick="myFunction()">Submit</button>
<span id="fail-message"></span>
</body>
</html>

Related

How to validate all inputs which exists on page?

All inputs from page
I have this html page which is dynamical created, which contains some divs. Every div-question(0,1,2, etc) contain an input based on which answer type the user chose. I want to validate every single inputs from page and:
If value of one input type number,text,date is != "" alert("something")
else send the value in an array;
If checkbox/radio is not checked alert("something");
I tried something like this:
let nrDiv = document.getElementsByClassName("div-question");
let existInput = nrDiv[0].querySelector("input[type='text']");
let numberInput = nrDiv[0].querySelector("input[type='number']");
if (document.body.contains(existInput)) {
for (let i=0; i < nrDiv.length ;i++) {
let container = document.getElementsByClassName("div-questions" + i + "");
let userInputAnswer = container[0].querySelector("input[type='text']");
if (userInputAnswer.value == "") {
alert("Adaugati un raspuns!")
return;
}
if (userInputAnswer.value != ""){
let answer = {
question: questions[i].textQuestion,
answer: userInputAnswer.value
}
answers.push(answer);
}
}
}
It's working but if I come with another for loop, for input type="number" is not working anymore. I'm getting value null. So if I come with this:
if (document.body.contains(numberInput)) {
for (let i=0; i < nrDiv.length ;i++) {
let container = document.getElementsByClassName("div-questions" + i + "");
let userInputAnswer = container.querySelector("input[type='number']");
if (userInputAnswer.value == "") {
alert("Adaugati un raspuns!")
return;
}
if (userInputAnswer.value != ""){
let answer = {
question: questions[i].textQuestion,
answer: userInputAnswer.value
}
answers.push(answer);
}
}
}
And for the checkbox and radio inputs I don't have any idea. I want something like this:
If all inputs are not empty and minimum one checkbox/radio is checked, send the answer and question in an array else alert("error");
I feel like this is simple once you add the required attribute and/or a pattern.
This is a simple POC:
<form action="">
<input type="text" required>
<input type="number" required>
<input type="checkbox" required>
<input type="radio" required>
<input type="date" required>
<button type="submit">Submit</button>
</form>
Notice that when you click the submit button, it does the verification you want, in this case != "".

How can i remove the repeating words in my html input field

<input id="btn-input" type="text" class="form-control input-sm" placeholder="Type your message here..." name="subject" pattern=".+?(?:[\s'].+?){2,}" autofocus required title="" />
I have a problem with this, it is inserting when i insert repeating words like
college college college
and i also wanto to have a question format it is possible?
also open for java script suggestions even i already have
This works pretty good (when user pastes, inserts anything):
Code Snippet:
<!DOCTYPE HTML>
<html>
<body>
<input id="btn-input" type="text" class="form-control input-sm" placeholder="Type your message here..." name="subject" pattern=".+?(?:[\s'].+?){2,}" autofocus required title="" />
<button id="toggleduplicates">Toggle allowing duplicates</button>
<script>
// I added this to allow duplicates
let allowDuplicates = false;
var element = document.getElementById("btn-input"),
togglebtn = document.getElementById("toggleduplicates");
function handler(e){
if(!allowDuplicates){
var userInput = element.value,
allWords = userInput.split(" "),
searchedWords = [];
// Search thru all words (Indicating words by splitting the input in spaces, as done in the "allWords" variable)
for(i = 0; i < allWords.length; i++){
// If the current word (allWords[i]) already is in the searchedWords array
if(searchedWords.includes(allWords[i]))
element.value = element.value.replace(allWords[i] + " ", "");
// Adds the word to the list of used words
searchedWords.push(allWords[i]);
}}}
// Execute the function "handler" when the input field is updated
element.addEventListener("input", handler);
function toggleHandler(){
// Setting the allow duplicates boolean to the value that is not currently (true -> false / false -> true)
allowDuplicates = !allowDuplicates;
// Updates the input, in case it would include duplicates
handler();
alert("You may now " + (!allowDuplicates ? "NOT ":"") + "use duplicate words.");
}
// Execute the function "toggleHandler" when the button is clicked
togglebtn.addEventListener("click", toggleHandler);
</script>
</body>
</html>

Compare input text with person name belongs to only one input number id

Im trying to write a validation for 2 groups of fields. I have 6 inputs, 3 for text name and 3 more for id number... the validation should do this "if input name="RE_SignedByID" has an input type name="RE_SignedByName", then other inputs name="RE_SignedByID", should NOT contain the same name="RE_SignedByName" More easy explanation... one ID number should have only one Person Name (Id number is unique for one person name). What can I use for that? Should I map() all the inputs?
Those are my inputs:
<div id="signedBy" class="clearfix">
<label>Signer, person ID & name</label>
<span id="signedByID" class="ids half">
<input type="text" name="RE_SignedByID" placeholder="personID, person1" data-validate="" tabindex="101" required>
<input type="text" name="RE_SignedByID" placeholder="personID, person2" data-validate="" tabindex="103">
<input type="text" name="RE_SignedByID" placeholder="personID, person3" data-validate="" tabindex="105">
</span>
<span class="names half">
<input type="text" name="RE_SignedByName" placeholder="name, person1" tabindex="102" required>
<input type="text" name="RE_SignedByName" placeholder="name, person2" tabindex="104">
<input type="text" name="RE_SignedByName" placeholder="name, person3" tabindex="106">
</span>
</div>
I guess it should also be an "on change" function? or can I make the validation on click? Some ideas...? Im actually compleatley lost here...
Thanks in advance!!!
Maybe use different class names for all 3 of them to make them unique?
<input class="name1">
<input class="name2">
<input class="name3">
I'm not sure what you mean but if you want to make the input types unique and not call them all when you write class="names half", then you should give them all unique class names.
So from my understanding you don't want multiple fields to have the same value.
My approach would be this:
let inputTimeout = null; //set an empty timeout object
let vars = [null, null, null, null]; // create an array containing as many nulls as you have inputs
$('.nameInput').on('keyup', function(){
let self = $(this);
clearTimeout(inputTimeout); //clear the timeout
inputTimeout = setTimeout(function(){ //set a timeout to check whether there is a dupe after the user has stopped typing
if (vars.indexOf(self.val()) == -1){ //check if the vals array contains the newly entered string
vars[self.attr('data-inputnum')] = self.val(); //insert the value into the array
}else{
//handle duplicates here
}
}, 500); //500ms is a sensible value for end of user input, change it if users complain that your app is too fast/slow
});
You then just have to edit your HTML a bit so that all name inputs have a class in common (i used .nameInput) and have a data-inputnum attr.
This would look something like this:
<input type="text" name="RE_SignedByName" placeholder="name, person1" tabindex="102" class='nameInput' data-whichinput='0'/>
<input type="text" name="RE_SignedByName" placeholder="name, person2" tabindex="103" class='nameInput' data-whichinput='1'/>
<!--and so on-->
Of course, never rely on JavaScript verification alone, always also check inside your backend. However this would be out of scope for this answer.
Hi Thanks all for the help, made me realize a couple of things till I got the answer. This is my working code:
var valSignedID = $("[name=SignedByID]").map(function() {
return this.value.trim();
}).get();
var valOwnersID = $("[name=OwnersID]").map(function() {
return this.value.trim();
}).get();
valSignedID.sort();
valOwnersID.sort();
for (var i = 0; i < valSignedID.length - 1; i++) {
if (valSignedID[i] == valSignedID[i + 1] && valSignedID[i] != "") {
alert(" You can not have duplicated signers ID's");
return false;
// break;
}
}
for (var i = 0; i < valSingedName.length; i++) {
if (valSingedName[i] == valSingedName[i + 1] && valSingedName[i] != "") {
alert(valSingedName[i] + " should not have different ID");
//return false;
}
}

How to display input values from textfields with array name attributes using javascript

I have created a form which should submit data, but before submission I want the user to have a preview of what they have filled before clicking on the submit button.
The JavaScript function I have put in place, only shows input values from only one of the textfield.
what I expect was that for each textfield I would get its input values displayed.
Currently, I am getting just one value from the textfields with this same id.
How can I adjust my code to show value of each textfield .
// function and element to view input value
function myFunction() {
var Milstonedescription =
document.getElementById("milstanedetails").value;
document.getElementById("Milestonesdescriptionvalue").innerHTML =
Milstonedescription;
}
<input type="text" class="milstone" id="milstanedetails" placeholder="Describe the milestone or task you will complete" oninput="myFunction()" name="milestone[]">
<input type="text" class="milstone" id="milstanedetails" placeholder="Describe the milestone or task you will complete" oninput="myFunction()" name="milestone[]">
<p class="halffieldcontainer" id="Milestonesdescriptionvalue"></p>
The problem on your code is that you use the same id on multiple input field, thats not possible because id are unique and whatever you will get only the first element with the matching id.
If you want to get your value from each fields you should use getElementsByClassName('className') and looping on, it's seems to correspond to what you want to do.
EDIT :
Yeah last version didn't work properly, i edited and tested that one. Seems to work properly on my side now. ( http://jsfiddle.net/tgo46se2/ )
function myFunction() {
let milstones = document.getElementsByClassName("milstone");
let milstoneDescription = '';
for(let i = 0; i < milstones.length; ++i) {
milstoneDescription += milstones[i].value;
}
document.getElementById("Milestonesdescriptionvalue").innerHTML = milstoneDescription;
}
this could works:
<!doctype html>
<head></head>
<body>
<p id="text"></p>
<input type="text" class="milstone" id="milstanedetails" placeholder="Describe the milestone or task you will complete" oninput="myFunction('milstanedetails','Milestonesdescriptionvalue')" name="milestone[]">
<input type="text" class="milstone" id="milstanedetails2" placeholder="Describe the milestone or task you will complete" oninput="myFunction('milstanedetails2', 'Milestonesdescriptionvalue')" name="milestone[]">
<p class="halffieldcontainer" id="Milestonesdescriptionvalue"></p>
</body>
<script>
// function and element to view input value
function myFunction(idEl, idPrev) {
var Milstonedescription =
document.getElementById(idEl).value;
document.getElementById(idPrev).innerHTML =
Milstonedescription;
}
</script>
</html>
I change the second id because in html id must be unique.
I hope this help
first, you have to make each input id unique because using the same id value for multiple elements is not valid in HTML.
you can achieve what you want by this code:
function myFunction(){
var nodes = document.querySelectorAll("[name='milestone[]']");
var input_value1 = nodes[0].value;
var input_value2 = nodes[1].value;
var text = '';
if(input_value1 && input_value1 !== ''){
text += 'first input value: ' + input_value1;
}
if(input_value2 && input_value2 !== ''){
text += '<br /> second input value: ' + input_value2;
}
document.getElementById("Milestonesdescriptionvalue").innerHTML = text;
}
<input type="text" class="milstone" id="milstanedetails1" placeholder="Describe the milestone or task you will complete" oninput="myFunction()" name="milestone[]">
<input type="text" class="milstone" id="milstanedetails2" placeholder="Describe the milestone or task you will complete" oninput="myFunction()" name="milestone[]">
<p class="halffieldcontainer" id="Milestonesdescriptionvalue"></p>
and here is a working snippet.
Get inputs by class attribute.
function myFunction() {
var milstones = document.getElementsByClassName("milstone");
var milstoneDescription = '';
for (var i = 0; i < milstones.length; i++) {
var val = milstones[i].value;
if (typeof val != "undefined")
milstoneDescription += val + ' ';
}
document.getElementById("Milestonesdescriptionvalue").innerHTML = milstoneDescription;
}

Skip field if empty

I have 4 fields that can be filled in by end user. I would like to send the contents of these in an email but I don't want blank spaces in the email. What I am looking for is a way to ignore those empty field and only return those that have value. I have this piece of code but it only ever returns the last value :
var Textbox = Browser.getValue("myTextBox");
var Field1 = Browser.getValue("myField1");
var Field2 = Browser.getValue("myField2");
var Field3 = Browser.getValue("myField3");
var Field4 = Browser.getValue("myField4));
if (Field1 != "" ){
Browser.setValue(TextBox), (Field1 += "\n" + Textbox));
}
if (Field2 != ""){
Browser.setValue(Textbox), (Field2 += "\n" + Textbox));
}
if (Field3 != ""){
Browser.setValue(Textbox), (Field3 += "\n" + Textbox));
}
if (Field4 != ""){
Browser.setValue(Textbox), (Field4 += "\n" + Textbox));
}
Can anyone help me? I basically need that the Textbox after each statement in updated and used in the next using just Javascript.
Thank you in advance
You seem to be trying to do something like the following. It goes over all the controls in the form and gets all the values that aren't the initial value and writes them to the textarea on new lines.
<script>
// Collect all the non–default values in the form and write
// on new lines to the text area
function consolidateValues(form) {
// Get the textarea to write values to
var textArea = form.myTextBox;
// Get all controls in the form
var control, controls = form.elements;
// Variable to hold the consolidated value
var text = [];
// Collect all the values, skipping the first control
for (var i=1, iLen=controls.length; i<iLen; i++) {
control = controls[i];
if (control.value != control.defaultValue) {
text.push(control.value);
}
}
// write the value to the text area
textArea.value = text.join('\n');
// Stop form from submitting
return false;
}
</script>
<form onsubmit="return consolidateValues(this)">
<textarea name="myTextBox" size="100" rows="10"></textarea>
<br>
<input name="myField1">
<br>
<input name="myField2">
<br>
<input name="myField3">
<br>
<input name="myField4">
<br>
<input type="submit"> <input type="reset">
</form>

Categories

Resources