I'm building a multiple select with ES6. It's all up and functional (moving trough items, clicking them, highlighting, whatever you want) but the only problem is handling those checkboxes. Whenever an item is highlighted and enter is pressed I must catch the event, verify the number of checked items and update dropdown's title.
The methods I found so far are based on using document.createEvent() and fireEvent(), but they both are deprecated (and yes, I can't figgure out how to solve it with CustomEvent).
I've been trying to find an answer for 3 days now, trust me when I say I tried my best.
checkbox.checked = true
checkbox.checked = false
only change checkbox value but won't trigger any event
Since changing a checkbox value doesn't trigger any event, of course it won't trigger neither 'click' nor 'change' event. They must be triggered separately or together on whatever the case, and the listeners must be specific as well, and new Event('change') works just fine. It was a matter of how to trigger and listen the events.
Thanks for the answers :-)
It might sound stupid, but have you tried simply calling click?
checkbox.click()
Not sure if applicable in OP's concrete case (that is not described in the question), but in general it should NOT be necessary to trigger events from inside your own code when it's possible to just call the same function from multiple places, e.g.:
const checkboxes = document.getElementsByTagName('input')
const button = document.getElementById('button')
const postProcess = (msg) => {console.log(`Processing after clicking ${msg}`)}
[...checkboxes].forEach(checkbox => {
checkbox.onclick = (e) => {
postProcess(`checkbox '${e.currentTarget.value}'`)
}
})
button.onclick = () => {
const previous = checkboxes[0].checked
checkboxes[0].checked = !previous
postProcess(`button that turned checkbox 'a' ${previous ? 'off' : 'on'}`)
}
<label><input type="checkbox" value="a">A</label>
<label><input type="checkbox" value="b">B</label>
<button id="button">Toggle A</button>
Related
I understand that if you change some property in DOM it is reflected in UI and event.preventDefault() function prevents the default changes . Now in this script i changed DOM and stopped default action but it is not reflecting in interace ?
let check = document.getElementById('check');
check.onclick = function(event) {
event.target.checked = !event.target.checked;
event.preventDefault();
}
<input id="check" type="checkbox" /> Checkbox
In this specific example, of course, you could just not have the handler. But you've indicated in the comments that the situation is more complex than shown in the question.
You have to let the event finish being processed before you can change the checked state of the box and have that change stick, for instance with the old setTimeout(..., 0) trick:
let check = document.getElementById('check');
check.addEventListener("click", function({target}) {
setTimeout(() => {
target.checked = !target.checked;
}, 0);
event.preventDefault();
});
<input id="check" type="checkbox" /> Checkbox
(Just a microtask like Promise.resolve().then(...) doesn't work, at least on Chrome, apparently you have to go back to the main event loop.)
That example also uses addEventListener rather than onclick and ES2015+ destructuring (the {target} in the function parameter list), since you're using let and so appear to be using ES2015+.
But it works using onclick, too:
let check = document.getElementById('check');
check.onclick = function({target}) {
setTimeout(() => {
target.checked = !target.checked;
}, 0);
event.preventDefault();
};
<input id="check" type="checkbox" /> Checkbox
Thanks for all the help guys ,
After digging i came to this conclusion that:
1) Initially the browser toggles the checked value and calls the event listener
2) Now it again encounters a toggle statement and it toggles the value again , now the value is back to original
3) Now preventDefault() is called which is executed after the bubble of eventlisteners (i think) and it sees that the new value of checked is same as the initial value(which i think it keeps track of ) and does nothing (if it was changed it would toggle again).
If you replace the line - event.target.checked = !event.target.checked;
you can see preventDefault() toggling but in this case it does not toggle .
I have a web page, primarily used by mobile users (about 80% of my users), with about 350 <input type="checkbox"> elements. When a checkbox is checked or unchecked, I want to call some javascript to save the state in local storage. When I created my page there were only about 100 elements so instead of making each element <input type="checkbox" onclick="save();"> which seemed prone to typos or just plain forgetting to add the onclick, I added this to my onload function:
var input_elements = document.querySelectorAll("input[type='checkbox']");
for (var i = 0; i < input_elements.length; i++) {
input_elements[i].addEventListener("click", function() { save(this); });
}
which works great but adds a small penalty to page load times -- which is getting worse as I add elements, and I'm expecting to keep adding another 100-150 each year.
Is there a "better" way of doing this, both in terms of reducing load times (especially for mobile users with slower browsers) and preventing me from making dumb typos that break something for my users but are hard for me to spot?
You can add event handler on some common parent, for example some wrapper div or document if there's no wrapper parent. Search for event delegation mechanism to get more information about this pattern.
You could add a capturing click handler and test if the click was on a check box:
function checkCheck(event) {
if( event.target && event.target.type == "checkbox"){
checkSave( event.target)
}
}
function checkSave( checkBox) {
// do something for click on checkbox element
console.log("checkbox %s, checked: %s", checkBox.id, checkBox.checked);
}
window.addEventListener("click", checkCheck, true);
HTML
<input type="checkbox" id="test">
I have a webpage with a small survey. I want to pre populate some of the answers based on user inputs to previous question.
In the below code, if value of id QR~QID3 depends upon value of QID1_Total. However after the page loaded and even if the condition is met the textbox is not populated with correct value.
.addOnload(function()
{
if(document.getElementById("QID1_Total").value>15) {
document.getElementById("QR~QID3").value = "Good";
}
else{
document.getElementById("QR~QID3").value = "Average";
}
});
$("#QID1_Total").on("input", function() {
//statements goes here
});
use of on("input" will track every inputting event, include drop and paste.
know more about onInput : https://mathiasbynens.be/notes/oninput
Here is an Fiddle Example to know how trigger works :
https://jsfiddle.net/5sotpa63/
An Assumption
Let Us Say you are using a function, which holds this statement show Good and Average according to users Input.
var targetElem = document.getElementById("QID1_Total");
var showComment = (targetElem,value>15) ? "Good" : "Average";
document.getElementById("QR~QID3").value = showComment;
Above code is the shorter method of your own statement mentioned in your question.
Now on Change of the target QR~QID3 you need to load some content. you utilize the below code as follows.
$("#QR~QID3").on("input", function() {
//your next question loading statements goes here,
//statements to proceed when you show some comment Good or Average
}).trigger("input");
Hope! this could be helpful.
$('#QID1_Total').keydown(function () {
//ur code
});
as the mouse key is pressed in the input field the function is called
You need to add an event listener to the "QID1_Total" element.
If you want to run the check while the user changes the input, i.e. after each keypress use the oninput event.
If you want to run the check after the user has completed the input, use the onchange event. The onchange event will only fire after the input loses focus.
You can bind the event listeners by using the addEventListener() function like this:
document.getElementById("QID1_Total").addEventListener("input", function(){
//Code goes here
});
Here is a JSFiddle showing both methods.
You also have to use the parseInt() function on the textbox values before you can perform mathematical functions with them.
I have a pretty simple form. When the user types in an input field, I want to update what they've typed somewhere else on the page. This all works fine. I've bound the update to the keyup, change and click events.
The only problem is if you select an input from the browser's autocomplete box, it does not update. Is there any event that triggers when you select from autocomplete (it's apparently neither change nor click). Note that if you select from the autocomplete box and the blur the input field, the update will be triggered. I would like for it to be triggered as soon as the autocomplete .
See: http://jsfiddle.net/pYKKp/ (hopefully you have filled out a lot of forms in the past with an input named "email").
HTML:
<input name="email" />
<div id="whatever"><whatever></div>
CSS:
div {
float: right;
}
Script:
$("input").on('keyup change click', function () {
var v = $(this).val();
if (v) {
$("#whatever").text(v);
}
else {
$("#whatever").text('<whatever>');
}
});
I recommending using monitorEvents. It's a function provide by the javascript console in both web inspector and firebug that prints out all events that are generated by an element. Here's an example of how you'd use it:
monitorEvents($("input")[0]);
In your case, both Firefox and Opera generate an input event when the user selects an item from the autocomplete drop down. In IE7-8 a change event is produced after the user changes focus. The latest Chrome does generate a similar event.
A detailed browser compatibility chart can be found here:
https://developer.mozilla.org/en-US/docs/Web/Events/input
Here is an awesome solution.
$('html').bind('input', function() {
alert('test');
});
I tested with Chrome and Firefox and it will also work for other browsers.
I have tried a lot of events with many elements but only this is triggered when you select from autocomplete.
Hope it will save some one's time.
Add "blur". works in all browsers!
$("input").on('blur keyup change click', function () {
As Xavi explained, there's no a solution 100% cross-browser for that, so I created a trick on my own for that (5 steps to go on):
1. I need a couple of new arrays:
window.timeouts = new Array();
window.memo_values = new Array();
2. on focus on the input text I want to trigger (in your case "email", in my example "name") I set an Interval, for example using jQuery (not needed thought):
jQuery('#name').focus(function ()
{
var id = jQuery(this).attr('id');
window.timeouts[id] = setInterval('onChangeValue.call(document.getElementById("'+ id +'"), doSomething)', 500);
});
3. on blur I remove the interval: (always using jQuery not needed thought), and I verify if the value changed
jQuery('#name').blur(function ()
{
var id = jQuery(this).attr('id');
onChangeValue.call(document.getElementById(id), doSomething);
clearInterval(window.timeouts[id]);
delete window.timeouts[id];
});
4. Now, the main function which check changes is the following
function onChangeValue(callback)
{
if (window.memo_values[this.id] != this.value)
{
window.memo_values[this.id] = this.value;
if (callback instanceof Function)
{
callback.call(this);
}
else
{
eval( callback );
}
}
}
Important note: you can use "this" inside the above function, referring to your triggered input HTML element. An id must be specified in order to that function to work, and you can pass a function, or a function name or a string of command as a callback.
5. Finally you can do something when the input value is changed, even when a value is selected from a autocomplete dropdown list
function doSomething()
{
alert('got you! '+this.value);
}
Important note: again you use "this" inside the above function referring to the your triggered input HTML element.
WORKING FIDDLE!!!
I know it sounds complicated, but it isn't.
I prepared a working fiddle for you, the input to change is named "name" so if you ever entered your name in an online form you might have an autocomplete dropdown list of your browser to test.
Detecting autocomplete on form input with jQuery OR JAVASCRIPT
Using: Event input. To select (input or textarea) value suggestions
FOR EXAMPLE FOR JQUERY:
$(input).on('input', function() {
alert("Number selected ");
});
FOR EXAMPLE FOR JAVASCRIPT:
<input type="text" onInput="affiche(document.getElementById('something').text)" name="Somthing" />
This start ajax query ...
The only sure way is to use an interval.
Luca's answer is too complicated for me, so I created my own short version which hopefully will help someone (maybe even me from the future):
$input.on( 'focus', function(){
var intervalDuration = 1000, // ms
interval = setInterval( function(){
// do your tests here
// ..................
// when element loses focus, we stop checking:
if( ! $input.is( ':focus' ) ) clearInterval( interval );
}, intervalDuration );
} );
Tested on Chrome, Mozilla and even IE.
I've realised via monitorEvents that at least in Chrome the keyup event is fired before the autocomplete input event. On a normal keyboard input the sequence is keydown input keyup, so after the input.
What i did is then:
let myFun = ()=>{ ..do Something };
input.addEventListener('change', myFun );
//fallback in case change is not fired on autocomplete
let _k = null;
input.addEventListener( 'keydown', (e)=>_k=e.type );
input.addEventListener( 'keyup', (e)=>_k=e.type );
input.addEventListener( 'input', (e)=>{ if(_k === 'keyup') myFun();})
Needs to be checked with other browser, but that might be a way without intervals.
I don't think you need an event for this: this happens only once, and there is no good browser-wide support for this, as shown by #xavi 's answer.
Just add a function after loading the body that checks the fields once for any changes in the default value, or if it's just a matter of copying a certain value to another place, just copy it to make sure it is initialized properly.
I'm confused on how JavaScript handles Change Events and am looking for some insight.
Let's say we have two HTML controls; a Checkbox and a Button and I want to use JS to display a message that says how many times the Checkbox has changed from checked to not-checked.
<input type="checkbox" id="cb" />
<button id="btn">Change Checkbox</button>
<div id="msg"></div>
The JS can look something like this:
var count = 0;
var cb = document.getElementById("cb");
var btn = document.getElementById("btn");
var msg = document.getElementById("msg");
cb.addEventListener("change", cb_onChange);
btn.addEventListener("click", btn_onClick);
// Change the state of the Checkbox when user clicks the Button
function btn_onClick() {
cb.checked = !cb.checked;
}
// The state of the Checkbox has changed, so increment the change count and display it
function cb_onChange() {
msg.innerHTML = "Checkbox changed " + count+++" times";
}
Test it out here http://jsfiddle.net/26RWh/
Notice that the OnChange event of the Checkbox is NOT dispatched when the Checkbox is programmatically set at cb.checked = !cb.checked. - i.e. The cb_onChange listener is only executed if/when the user manually clicks the Checkbox.
How come the OnChange event isn't fired when I change the state in code?
This is the way events on input-elements work in javascript.
If you want the callback to be executet you need to manually fire the change-event on the checkbox.
There are questions about this:
do it in pure JavaScript
and with help of jquery
when the browser identifies a change event in checkbox, it sets the checked propery to !checked and calls the subscribed functions which you can assume happens in one function(f1) and which is called when the event occurs. In this case you are not calling the function f1 but just setting the property.