Pass parameter in addEventListener - javascript

I have a closure function in javascript and that i just want to call on addEventListener. I am not using ES6 so that i can not use static method with class.
function validationFunction()
{
let _validateAlphaNumeric = function (param1)
{
return /^[0-9a-zA-Z]+$/.test(param1);
}
let _customValidation = function (param1,param2){
let a = new RegExp(param2);
return a.test(param1);
}
return {
ValidateAlphaNumeric : _validateAlphaNumeric,
CustomValidation :_customValidation
}
}
function valid(){
var validation = new validationFunction();
if(validation.ValidateAlphaNumeric(document.getElementById("Name").value)){
document.getElementById("ErrorName").innerHTML = "Alpha numeric";
}
else{
document.getElementById("ErrorName").innerHTML = "Some error";
}
if(validation.CustomValidation(document.getElementById("Name").value,"[A-Za-z]{3}"))
{
document.getElementById("ErrorName1").innerHTML = "True";
}
else{
document.getElementById("ErrorName1").innerHTML = "False";
}
}
<input type="button" value="Save" onclick="valid();">
<br>
<input type="text" id="Name">
<br>
<span id="ErrorName" style="color:red"></span>
<br>
<span id="ErrorName1" style="color:red"></span>
This works fine for me, problem came when i am trying to this function using addEventListener. I know that i can use pattern attribute in html5 for validation, but its not about validation i have to do some more stuff onkeypress. I do not want to make another method for it.

Related

Check if value matches any of the other values in array in JS ES6

