If any textbox on page is changed, call function - javascript

I know how to check if one textbox is changed, but what about if any textbox is changed?
Any ideas?

the following code will append onchange event listeners to all input tags on the page with type equal to "text".
var textboxes = document.getElementsByTagName("input");
for(var i = 0; i < textboxes.length; i++) {
if(textboxes[i].type == "text") {
textboxes[i].onchange = function() {alert("changed");};
}
}

With jQuery:
$("input[type=text]").change(function() {
// put your code here
});
EDIT:
If you are new to jQuery or don't know about it, it's a JavaScript framework. Click here to learn about it's change() function.

Generally, you have all your textboxes in one div. Use event bubbling:
// Add an event handler on your whole div
document.getElementById('div-with-your-checkboxes').onchange = function(e) {
// Cross browser check
var evt = e || window.event
// Get the element that triggered the event
var target = evt.target || evt.srcElement
// Check if it is an INPUT element
if (target.tagName === 'INPUT') {
// Your code in here.
}
}
This way, you add only one event which will check every onchange events in your div. Just a simple check and you're done.
This is way more efficient than adding an event handler for every input element.
PS: the jQuery way would be like this:
$('#div-with-your-checkboxes').change(function(e) {
if ($(e.target).tagName === 'INPUT') {
// Your code in here.
}
})
As you can see, jQuery is not really needed for this simple task :-).

You could use some jQuery.
Give the textbox's a class, e.g. class="onchange" then add some jQuery
$(function(){
$('.onchange').change(function(){
// your code in here.
});
});
That way, any textbox with the class onchange will raise the jQuery change event.

Loop over document.getElemenetsByTagName("input"). For each element, verify that type == "text" and, if so, attach an event listener.
JQuery does this in a line: $("input[type=text]").on("change", function() { ... })
If you want to do this for text boxes created dynamically after load time, use $("input[type=text]").live("change", function() { ... })

Related

Add event handler and call once immediately

In a web application using jQuery, I have the following code:
$("input[type=checkbox]").on("click", function (event) {
let isChecked = event.currentTarget.checked;
// Do something
});
This will do something whenever the user clicks on a checkbox.
It is necessary to properly initialise the page state by calling this event handler once when loading the page, so it can do whatever would be done on a change of the checkbox already in the beginning.
How can I simply call the added event handler for all matching elements, without actually triggering the event? In the case of "click", this would modify the checkbox state which would break the data.
My current workaround is this:
$("input[type=checkbox]")
.on("click change", function (event) {
let isChecked = event.currentTarget.checked;
// Do something
})
.change();
This adds the event handler for multiple events and only triggers one that has no side effects. But I'd like to limit the event handlers on what's really necessary. If only a "click" event can be used on an element, there are no alternatives. Also, in my case, only elements are hidden or shown, but if something else happens, it might happen twice now.
I'm looking for the onAndNow function in this example pseudocode:
$("input[type=checkbox]").onAndNow("click", function (event) {
let isChecked = event.currentTarget.checked;
// Do something
});
This is another not-so-nice and incomplete solution:
function onCheckboxClicked(event) {
let isChecked = event.currentTarget.checked;
// Do something
}
$("input[type=checkbox]").on("click", onCheckboxClicked);
onCheckboxClicked(???);
You can trigger the function on each of the elements using this code:
function onCheckboxClicked(event) {
if (event == 0) {
console.log("onload")
} else {
console.log("event")
// Do something
}
console.log($(this).prop('checked'))
}
// Event driven
$("input[type=checkbox]").on("click", onCheckboxClicked);
// Executed on load
$("input[type=checkbox]").each(onCheckboxClicked);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" />
Note: As you can see, you won't be able to pass an event with an onload, so you will have to write code for each situation. You can, however, access the element with $(this).

Getting the source of this click event in JQuery

I have multiple dynamically created buttons with the same class on my page and when I try to call a function on the click of the button, the function gets called for all of the buttons with the same class.
I want the function to be called for this click event only.
Here is my function:-
$(".js-btn-plus").click(function (e) {
var link = $(e.target);
var val = link.next('.value').text();
val++
link.next('.value').text(val);
});
Maybe generate unique ID for the button and use that as an event reference instead of the class?
.text() returns a string. Convert the string val to a number
val = Number(val) + 1
or
val = +val++
Please could you provide some sample HTML to alongside the JQuery?
From what I can see you may want to have a look at using $(this) instead of e.target
$(document).on('click', '.js-btn-plus', function() {
var val = parseInt( $(this).find('.value').text() );
val++;
$(this).find('.value').text(val);
});
Not 100% sure what it is that you're trying to achieve, there may be a better way of doing it if you could explain a little bit more and provide some HTML to go alongside your question.
Edit: Using the 'on' function allows you to dynamically bind the function events instead of having them have a listener fire when the script is loaded and executed.
My solution:
$(".js-btn-plus").click(function (e) {
var val = parseInt($(this).next('.value').text());
val++;
$(this).next('.value').text(val);
});

Jquery get value of selector when using the on event listener

I'm using the on event listener to listen for dynamically added select elements. When an event happens is there a way to get the specific select element? this references ul.form.
$('ul.form').on('change', $("select[id$='end']"), function () {
var selector = // unsure what goes here.
self.modify(this);
});
$('ul.form').on('change', $("select[id$='end']"), function (e) {
var selector = e.target;
self.modify(this);
});

Dynamically changing a checkbox doesn't trigger onChange?

