javascript addEventListener firing on all elements - javascript

Im sure I have missed something obvious but any idea why the following addEventListener code is firing everywhere (on not just on the submit button)?
HTML:
<form action="#">
<input type="text"><br>
<input type="text"><br>
<button id="submit">submit</button><br>
</form>
JS:
function validate () {
var inputs = document.getElementsByTagName('input');
var inputs_length = inputs.length-1;
for (i=0; i<=inputs_length; i++) {
var inputs_value = document.getElementsByTagName('input')[i].value;
if (inputs_value == "") {
alert('there is a text box empty');
}
}
}
var el = document.getElementById('submit');
if (el.addEventListener) {
el = addEventListener('click', validate, false);
} else if (el.attachEvent) {
el.attachEvent('onclick', validate);
}
THE FIX IS CHANGE
el = addEventListener('click', validate, false);
TO
el.addEventListener('click', validate, false);
MY TYPO :(

Change this:
if (el.addEventListener) {
el = addEventListener('click', validate, false);
To this:
if (el.addEventListener) {
el.addEventListener('click', validate, false);

A lengthy comment.
In your code:
// inputs is an HTMLCollection of all the inputs
var inputs = document.getElementsByTagName('input');
// No need for the -1
var inputs_length = inputs.length;
// Don't forget to declare counters too, very important
// Just use < length
for (var i=0; i<inputs_length; i++) {
// Instead of this very inefficient method
var inputs_value = document.getElementsByTagName('input')[i].value;
// use the collection you already have
var inputs_value = inputs[i].value;
if (inputs_value == "") {
alert('there is a text box empty');
}
}
Also better to declare inputs_value at the beginning so all declarations are in one place, but as you have it is not harmful.
Oh, and don't give a form element a name or id of "submit" (or any other form method) as it will shadow the form method of the same name so it can't be called.

Related

alert box shows up N times after clicking N times on submit button

Given this function:
function validate() {
var elements = ["firstname", "lastname", "password", "favfood", "favsport"];
document.getElementById('register').noValidate = true;
document.getElementById('register').addEventListener('submit', function(event) {
for (var i = 0; i < elements.length; i++) {
if(document.getElementById(elements[i]).hasAttribute("required")) {
if(!document.getElementById(elements[i]).checkValidity()) {
event.preventDefault();
alert('Please, fill in every required field of the form.');
break;
}
}
}
}, false);
}
And this form:
<form name="register" id="register" method="POST" action="this-file.php">
[HTML ELEMENTS TO VALIDATE]
<input type="submit" value="Register" onclick="validate()">
</form>
When I press Register the first time (without filling in anything), the alert box shows up just once; if I press Register again, the alert box shows up twice and so on. What's going on?
I'm using a custom JavaScript function to validate my form because the required attribute does not work on Safari.
Thank you all in advance.
Its quite straightforward, you are adding submit event listener each time whenever your hit submit button i.e. through validate function. There are two ways to handle this either register it only once or remove the added listener first and than add it.
First Way
function validate() {
var elements = ["firstname", "lastname", "password", "favfood", "favsport"];
document.getElementById('register').noValidate = true;
document.getElementById('register').addEventListener('submit', function(event) {
for (var i = 0; i < elements.length; i++) {
if(document.getElementById(elements[i]).hasAttribute("required")) {
if(!document.getElementById(elements[i]).checkValidity()) {
event.preventDefault();
alert('Please, fill in every required field of the form.');
break;
}
}
}
}, false);
}
validate(); // call this function directly and remove it from your submit button
Second Way
function validateCallback(event) {
var elements = ["firstname", "lastname", "password", "favfood", "favsport"];
for (var i = 0; i < elements.length; i++) {
if(document.getElementById(elements[i]).hasAttribute("required")) {
if(!document.getElementById(elements[i]).checkValidity()) {
event.preventDefault();
alert('Please, fill in every required field of the form.');
break;
}
}
}
}
function validate() {
document.getElementById('register').noValidate = true;
document.getElementById('register').removeEventListener('submit', validateCallback, false);
document.getElementById('register').addEventListener('submit', validateCallback, false);
}
and use it same as you are using currently.
You are getting more and more alerts because inside your validate method, you're adding a new event listener to the submit button each time.

can not find the solution to my "addEventListener" function

I am stuck on problem where I try to utilies the addEventListener.
I did try to find solutions on the web but I think my knowledge is to limited to pick the suitable answer.
What I tried is to invoke a function "addFile()" when a key is pressed in this example enter(13) unfortunatly nothing happens. I could add the onkeypress attribute to the input "add-file" with a slightly edited addFileOnKeyEvent(event) but I'm trying to understand what is wrong with my eventListener.
I hope you could follow my explanation, as this is my first question. :)
function addFile() {
var x = document.getElementById("add-file").value;
x = x + ".xml";
var lbl = document.createElement("label");
var node = document.createTextNode(x);
lbl.appendChild(node);
var element = document.getElementById("appendable");
element.appendChild(lbl);
}
function addFileOnKeyEvent(event) {
var evt = event.keyCode;
var textField = document.getElementById("add-file").addEventListener("keypress", function() {
if (evt == 13) {
addFile();
}
});
}
<label>Dateien</label>
<input id="add-file" type="text" onclick="this.select();">
<button type="submit" onclick="addFile()">Hinzufügen</button>
<div class="data-display">
<span id="appendable"></span>
</div>
At first, addFileOnKeyEvent() is never called before anywhere. So you must call it when you try to add file. Or you must bind the event to the text field by default.
Also need not pass event object to addFileOnKeyEvent(). The event must be captured in the addEventListener callback function.
function addFile() {
var x = document.getElementById("add-file").value;
x = x + ".xml";
var lbl = document.createElement("label");
var node = document.createTextNode(x);
lbl.appendChild(node);
var element = document.getElementById("appendable");
element.appendChild(lbl);
}
function addFileOnKeyEvent() {
document.getElementById("add-file").addEventListener("keypress", function(event) {
var evt = event.keyCode;
if (evt == 13) {
addFile();
}
});
}
// call the function here
addFileOnKeyEvent();
// else just put the event handler part alone. The function is unnecessary here.
<label>Dateien</label>
<input id="add-file" type="text" onclick="this.select();">
<button type="submit" onclick="addFile()">Hinzufügen</button>
<div class="data-display">
<span id="appendable"></span>
</div>
That's not how events work. Try this...
document.getElementById("add-file").addEventListener(
"keypress",
function(event) {
if (event.keyCode == 13) {
addFile();
}
});
Instead of...
function addFileOnKeyEvent(event) {
var evt = event.keyCode;
var textField = document.getElementById("add-file").addEventListener("keypress", function() {
if (evt == 13) {
addFile();
}
});
}

Radio button returning undefined value in javascript

http://jsfiddle.net/jngpjbjm/
Have a look at the fiddle link attached. Radio button value is returning a undefined value. I don't why. Please help with this.
<input type="radio" name="arv" value="1">1
<br>
<input type="radio" name="arv" value="2">2
var radio = document.getElementsByName('arv');
radio[0].addEventListener('click', check());
radio[1].addEventListener('click', check());
function check() {
for (var i = 0; i < radio.length; i++) {
var rcheck = radio[i].checked;
if (!rcheck) {
alert(rcheck.value);
}
}
}
Try this: http://jsfiddle.net/jngpjbjm/3/
It should be:
alert(radio[i].value);
Maybe you need something like this?
function check() {
alert( event.target.value );
}
http://jsfiddle.net/jngpjbjm/9/
I have tried to remove all excessive code from your original script as being unnecessary (kind of), whats left are the bare essentials. thanks #mplungjan
Try this:
var radio = document.getElementsByName('arv');
// here is how to add event listeners like the pros over at MDN
radio[0].addEventListener('click', check, false);
radio[1].addEventListener('click', check, false);
function check(e) {
//simply grab the event by passing it as "e" and capturing its target.value
var rcheck = e.target.value;
alert(rcheck);
}
Use this
var radio = document.getElementsByName('arv');
radio[0].addEventListener('click', check);
radio[1].addEventListener('click', check);
function check() {
for (var i = 0; i < radio.length; i++) {
var rcheck = radio[i].checked;
if (!rcheck) {
alert(radio[i].value);
}
}
}
This version will work in all browsers.
window.onload=function() {
var radios = document.getElementsByName('arv');
for (var i=0;i<radios.length;i++) {
radios[i].onclick=function() {
alert(this.value);
}
}
}
onclick
Because it was essentially part of DOM 0, this method is very widely supported and requires no special cross–browser code; hence it is normally used to register event listeners dynamically unless the extra features of addEventListener() are needed.

Javascript: Best event to use to call function for any change in text area?

I want a function to be called whenever there is any change within my text area, i.e. char typed, removed, cut, pasted etc.
Currently I am using:
onkeyup || onmousemove = function();
This seems to only be calling onmousemove, what can I use to call my function on ANY change to the textarea.
I am creating this JS as a string to add it as a parameter to the creation of a text_area using codeigniteras described here at form_input section
e.g:
$js= 'onkeyup || onmousemove = "function()"';
echo text_area('name', " ", $js);
There's no way to combine multiple HTML attribute assignment, you have to do them separately. Try:
text_input('name', ' ', 'onkeyup="function()" onmousemove="function()"');
try this :
$('#element').on('keyup keypress blur change', function() {
...
});
Just give textarea an id say myId and bind events to it to trigger handler.
var element = document.getElementById("myId");
var myEvents = "oninput onchange onkeyup onpaste".split(" ");
var handler = function (e) {
};
for (var i=0, len = myEvents.length; i < len; i++) {
element.addEventListener(myEvents[i], handler, false);
}
Try something like below
Example
<textarea id='textarea1'>data</textarea>
//....................
$("textarea").bind('input propertychange', function(){
alert($(this).val());
});
Note: Use jquery plugin
DEMO
If you want to prevent simultaneous triggers then use the below code
<textarea id="textarea"></textarea>
//.......
var text = "";
$("#textarea").on("change keyup paste", function() {
var Val = $(this).val();
if(Val == text) {
return; //prevent multiple simultaneous triggers
}
text = Val;
alert("changed!");
});
DEMO2

Checking all forms on site

I need to check some forms (~10) on my site.
I wrote function which will change class of inputs, so they would become red.
function validate()
{
var result = true;
var inputList = document.getElementsByTagName("input");
for (var i=0; i<inputList.length; i++)
if (inputList[i].type == 'text')
{
if(inputList[i].value == "")
{
inputList[i].className='error';
inputList[i].onchange = function()
{
this.className='';
resetEvents(this);
}
result = false;
}
else
{
inputList[i].className='';
}
}
return result;
}
There are no problems with it. I checked it with some forms and it works fine. If I want form to be submitted I should add return validate(); to onSubmit action:
<form class='form' id='form' action='' method='post' onSubmit='return validate()'> Now I need to set onSubmit-actions of all forms.
I want to assign forms handler on page loaded:
window.onload = function() {
var formList = document.getElementsByTagName("form");
for (var i=0; i < formList.length; i++)
formList[i].onsubmit = return validate();
}
This code don't work, because of return validate();, but if I remove return and will just assign handler all inputs would be with .error class already on page load.
What I have to make this working correct?
you need to assign the function reference to the onsubmit handler, not the value returned by validate method
formList[i].onsubmit = validate; //this inside validate will refer to the submitted form
Demo: Fiddle
But I will prefer to use jQuery submit handler(this inside the validate method will refer to the clicked form)
jQuery(function(){
$('form').submit(validate)
})
Demo: Fiddle
Note: it has one drawback, that is since you are returning false from validate it will prevent both the default action and the propagation of the submit event.

Categories

Resources