I have tried a few things. Not sure where I'm going wrong.
I have a form where the user needs to put in all the people who are attending:
Person 1
Name
DOB
Email
Person 2
Name
DOB
Email
etc
I need to work out if any of the "Email" values are the same.
So I orginally thought get all the inputs:
let checkEmails = document.querySelectorAll("[data-email='email']");
and when each of those is updated run a function to check and pass the value:
for (const inputs of Array.from(checkEmails)) {
inputs.onchange = function(){
const value = this.value;
checkMatchingEmails(value);
};
}
First I tried using the "includes" method, but it was always returning "doesn't match", wasn't sure how to debug that so I tried different methods.
function checkMatchingEmails(value){
if (Array.from(checkEmails).includes(({ value }) == value)) {
console.log("matches");
} else {
console.log("doesnt match");
}
}
checkMatchingEmails();
If you can see my issue here please stop reading as I just mention other methods I tried:
Another method:
function checkMatchingEmails(value){
let checkEmailValues = document.querySelectorAll("[data-pnr-field='passportNumber'].value");
for (const inputValues of Array.from(checkEmailValues)) {
if(inputValues == value) {
console.log("matches");
} else {
console.log("doesnt match");
}
}
}
checkMatchingEmails();
Hope you can help me.
Solved it with:
let checkEmails = [];
const checkEmailValues = document.querySelectorAll("[data-pnr-field='passportNumber']");
checkEmailValues.forEach(item => item.addEventListener('change', checkMatchingEmailValues));
function checkMatchingEmailValues(e) {
const email = e.target.value;
if(checkEmails.includes(email)){
console.log("email matches");
console.log(e);
} else {
console.log("email doesnt match");
checkEmails.push(email);
}
console.log(checkEmails);
}
There are a couple of mistakes in your code.
Mistake 1
document.querySelectorAll("[data-email='email']")
returns a NodeList.
You cannot check if it includes a string value and will always return false.
You should check the documentation on Array.includes
Mistake 2
inputs.onchange = function(){
This is not how we add event listeners.
Use inputs.addEventListener("change", function)
Refer the documentation here 👉 Event handlers
Possible solution
You should basically create an Array of string values and do an includes on the same. Also you might need to track the index of each element.
A rough implementation might look like below. You can run the snippet and see the validation errors.
let checkEmails = document.querySelectorAll("[data-email='email']");
let emailsEntered = [];
for (let i = 0; i < checkEmails.length; i++) {
checkEmails[i].addEventListener("change", (e) => {
const value = e.target.value;
if (!checkMatchingEmails(value)) {
emailsEntered[i] = value;
e.target.nextElementSibling.innerHTML = "";
} else {
e.target.nextElementSibling.innerHTML =
`This value is already entered at index ${emailsEntered.indexOf(value)}`
}
console.log(emailsEntered);
});
}
function checkMatchingEmails(value) {
return emailsEntered.includes(value);
}
<input type="text" placeholder="Enter a value" data-email="email" />
<div id="error" style="color:red"></div>
<input type="text" placeholder="Enter a value" data-email="email" />
<div id="error" style="color:red"></div>
<input type="text" placeholder="Enter a value" data-email="email" />
<div id="error" style="color:red"></div>
<input type="text" placeholder="Enter a value" data-email="email" />
<div id="error" style="color:red"></div>
Please note that this is just a rough draft and not all the edge cases might be handled.

Regex always returning either always true or always false regardless of valid test value

I am trying to validate a form field using Regex. The field should contain 5 numbers (ie 12345 = valid, 1234a = invalid, 123456 = invalid), that is it. no more, no less. The problem is with different regex formats, the .test() method either always returns true, or always returns false. It never works for correct values and fails for incorrect values. All regex testers test the regex successfully for JavaScript but when I add it to my page (WordPress), I get these issues. I read up about the /g field should be removed and tried all that. still no luck.
HTML:
<form name="newform" action="Create.php" onsubmit="return validateForm()" method="POST" >
Code <br/><br/><input id="code" class="form-control" type="text" value="" name="code" onkeypress="CodeStyleRefresh()" />
<button type="submit" id="submit" name="submit">Create</button>
</form>
JavaScript:
<script type="text/javascript">
function validateForm(){
var CodePattern = new RegExp(/\b\d{5}\b/);
if(CodePattern.test(document.forms["newform"]["code"].value) == true)
{
return true;
}
else
{
return false;
}
}
function CodeStyleRefresh(){
document.getElementById("code").setAttribute("style", "background-color: #ffffff;");
}
</script>
Some other ways I have tried to specify the expression:
var CodePattern = new RegExp(/\b\d{5}\b/);
var CodePattern = new RegExp('/\b\d{5}\b/');
var CodePattern = /\b\d{5}\b/;
var CodePattern = '/\b\d{5}\b/';
var CodePattern = \b\d{5}\b;
var CodePattern = '\b\d{5}\b';
This is my first time ever touching regex and I am fairly new to the JavaScript family as well. Not having such a good time.
UPDATE:
I have gone back to basics. My JavaScript now looks as follows based on a few suggestions:
function validateForm(event)
{
console.log("Im running the script!");
console.log(event.target.querySelector("[name=code]").value);
var CodePattern = new RegExp(/\b\d{5}\b/);
var codeVal = event.target.querySelector("[name=code]").value;
if(CodePattern.test(codeVal) == true)
{
alert("Expression Passed!");
}
else
{
alert("Expression Failed!");
return false;
}
}
My HTML is now:
<form name="newform" onsubmit="return validateForm(event)" method="POST">
Code
<input id="code" class="form-control" type="text" value="" name="code" />
<button type="submit" id="submit" name="submit">Create</button>
</form>
Still this expression is only hitting the failed state and alerts expression failed.
If it helps, I am adding the JavaScript to a WordPress page, the form is normal html on the same page. I have tried adding the JavaScript to both the header and the footer but this does not change anything. I'm starting to think I should just check if the length of the field = 5 and if I can then cast it to an int instead of using RegEx at all!
Your regex is fine. If you are only getting the error when you upload your code to your wordpress site, I'd be tempted to say that your problem is your context, perhaps you have more than one form with the same name?
Try a context aware piece of code, update your html to:
<form name="newform" onsubmit="return validateForm(event)" method="POST">
Code
<input id="code" class="form-control" type="text" value="" name="code" onkeypress="CodeStyleRefresh()" />
<button type="submit" id="submit" name="submit">Create</button>
</form>
And your javascript:
function validateForm(event){
var myRegex = new RegExp(/\b\d{5}\b/);
//event.target holds the node element that triggered the function in our case, the Form itself
var myValue = event.target.querySelector("[name=code]").value; //here we find the input with the name=code inside the form that triggered the event
return myRegex.test(myValue) //return true if it passed, false if not
}
Since I cannot insert this much code in comments, I am posting an answer here to show how it all works.
function validateForm(frm, evt)
{
var codeVal = frm.code.value;
var CodePattern = /\b\d{5}\b/;
// comment below line after testing
evt.preventDefault();
if(CodePattern.test(codeVal) == true)
{
console.log("Expression Passed!");
return true;
}
else
{
console.log("Expression Failed!");
return false;
}
}
<form name="newform" onsubmit="return validateForm(this, event)" method="POST">
Code <br/><br/>
<input id="code" type="text" value="abc 12345 foo bar" name="code" />
<input type="submit" id="submit" name="submit" value="Create" />
</form>
Thank you for all the suggestions. I have learnt a few things by looking at them all and I have made a few changes.
I could not however get the regex to work properly in wordpress. I was forced to create a longwinded, dirtier solution to this. I will continue to look at possible solutions and test on other wordpress sites, but for now, this is the code I am using to validate the field:
function validateForm(frm, evt)
{
var codeVal = frm.code.value;
console.log("Code Value: " + String(codeVal));
// comment below line after testing
evt.preventDefault();
var lenPass = false;
var strlen = codeVal.length;
if(strlen == 5)
{
lenPass = true;
}
if(lenPass)
{
var c1 = Number.isNaN(Number(codeVal.charAt(0)));
var c2 = Number.isNaN(Number(codeVal.charAt(1)));
var c3 = Number.isNaN(Number(codeVal.charAt(2)));
var c4 = Number.isNaN(Number(codeVal.charAt(3)));
var c5 = Number.isNaN(Number(codeVal.charAt(4)));
console.log(c1);
console.log(c2);
console.log(c3);
console.log(c4);
console.log(c5);
var pass = true;
if(c1)
{
pass = false;
}
if(c2)
{
pass = false;
}
if(c3)
{
pass = false;
}
if(c4)
{
pass = false;
}
if(c5)
{
pass = false;
}
if(pass)
{
alert("Expression Stage 2 Passed!");
return true;
}
else
{
alert("Expression Stage 2 Failed!");
return false;
}
}
else
{
alert("Expression Stage 1 Failed!");
return false;
}
}
<html>
<head>
</head>
<body>
<form name="newform" onsubmit="return validateForm(this, event)" method="POST">
Code <br/><br/>
<input id="code" type="text" value="" name="code" />
<input type="submit" id="submit" name="submit" value="Create" />
</form>
</body>
</html>

How to Trigger Validation

How do I force a user to enter a valid time and valid number before pressing the button "Show"?
I have two fields in my html code and I found two good validation scripts in JS. One for time and one to determine if input field has a numeric value.
I can't change anything in the HTML.
function checkTime() {
re = /^\d{1,2}:\d{2}([ap]m)?$/;
if (time_untilopt.value != '' && !time_untilopt.value.match(re)) {
alert("Wrong time!");
return false;
}
}
function checkRoomNr() {
var numbers = /^[0-9]+$/;
if (roomopt.value.match(numbers)) {
console.log("is number");
} else {
console.log("not a number!");
}
}
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room">
</div>
<button id="show-schedule">Show</button>
If you want the validation to take place as data is being entered into the fields, you should set your functions up to run on the input event of the fields. If you want to wait until the user leaves the field and has made changes to the value of the field, then you can use the change event of the fields.
But, you'll also want the data to be checked when the form that contains the fields is submitted, so you need to set up a submit event handler for the form as well.
The way to connect a function to an event is to register the function as an "event handler" and that is done (using modern standards-based code) with the .addEventListener() method:
// First, get references to the elements you'll want to work with.
// And, use those variable names to reference the elements in your
// code, not their IDs.
var timeUntil = document.getElementById("time-until");
var room = document.getElementById("room");
var form = document.querySelector("form");
// We'll set up a variable to keep track of whether there are any errors
// and we'll assume that there are not any initially
var valid = true;
// Set up the event handling functions:
timeUntil.addEventListener("change", checkTime);
room.addEventListener("change", checkRoomNr);
form.addEventListener("submit", validate);
function checkTime(evt){
re = /^\d{1,2}:\d{2}([ap]m)?$/;
if(timeUntil.value != '' && !timeUntil.value.match(re)) {
console.log("Wrong time!");
valid = false; // Indicate an error
} else {
valid = true;
}
}
function checkRoomNr(evt){
var numbers = /^[0-9]+$/;
if(!room.value.match(numbers)){
console.log ("not a number!");
valid = false; // Indicate an error
} else {
valid = true;
}
}
// This function is called when the form is submitted
function validate(evt){
// Invoke the validation functions in case the fields have not been checked yet
checkTime();
checkRoomNr();
if(!valid){
evt.preventDefault(); // Cancel the form's submission
console.log("Submission cancelled due to invalid data");
}
}
<form action="#">
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room">
<div>
<button id="show-schedule">Show</button>
<form>
function checkTime( val ) { //Pass a value
return /^\d{1,2}:\d{2}([ap]m)?$/.test( val ); //Return a boolean
}
function checkNum( val ) { //Pass a value
return /^\d+$/.test( val ); //Return a boolean
}
const time = document.getElementById("time-until"),
room = document.getElementById("room"),
show = document.getElementById("show-schedule");
function validateForm () {
show.disabled = (checkTime( time.value ) && checkNum( room.value )) === false;
}
[time, room].forEach( el => el.addEventListener("input", validateForm) );
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room">
</div>
<!-- MAKE BUTTON DISABLED -->
<button id="show-schedule" disabled>Show</button>
Now you can reuse your functions like checkTime( val ) regardless of the input ID.
This may be a starting point basically you need to add event handlers and wire up time_untiloptand time_untilopt and add disabled to the show button. and listen for changes. There many ways, this is just an idea.
const button = document.getElementById('show-schedule');
const time_untilopt = document.getElementById('time-until');
const roomopt = document.getElementById('room');
function checkTime() {
re = /^\d{1,2}:\d{2}([ap]m)?$/;
if (time_untilopt.value != '' && !time_untilopt.value.match(re)) {
alert("Wrong time!");
return false;
}
return true;
}
function checkRoomNr() {
var numbers = /^[0-9]+$/;
if (roomopt.value.match(numbers)) {
console.log("is number");
return true;
} else {
console.log("not a number!");
return false;
}
}
function change() {
button.disabled = !(checkTime() && checkRoomNr());
}
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until" onchange="change()">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room" onchange="change()">
</div>
<button id="show-schedule" disabled="true">Show</button>
Inside both of your functions you'll want to set up your variables (time_untilopt and roomopt) to actually point to your two <input> fields. Then you'll simply want to return true if they pass validation, and return false if they don't.
To trigger these checks, you'll want to set up an onlick attribute for your submission, which is tied in to a third function, which I have named show(). This third function should conditionally check that both of the other functions return true. If they do, all is good, and you can continue with the submission. If they're not good, simply return false in this function as well.
This can be seen in the following:
function checkTime() {
re = /^\d{1,2}:\d{2}([ap]m)?$/;
var time_untilopt = document.getElementById('time-until');
if (time_untilopt.value != '' && !time_untilopt.value.match(re)) {
return true;
}
else {
console.log("Wrong time!");
return false;
}
}
function checkRoomNr() {
var numbers = /^[0-9]+$/;
var roomopt = document.getElementById('room');
if (roomopt.value.match(numbers)) {
return true;
} else {
console.log("The room number is not a number!");
return false;
}
}
function show() {
if (checkTime() && checkRoomNr()) {
console.log('Both validations passed!');
return true;
}
else {
return false;
}
}
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room">
</div>
<button id="show-schedule" onclick="show()">Show</button>
Also note that your checkTime() function is actually doing the exact opposite of what you want; if the time is not empty and matches the validation, you want to return true, not false. This has been corrected in the above example.
Hope this helps! :)