Note: jQuery is not an option.
I want to detect a change in the state of a checkbox, but the onChange event doesn't seem to fire when I do this:
document.getElementById('myCheckBox').addEventListener('change',function() {
console.log('Changed!');
});
document.getElementById('someLink').onClick = function() {
// toggle checkbox
document.getElementById('myCheckBox').checked = !document.getElementById('myCheckBox').checked;
};
When I click #someLink the change event is not fired. I could add another listener to #myLink, but then if I add other links that check the same box I have to add more listeners. I want one listener for a checkbox change event. Again, jQuery is not an option, I need vanilla JS.
EDIT: Sorry if I did not make this more clear, but I want to avoid adding complexity to each link that will check this box. So ideally (and maybe the answer is that this is impossible) I don't want to have to alter the link/click logic at all. I want to be able to change the .checked property anywhere in the code and have it be detected without additional logic at each change (if possible).
UPDATE:
Okay so there is apparently no way to do this nicely without altering the onClick logic, so (like some kind of animal) I ended up brute forcing the problem as follows:
function mySentinel() {
if(document.getElementById('myCheckBox').checked) {
console.log("I've been checked!");
return;
}
setTimeout("mySentinel()",100);
}
// then call this somewhere in the on document load section...
mySentinel();
You can add some sort of timeout if you want also:
function mySentinel(var i) {
if(document.getElementById('myCheckBox').checked) {
console.log("I've been checked!");
return;
}
if(i <= 0) {
console.log("Time out. Still not checked");
}
i--;
setTimeout("mySentinel("+i+")",100);
}
// then call this somewhere in the on document load section...
// 60 second timeout (some math can make the argument look nicer)
mySentinel(600);
That is correct, changing the value or checked state of an input programatically does not fire the event handlers.
You'll have to trigger the event as well with javascript
document.getElementById('myCheckBox').addEventListener('change',function() {
console.log('Changed!');
});
document.getElementById('someLink').onclick = function() {
var box = document.getElementById('myCheckBox')
box.checked = !box.checked;
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
box.dispatchEvent(evt);
} else {
box.fireEvent("onchange");
}
};
and note that's it's onclick (all lowercase)
FIDDLE
EDIT
I want to avoid adding complexity to each link that will check this box.
So ideally ... I don't want to have to alter the link/click logic at all.
I want to be able to change the .checked property anywhere in the code and have it be detected without additional logic at each change (if possible).
And that's not really possible, without using horrible hacks with intervals etc.
When the checked state is changed programatically the event handler isn't triggered at all, because that would really be a huge issue in most cases, and much harder to work around the opposite scenario, where you just trigger the event handler manually instead, and that is really the only way to do it.
Of course, you can make it a lot more convenient using classes and external function and such
document.getElementById('myCheckBox').addEventListener('change',function() {
console.log('Changed!');
});
var links = document.querySelectorAll('.someLinkClass');
for (var i = links.length; i--;) {
links[i].addEventListener('click', triggerChange, false);
}
function triggerChange() {
var box = document.getElementById('myCheckBox')
box.checked = !box.checked;
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
box.dispatchEvent(evt);
} else {
box.fireEvent("onchange");
}
};
and anytime you add a link, you just add that class
Change the checkbox
Change the checkbox again
Change the checkbox even more
etc.
If you want to add more links that will trigger the checkbox, create a class name for them and use getElementByClass('classname')
Use onclick in your html, not js. Example: <div onclick="doSomething()"></div>
Just use an if/else statement for the check/uncheck:
if(document.getElementById('myCheck').checked){document.getElementById("myCheck").checked = false;} else{document.getElementById("myCheck").checked = true;}
I think jQuery have a change event. And you don't use it in the good way.
Read this page: http://api.jquery.com/change/
and this: jQuery checkbox change and click event
When any change occurs in the checkbox, jQuery event function is called. And then you can write anything in this event function
You can invoke/trigger an event but its not as easy as it seems, especially when you have to deal with internet explorer.
The cleanest solution is to put your event into its own function, then call it where you need it.
function handleEvent(){
console.log('Changed!');
}
documentent.getElementById('myCheckBox').addEventListener('change',function() {
handleEvent()
});
document.getElementById('someLink').onClick = function() {
// toggle checkbox
document.getElementById('myCheckBox').checked = !document.getElementById('myCheckBox').checked;
handleEvent();
};

How to define events for dynamically created element in pure JS?

How to catch elements onclick event when element may be created in future or added dynamically?
// Here i need to define function for click
// In jQuery it would be like this: jQuery('body').on('click', 'a.some-link-class', function(){});
var some_link = document.createElement('a');
some_link.class = 'some-link-class';
some_link.href = '#';
var some_link_text = document.createTextNode('Some Link Title');
some_link.appendChild(some_link_text);
document.body.appendChild(some_link);
You can attach an event to the body and test if the source of the event is the control type you want, or a class, or something else.
//attach the event to everything in the body
document.body.addEventListener('click', eventFunction, false);
//event function
function eventFunction(e)
{
//test if the source triggering the event is an element from the class you want
//you can do the test on the class, tagname... anything you desire
if(e.ClassName.match('myclass'))
{
//do something if the class matches
dosomething();
}
}
With this, you can create any element you want after that. If they have the good class they will trigger the event if clicked and the function will run.
You must use event delegation for JS. just attach an event to a parent item or document and check in the parent if trigger is your element. You can use a class name or tag name etc.
// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click",function(e) {
// e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
// List item found! Output the ID!
console.log("List item ",e.target.id.replace("post-")," was clicked!");
}
});
in this way the event also works for elements what will be added afterwards.
Just attach it when you create it:
some_link.onclick = function() {
//do stuff
}
Either
some_link.addEventListener('click', handler);
or
some_link.onclick = handler;

Categories

Resources