I have a function that currently works with an input to prevent customers from inputting a P.O. Box into an address field. The input that works has an inline onKeyPress event, however the input I need to run the function on doesn't (and I can't access it).
My question is how to incorporate the correct event listener so that my function runs on this inaccessible input?
My JS Fiddle is here: http://jsfiddle.net/ZQQS9/4/
function killPObox(id) {
var idValue = document.getElementById('v65-onepage-shipaddr1').value;
if (id == 'v65-onepage-shipaddr1') {
function runVal() {
if (idValue.substr(0,4).toUpperCase() === "PO B" || idValue.substr(0,5) === "P.O. ") {
alert("USA Light cannot ship to P.O. Boxes. Please enter a street address.");
}
}
setInterval(runVal(),1);
}
}
<!-- Practice input that works -->
1. <input type="text" class="quantity" name="v65-onepage-shipaddr1" id="v65-onepage-shipaddr1" onKeyPress="killPObox(this.name)">
<br>
<br>
<!-- Actual input that I need to hook into, cannot edit -->
2. <input type="text" size="25" maxlength="75" name="ShipAddress1" id="v65-onepage-shipaddr1" value="" style="" onkeydown="">
You can use the addEventListener() method like this:
document.getElementById('v65-onepage-shipaddr2').addEventListener('keypress', killPObox('v65-onepage-shipaddr2'));
I think your first input is incorrectly passing this.name as the argument to the killPObox() function. Should you be passing this.id instead? Also you may want to replace 'v65-onepage-shipaddr1' in your killPObox() function to just id to use the argument passed into the function.
I'm sure you have solved this already, but since this is still unanswered (and I stumbled on it) I'll add the solution for future visitors.
Use the correct event
First off, the onKeyPress will actually fire before the typed character has been registered in the input element. So if a user types abc and you do onKeyPress="alert(this.value)" it would alert ab. A better alternative would be onKeyUp, since this would get the last typed character too.
Use the event correctly
Next, the events - your options are:
//inline, not considered "best practice"
<input type="text" name="myinput" id="myinput" onKeyUp="killPObox(this)"/>
//same event as above, but in pure js
document.getElementById('myinput').onkeyup = function (e) {
killPObox(e.target);
};
//or attach an eventListener
document.getElementById('myinput').addEventListener('keyup', function (e) {
killPObox(e.target)
});
All of these should work for the majority of browsers. I would suggest alternative 3, or if you need IE8 support, alternative 2.
The JavaScript, simplified
Your function, killPObox(), should look something like this (using one of the above events):
function killPObox(el) {
if (el.id == 'v65-onepage-shipaddr1' || el.id == 'v65-onepage-shipaddr2') {
if (el.value.substr(0, 4).toUpperCase() === "PO B" || el.value.substr(0, 5) === "P.O. ") {
alert("USA Light cannot ship to P.O. Boxes. Please enter a street address.");
}
}
}
Last but not least..
Finally, a very important part when using event binding, you need to use window.onload(). This is to make sure that both the script and elements that are to be bound are loaded before any code is run.
window.onload = function () {
// my binds, events and calls here
};
An actual working example of all three events:
function killPObox(el) {
if (el.id == 'v65-onepage-shipaddr0' || el.id == 'v65-onepage-shipaddr1' || el.id == 'v65-onepage-shipaddr2') {
if (el.value.substr(0, 4).toUpperCase() === "PO B" || el.value.substr(0, 5) === "P.O. ") {
alert("USA Light cannot ship to P.O. Boxes. Please enter a street address.");
}
}
}
window.onload = function () {
document.getElementById('v65-onepage-shipaddr1').onkeyup = function (e) {
killPObox(e.target);
};
document.getElementById('v65-onepage-shipaddr2').addEventListener('keyup', function (e) {
killPObox(e.target)
});
};
"PO B" or "P.O. " will trigger the alert in all boxes:<br><br>
0. <input type="text" class="quantity" name="v65-onepage-shipaddr0" id="v65-onepage-shipaddr0" onKeyUp="killPObox(this)" />
<br/><br/>
1. <input type="text" class="quantity" name="v65-onepage-shipaddr1" id="v65-onepage-shipaddr1" />
<br/><br/>
2. <input type="text" class="quantity" name="v65-onepage-shipaddr2" id="v65-onepage-shipaddr2" />
Related
I have this problem to solve
In this form a user types in a value. (Actually,
a scanner scans a number and virtually types it - without
sending extra keys like Enter)
I need to contantly check - while typing is going on - if the value in the input
box is a 8 digit number (starting with "4") and if it
is, fire the submit action.
I tried to log any changes. But the code below only logs changes after I leave the input box.
<form action="#" onsubmit="return validateFormOnSubmit(this);">
<input name="boarding_id" value="" width="600px" onChange="console.log(this.value);">
<button type="submit" name="action" class="btn btn-primary" value="0">Scan</button>
</form>
Is there a Javascript way to pass the value of the box to a function whenever a single letter is typed?
Note: While the form displays a "scan" button, the goal is to have that button automatically clicked as soon as 8 digits have been entered and been declared valid by a validator function.
It is generally not a good idea to use inline event handlers.
Actually, a scanner scans a number and virtually types it
So, as far as I understand you want to show the result of some scanning function that inputs values and check the input value. Looks like there's not really a need for a change handler. Here's a minimal reproducable example for a dummy scanning function. It uses event delegation for handling the button click.
document.addEventListener(`click`, handle);
function scan(i = 0) {
const inp = document.querySelector(`[name='boarding_id']`);
const showIt = document.querySelector(`#showIt`);
if (i < 1) {
inp.value = 4;
i += 1;
} else {
const nr = 1 + Math.floor(Math.random() * 9);
const currentValue = inp.value;
inp.value += nr;
}
if (i < 8) {
showIt.textContent = `Scanning ...`;
return setTimeout( () => scan(i + 1), 100)
}
showIt.textContent = `Done!`;
document.querySelector(`#scan`).removeAttribute(`disabled`);
}
function handle(evt)
{
if (evt.target.id === `scan`) {
evt.target.setAttribute(`disabled`, `disabled`);
return scan();
}
}
<input name="boarding_id" value="" width="600px" readonly>
<span id="showIt"></span>
<p><button id="scan">Scan</button></p>
const input = document.querySelector('input');
const demo_variable = document.getElementById('demo_variable');
input.addEventListener('input', updateValue);
function updateValue(e) {
demo_variable.textContent = e.target.value;
}
<form action="#" onsubmit="return validateFormOnSubmit(this);">
<input name="boarding_id" value="" width="600px" >
<button type="submit" name="action" class="btn btn-primary" value="0">Scan</button>
<p id="demo_variable"></p>
</form>
You can use the input event, which also triggers when editing happens without the keyboard (mouse drag/drop, context menu, other device...).
Use a regular expression to do the verification. You can access the form via the form property of the input element:
<input name="boarding_id" oninput="/^4\d{7}$/.test(this.value) && this.form.submit()">
It is however better practice to bind events not with HTML attributes, but with JS code. For that purpose give the form element an id attribute (like id="frm"), and then:
const form = document.getElementById("frm");
form.boarding_id.addEventListener("input", (e) => /^4\d{7}$/.test(e.target.value) && form.submit());
You can achieve this in multiple ways. I have shown one below
function myFunction() {
const userInput = document.getElementById("numberinput").value;
document.getElementById("displaynumber").innerHTML = "You typed: " + userInput;
}
function submtValue(value) {
const submitValue =document.getElementById("numberinput").value;
if(submitValue.length === 8) {
// do your validation
alert("Bingo..!!")
}
else {
alert("Minimum length required is 8")
}
}
<input type="number" id="numberinput" oninput="myFunction()">
<p id="displaynumber"></p>
<button type="submit" value="Submit" onclick="submtValue()">Submit</button>
You can add key event like onkeydown or onkeypress on input which will trigger everytime type inside input and once condition fulfilled submit form
I have multiple input fields and I want to limit them to accept numbers only in Vue.js.
I want do disable user from typing any characters except digits from 0-9.
I already did that successfully by doing this(this solution copy-paste proof):
Code in Vue.js template:
<input type="text" name="priceMax" class="input" #input="correctNumberInput" />
Method that removes everything except numbers:
correctNumberInput: function(event){
event.target.value = event.target.value.replace(/[^0-9]/g, "");
}
This worked perfectly fine on multiple fields.
Here comes the problem: For different reason, I needed to use v-model on these input fields. After adding v-model my method doesn't work anymore. I guess it's because v-model also uses input event under the hood. So only adding "v-model", stops it from working:
<input type="text" name="priceMax" class="input" #input="correctNumberInput" v-model="priceMax" />
I have few possible solutions in mind, but all of them include a lot of repeated code.
For example, I could add watchers for every input field, but that would be a lot of repeated code (because I would need to do it for every input field). I have 5 input fields, so basically I would need to write 5 almost identical watchers. I would like to avoid that if that is possible... For example:
watch:{
number(){
this.priceMax = this.priceMax.replace(/[^0-9]/g, "");
}
}
Is there any way I can solve it and make it as simple as my solution was without repeating code? It would be nice to also have solution that is copy-paste proof. All suggestions are welcome! Thanks in advance!
I've tried to test some code. Here what I have (link to the example):
<template>
<div>
<div>
<input
type="text"
name="priceMin"
class="input"
v-model="priceMin"
#input="correctNumberInput"
>
<label v-html="priceMin"></label>
</div>
<div>
<input
type="text"
name="priceMax"
class="input"
v-model="priceMax"
#input="correctNumberInput"
>
<label v-html="priceMax"></label>
</div>
</div>
</template>
<script>
export default {
name: "MyInput",
data: () => {
return {
priceMin: "",
priceMax: ""
};
},
methods: {
correctNumberInput: function(event, data) {
const name = event.target.name;
let value = String(this[name]).replace(/[^0-9]/g, "");
if (value) {
this[name] = parseInt(value, 10);
} else {
this[name] = "";
}
}
}
};
</script>
<style scoped>
input {
border: 1px solid black;
}
</style>
This is the code:
correctNumberInput: function(event, data) {
const name = event.target.name;
let value = String(this[name]).replace(/[^0-9]/g, "");
if (value) {
this[name] = parseInt(value, 10);
} else {
this[name] = "";
}
}
So I used your function, but I am not changing the event.target.value, I am changing the data. So I need to know the name of that data, that's why I use name attribute from input fields (const name = event.target.name;)
Update
If we have input type=number, then it has strange (empty) value inside #input callback. So it seems, better use keyboard filter (example here):
The main idea to have keyboard filter:
filterDigitKeys: function(event) {
const code = window.Event ? event.which : event.keyCode;
const isSpecial =
code === 37 ||
code === 39 ||
code === 8 ||
code === 46 ||
code === 35 ||
code === 36;
const isDigit = code >= 48 && code <= 57;
const isKeypad = code >= 96 && code <= 105;
if (!isSpecial && !isDigit && !isKeypad) {
// if not number or special (arrows, delete, home, end)
event.preventDefault();
return false;
}
}
And attach it to inputs:
<input type="number" min="0" name="numberInput" class="input"
v-model.number="numberInput" #keydown="filterDigitKeys">
Note: if we keep only #keydown handler, then we will not filter text insert into our inputs (but ctrl+v is not working anyway, only by mouse).
Maybe you can try this:
<input type="number" name="priceMax" class="input" #input="correctNumberInput" v-model.number="priceMax" />
From that site: click.
I'm working on an assignment and need to validate multiple inputs. I have created multiple functions and am having trouble calling each one. The first one is the only one that will call. The other two will just hang and do nothing.
If I do a single function call for oninput at the form tag it works. Just that it automatically calls the function and all validations. This causes all the prompts to come out at the same time which I don't want. This is why the oninput call is being done at the input tag.
HTML:
<div id="nameValidate"></div>
<label for="name">Name:</label>
<input type="text" id="nameID"
oninput="nameValidation()"/> <br />
<div id="emailValidate"></div>
<label for="email">Email:</label>
<input type="text" id="emailID"
oninput="emailValidation()"/> <br />
<div id="phoneValidate"></div>
<label for="phone">Phone Number:</label>
<input type="number" id="phoneID"
oninput="phoneValidation()"/>
Javascript
function nameValidation() {
var name = document.getElementById("nameID").value;
if (name.length < 3) {
document.getElementById("nameValidate").innerText = "Please
enter your full name.";
}
else if (name.length > 3) {
document.getElementById("nameValidate").innerText = "";
}
}
function emailValidation() {
var email = document.getElementById("emailID").value;
if (!email.match(".com") && email < 5) {
document.getElementById("emailValidate").innerText = "Please
enter your full email address.";
}
else {
document.getElementById("emailValidate").innerText = "";
}
}
function phoneValidation() {
var phone = document.getelementbyid("phoneID").value;
if (phone == "" || phone.length < 10) {
document.getelementbyid("phoneValidate").innertext = "please
enter your full phone number.";
}
else if () {
document.getelementbyid("phoneValidate").innertext = "";
}
}
Let's back up a minute and break some very bad habits that someone who doesn't know any better is teaching you.
Do not set up events using inline HTML event attributes (ie. onclick). This is a 25+ year old technique that persists today because people just copy/paste it and it seems to work in many cases. However, there are a number of very good reasons not to use this ancient technique that just will not die. Separate your JavaScript from your HTML and use modern, standards-based approaches to event handling with .addEventListener().
You've also mis-capitalized .getElementById() when you were getting the phone data and this would cause an error in your code that would prevent it from continuing. Always work with your developer tools (F12) open and the Console tab showing as this is where error messages will appear.
Next, only query the DOM once for elements that you'll need over and over. This means remove all the document.getElementById() lines from inside the functions and move them so they just get executed only once.
And, don't make references to properties of DOM elements, make the references to the element itself. This way, you scan the document just once to get the element reference, but then you can get any property you like when you need it without having to scan the document for the same element again.
Next, don't use .innerText as it is non-standard. Use .textContent instead.
And, don't use self-terminating tag syntax (ie.<br />, <input />). Here's why.
So, here's what your code should look like:
// Get references to the elements you'll be working with just once
var userName = document.getElementById("nameID");
var nameValidate = document.getElementById("nameValidate");
var email = document.getElementById("emailID");
var emailValidate = document.getElementById("emailValidate");
var phone = document.getElementById("phoneID");
var phoneValidate = document.getElementById("phoneValidate");
// Set up your event handlers in JavaScript, not HTML
userName.addEventListener("input", nameValidation);
email.addEventListener("input", emailValidation);
phone.addEventListener("input", phoneValidation);
function nameValidation() {
if (this.value.length < 3) {
nameValidate.textContent = "Please enter your full name.";
} else {
nameValidate.textContent = "";
}
}
function emailValidation() {
// Check the last 4 characters of the input
if ((this.value.substr(this.value.length - 4) !== ".com") && email.value.length < 5) {
emailValidate.textContent = "Please enter your full email address.";
} else {
emailValidate.textContent = "";
}
}
function phoneValidation() {
if (phone.value == "" || phone.value.length < 10) {
phoneValidate.textContent = "please enter your full phone number.";
} else {
phoneValidate.textContent = "";
}
}
<div id="nameValidate"></div>
<label for="name">Name:</label>
<input type="text" id="nameID"> <br>
<div id="emailValidate"></div>
<label for="email">Email:</label>
<input type="text" id="emailID"> <br>
<div id="phoneValidate"></div>
<label for="phone">Phone Number:</label>
<input type="number" id="phoneID">
Finally, as a professional technology trainer for over 25+ years, I would strongly advise you to inform whoever is teaching you these outdated techniques that they are doing you and anyone else they are teaching a disservice. Modern web development is hard-enough without having to unlearn bad habits brought on by those who don't know any better.
Firstly, your elseif has brackets but the condition is empty. Check your console, it should be showing a syntax error because:
} else if () {
document.getelementbyid("phoneValidate").innertext = "";
}
is not valid syntax. Turn it into an else.
Secondly, the function:
document.getelementbyid("phoneValidate").innertext = "";
does not exist on document, however, getElementById does.
Finally, ensure that you use the console to help you debug your code.
When working on a page whenever I call on my second function, validateNumber(), I get a "typeError: String is not a function" message can anyone explain to me why this message is occuring? My code is as follows:
< script type = "text/javascript" >
/* <![CDATA[ */
function validateLetter(dataEntry) {
try {
var textInput = dataEntry.value;
var replacedInput = textInput.replace(/[^A-Za-z]/g);
if (textInput != replacedInput)
throw "You can only enter letters into this field.";
dataEntry.value = replacedInput;
} catch (textInputError) {
window.alert(textInputError)
return false;
}
return true;
}
function validateNumber(dataEntry) {
try {
var textInput = dataEntry.value;
var replacedInput = textInput(/[^0-9]/g);
if (textInput != replacedInput)
throw "You can only enter numbers into this field.";
} catch (numberInputError) {
window.alert(numberInputError)
return false;
}
return true;
}
function validateInput(dataEntry) {
if (navigator.appName == "Microsoft INternet Explorer")
var enteredKey = dataEntry.keyCode;
else if (navigator.appName == "Netscape")
var eneteredKey = dataEntry.charCode;
}
/* ]] */
< /script>
<form action="validateTheCharacters" enctype="application/x-www-form-urlencoded" name="dataEntry">
<p>Enter your mother's maiden name:
<input type="text" id="letter1" name="letter1" onkeypress="validateLetter(this)">
</p>
<p>Enter the city you were born in:
<input type="text" id="letter2" name="letter2" onkeypress="validateLetter(this)">
</p>
<p>Enter the street you grew up on:
<input type="text" id="letter3" name="letter3" onkeypress="validateLetter(this)">
</p>
<p>Enter your phone number:
<input type="text" id="number1" name="number1" onkeypress="validateNumber(this)">
</p>
<p>Enter the year you were born:
<input type="text" id="number2" name="number2" onkeypress="validateNumber(this)">
</p>
<p>Enter the number of siblings you have:
<input type="text" id="number3" name="number3" onkeypress="validateNumber(this)">
</p>
<p>
<button type="reset" value="Reset Form">Reset Form</button>
</p>
</form>
I am almost certain this is the problem:
var textInput = dataEntry.value;
var replacedInput = textInput(/[^0-9]/g);
if textInput is a string you cannot pass parameters to it as if it were a function, instead:
var replacedInput = textInput.replace(/[^0-9]/g, ""); // dependening in what you are trying to achieve of course
var replacedInput = textInput(/[^0-9]/g);
That's not how you do search and replace in Javascript.
It's not quite clear what you intended here, but if you wanted to remove non-digits from the string, you'd do that using String.replace():
var replacedInput = textInput.replace(/[^0-9]/g, "");
That being said, an easier way of accomplishing this check would be to skip the replacement entirely and just use String.match() instead:
var textInput = dataEntry.value;
if (textInput.match(/[^0-9]/))
throw "You can only enter letters into this field.";
dataEntry.value = textInput;
You might consider isolating functionality so that functions like validateLetter simply validate that the string they are passed contains only letters, then have the caller function work out what to do if the return value is true or not.
In that case, you end up with very much simpler functions:
function validateLetters(s) {
return /^[a-z]+$/i.test(s);
}
function validateNumbers(s) {
return /^\d+$/.test(s);
}
To validate an input, you can add a class to say what type of validation it should have, e.g.
<input name="letter3" class="letter" onkeypress="validateLetter(this)">
Then the validateInput function can determine which validation function to call based on the class:
function validateInput(element) {
var value = element.value;
// If has class letter, validate is only letters
if (/(\s|^)letter(\s|$)/i.test(element.className)) {
// validate only if there is a value other than empty string
if (!validateLetters(value) && value != '') {
alert('Please enter only letters');
}
}
// If has class number, validate is only numbers
if (/(\s|^)number(\s|$)/i.test(element.className)) {
// validate only if there is a value other than empty string
if (!validateNumbers(element.value) && value != '') {
alert('Please enter only numbers');
}
}
}
Note that keypress is not a good event to use for validation as data can be entered without pressing any keys (e.g. paste from the context menu or drag and drop). Also, the listener doesn't see the value resulting from the keypress, it sees the previous value.
You really only need to perform validation when the form is submitted. Until then, why do you care what the values are? Allow the user to make mistakes and fix them themselves without being pestered by alerts (onscreen hints are really useful). Spend some time using your forms to enhance their usability (I realise this is probably not a production form, but names can have characters other than the letters a to z, e.g. von Braun and O'Reilly).
Lastly, form controls rarely need an ID, the name is usually sufficient to identify them if required (and they must have a name to be successful, so most have a name already). A bit of play HTML from the OP:
<form>
<p>Enter your mother's maiden name:
<input name="letter1" class="letter" onkeypress="validateInput(this)">
</p>
<p>Enter the number of siblings you have:
<input name="number3" class="number" onkeypress="validateInput(this)">
</p>
<p>
<input type="reset">
</p>
</form>
I have three input fields #product_upc, #product_price and #product_quantity, they are in the same place. I have a checkbox #to_hide and when users check it, the three inputs goes hidden(using hide() method). If the user uncheck the checkbox the three inputs become visible again, this time using show() method (I could use use toggle() instead but prefer to use this approach).
Now, when I submit the form I need to verify if those three input are visible and if they are visible then validate that they are not empty and in case of #product_upc I should check UPC validity by calling checkUPC(param) function.
I made this code but it's not working since elements are visible and code never pass trough validation:
if (($("#product_upc").val() !== '' || $("#product_upc").val().length >= 0) && $("#product_upc").is(":visible")) {
if (checkUPC($("#product_upc").val()) === false) {
alert("El UPC es inválido");
valid = false;
return false;
}
}
if ($("#product_price").is(":visible")) {
if (!$.trim($("#product_price")).length) {
alert("Debes escribir un precio");
valid = false;
$(this).focus();
return false;
}
}
if ($("#product_quantity").is(":visible")) {
if (!$.trim($("#product_quantity")).length) {
alert("Debes escribir una cantidad");
valid = false;
$(this).focus();
return false;
}
}
Which mistake I made?
Fixed II:
So, you want to check if a html element is visible or not, you first need to use hide() or show(), then you can use $('.panel1').is(':visible') to check if an element is visible or not. Take a look here.
Fixed:
Please take a look at this code at fiddle.
I developed a validation function that was called only if a div are visible.
You could use two classes for this field, and associate the event only for visible class.
Out Field<input type="text" /> </br>
<div class="panel1">
Field 1 <input type="text" /> </br>
Field 2 <input type="text" /> </br>
Field 3 <input type="text" /> </br>
</div>
<input type="checkbox" class="visible" checked=true>Visible</input></br>
<input type="button" class="btnValidate" value="Validate"></input>
After user click you could change this class to invisibleCheckBox
Then you associate the event to the class:
$('.visible').click(function(){
if ($(this).prop('checked')){
$('.panel1').show();
}else{
$('.panel1').hide();
}
});
$('.btnValidate').click(function(){
if ($('.panel1').is(':visible'))
alert('works');
if ($(".visible").prop('checked')){
console.log('validate!');
}else{
console.log('dont validate!');
}
});