Two JavaScript functions onsubmit and onclick

I have two JavaScript functions to check two fields (input title and textarea)
form name="myform" onsubmit="return Checkthis()"
button type="submit" onclick="Checkthis();return false;"
Inside Checkthis() I call Check1() and Check2() and in onsumbit=/onclick=. I call only on Checkthis()
However, only the first function is checked onsubmit and onclick; I have tried to remove Checkthis() and call two functions like onClick="Check1();Check2();" but this doesn't work either.
function Check1() {
var msg_area = document.getElementById("mydiv1");
if () {
return false;
}
}
function Check2() {
var msg_areaa = document.getElementById("mydiv2");
if () {
return false;
}
}
function Checkthis() {
Check1();
Check2();
}
I have tried with: onsubmit ="Checkthis()" and onsubmit="return (Check1() && Check2());"
Any method I use only the first function is checked!
Okay this might not be a popular answer, so downvote away, but it will probably work.
Use jQuery:
$(document).ready(function(){
$("#wtvrDiv").click(function(){
Check1();
Check2();
});
});
To better explain my comments, give this a shot.
HTML:
<form name="myform">
<input type="text" id="titleID" />
<input type="text" id="textareaID" />
<button type="button" onclick="checkthis()">Submit</button>
</form>
Javascript:
var check1 = function () {...} // Don't submit, just see if it's valid
var check2 = function () {...} // Don't submit, just see if it's valid
var checkthis = function() {
if (check1 && check2) {
document.getElementById("myform").submit();
}
}
This page is also very helpful for getting started with form validation.

function will not return a value

I'm trying to write a file upload function that will return either a true or false after it uploads the file. The only return I can currently get is undefined. I have tried a few variations of the code, but I can't figure it out. I believe it's a latency or scope issue, but not really sure. Take a look and tell me what you guys think.
HTML
<div id="add-form">
make : <input type="text" id="make" name="make" />
type : <input type="text" id="type" name="type" />
caliber : <input type="text" id="caliber" name="caliber" />
cost : <input type="text" id="cost" name="cost" />
description : <textarea id="description"></textarea>
<form id="image-form">
image : <input type="file" id="image" name="image" />
</form>
<button id="add-item">ADD ITEM</button>
</div>
JQUERY
$(function()
{
$('#add-item').click(function()
{
console.log(uploader());
});
var uploader = function uploader()
{
var iframe = $('<iframe name="postiframe" id="postiframe" style="display:none" />');
$("body").append(iframe);
var form = $('#image-form');
form.attr("action","hub.php?handler=image");
form.attr("method","post");
form.attr("enctype","multipart/form-data");
form.attr("encoding","multipart/form-data");
form.attr("target","postiframe");
form.attr("file",$('#image').val());
form.submit();
$("#postiframe").load(function()
{
var _frame = $("#postiframe").contents().find('body').html();
var obj = $.parseJSON(_frame);
if(obj['status']==true)
{
return true;
}
else
{
return false;
}
});
}
});
The problem is that you're returning a value from your ajax callback
$("#postiframe").load(function() {
// ...
return true;
By the time this line of code has been reached, the original function has already terminated, returning nothing, which of course evaluates as undefined
var uploader = function uploader()
{
var iframe = $('<iframe name="postiframe" id="postiframe" style="display:none" />');
$("#postiframe").load(function()
{
var _frame = $("#postiframe").contents().find('body').html();
var obj = $.parseJSON(_frame);
if(obj['status']==true)
{
//function has already ended by this point!
return true;
}
else
{
//function has already ended by this point!
return false;
}
});
//you need to return something HERE
}
I'd say your best bet would be to pass in two callback functions, one to be run if the uploads succeeds, and the other if it fails. This won't get you to the point where the function will return true or false based on the result of the upload, but it will allow you to specify code to be run based on whether or not the upload is successful
var uploader = function uploader(successCallback, failureCallback)
{
var iframe = $('<iframe name="postiframe" id="postiframe" style="display:none" />');
$("#postiframe").load(function()
{
var _frame = $("#postiframe").contents().find('body').html();
var obj = $.parseJSON(_frame);
if(obj['status']==true)
{
if (typeof successCallback === 'function')
successCallback();
}
else
{
if (typeof failureCallback === 'function')
failureCallback();
}
});
}
The solution is you should implement a callback pattern to deal with the async nature. Here is is oversimplified.
var uploader = function(callback) {
$("postiframe").load(function () {
// success
callback(true);
});
};
Usage
uploader(function (success) {
});

Categories

Resources