Dynamic Click via JavaScript (or jQuery) on a Checkbox - javascript

I know I can change the attribute checked to checked, but i need to actually "click" the checkbox to fire off a live() (jQuery) click event. I know I can also make it a function, but this would just be a lot cleaner and less code, if possible.
Oh, and FYI:
$('.modal-form [name='+json[0].owners[x].name+']').click();
Doesn't work. It checks em, but doesnt actually "click" them to where jQuery fires the live() event
Here's the AJAX call if anyone is interested:
$('.agenda-modal input[type=checkbox]:not([name="emergency-item"])').live('click',function(){
iid = $('.agenda-modal').attr('data-defaultitemid');
the_type = $(this).parent().parent().attr('id');
checked_item = $(this).val();
if($(this).attr('checked')){
if(the_type == 'the-elected-list'){
$livepreview.agenda({
action:'update',
type:'owner',
id:iid,
owner:checked_item
});
}
else if(the_type == 'the-bureau-list'){
$livepreview.agenda({
action:'update',
type:'bureau',
id:iid,
bureau:checked_item
});
}
}
else{
$livepreview.agenda({
action:'get',
type:'item',
id:iid,
callback:function(json){
if(the_type == 'the-elected-list'){
for(x in json[0].owners){
if(json[0].owners[x].name == checked_item){
$livepreview.agenda({
action:'delete',
type:'owner',
id:json[0].owners[x].item_owner_id
});
}
}
}
else if(the_type == 'the-bureau-list'){
for(x in json[0].bureaus){
if(json[0].bureaus[x].name == checked_item){
$livepreview.agenda({
action:'delete',
type:'bureau',
id:json[0].bureaus[x].item_bureau_id
});
}
}
}
}
});
}
});

This will 'click' the checkbox. I'm not positive if it will fire an event bound with live().
$('#myCheck').click();

please include an example. you are most likely not finding the right element by making a complex expression. tone it down.
var el = $('.modal-form [name='+json[0].owners[x].name+']')
alert( el.length )
Then you can .trigger('click') it. Make sure the event handler is bound/set.

Obviously I don't know your code base, but I really wonder whether calling a function by faking UI interaction would be "a lot cleaner". It might be less code, but it sounds very fragile to me. What happens when the UI is redesigned? Or another developer modifies the live() event handler without realizing that your code is implicitly using it as well? Moving the code into a separate function makes it both more legible and more robust (and probably not significantly longer).

Related

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();
};

JavaScript alert callback not working inside a function

I am trying to make a image preview containing of about 5-6 images which will appear one after another when user hovers over it (not like a carousel with prev and next buttons). Here is the fiddle consisting of what I gathered so far.. i don't know if this approach is right or not.. but I am stuck as the alert callback is not working. Could someone please tell me what is wrong?
$(function()
{
var imageCount = $('#product_grid_list').find('figure')[0].getElementsByTagName('img');
for (var i = 0, n = imageCount.length; i < n; i++) {
imageCount[i].on('click', function(e)
{
alert('Everything is going fine!');
}
);
}
}
);
The root cause of click event callback can't be triggered is that you're trying to register a event handler on a "DOM" (in this case: imageCount[i]) element in jQuery way. Try to register the event handler like this if you want to use pure javascript solution:
imageCount[i].addEventListener('click', function(e){
alert('Everything is going fine!');
});
Here is a jsfiddle demo.
Note: I didn't consider the cross browser issue in this case.
BTW, try to cache the length of imageCount node list, it will improve the performance.
You are using js AND jQuery at same time. It's wrong. If you use jQuery, than click event will be like this:
$(document).('click', '#product_grid_list figure img', function(){
alert('Everything is going fine!');
});
You are using a mix of jQuery and standalone javascript. You might as well go all the way to jQuery, with something like:
$('#product_grid_list figure:first img').click(function(e) {
alert('Everything is going fine, hopefully!');
});
You did not send the corresponding HTML, so we cannot test whether the above is correct.
it's just a simple click event in jQuery, no need to use js: http://jsfiddle.net/wP3QQ/11/
$('#product_grid_list').find('figure img').click(function(e){
alert('Everything is going fine!');
e.preventDefault();
});
You want the hover effect, so click event should not be used over here. It should be mouseover.
Working Fiddle
Code Snippet:
$(document).on('mouseover','#product_grid_list figure img',function(e){
alert("now it is working");
});
You are attempting to call on(), a jQuery method, on an HTMLElement (a DOM element). You can't do that, jQuery methods can only be called on jQuery collections. It's easy to get a jQuery collection for the elements you desire:
Use .find() to match the images
There's no need for a for() loop, jQuery's .on() will handle looping for you.
You may also want to prevent the default behaviour of your anchors
$(function () {
var imageCount = $('#product_grid_list').find('figure img');
imageCount.on('click', function (e) {
e.preventDefault()
alert('Everything is going fine!');
})
});
JSFiddle

Event delegation in jQuery, how to do it?

In JavaScript i used to use event delegation like this :
someDiv.addEventListener('click', function(evt){
if(evt.target.id == "#someChild"){
// Do something..
} else if(evt.target.id == "#anotherChild"){
// Do something else..
}
}, false);
What's the equivalent of this in jQuery? i know about .on() but how to use it in event delegation ? i mean is this how is it done :
someDiv.on('click, '#someChild, #anotherChild", function(evt){
if($(this).is("#someChild")){
// Do something..
} else if($(this).is("#anotherChild")){
// Do something else ..
}
});
But wouldn't it be just the same as in vanilla JavaScript ? I want to know if there's a better way to achieve it. And if this is the only way, what's the benefit of jQuery way over JS one ?
You can do:
$(someDiv).on('click', '#someChild, #anotherChild', function(){
if(this.id ==='someChild'){
// Do something..
} else if(this.id === 'anotherChild'){
// Do something else ..
}
});
Or create two event handlers if you do different things for both elements anyway:
$(someDiv).on('click', '#someChild', function(){
// Do something..
}).on('click', '#anotherChild', function() {
// Do something else ..
});
But wouldn't it be just the same as in vanilla JavaScript ? I want to know if there's a better way to achieve it. And if this is the only way, what's the benefit of jQuery way over JS one ?
Of course it's basically the same, jQuery just makes your life a bit easier by providing a wrapper around the DOM API, but it does not change how the DOM works.
There is a difference though, namely that this will refer to the element matched by the selector, not to the element the handler is bound to.
In general, the advantage is that the jQuery code is more cross-browser compatible than using addEventListener.
With jQuery you'd do it like this:
function onButtonClick(e) {
//this = the button that was clicked
}
$(document.body).on('click','button',onButtonClick)
You can read the docs here
You could start here, if this element is created dynamically, and not there on page load
$(document).on('click', '#someChild', function(evt) {
// Do something..
});
If the element is created before the page is rendered then this will work
<input type="button" onclick="fnClickfn();" id="xxx" />
EDIT:
Oh, also .on only works in later versions on jQuery (I think 1.6 and above), so make sure you aren't using an old version that would require .live and .die.

How to simulate onclickout event with JavaScript

I'd like to somehow be able to define with JavaScript an onclickout event. That is something that happens when the user clicks anywhere else that the element in question.
I tried with onblur but it just don't seem to work :/
Is there any other way?
This uses the jQuery help, but the logic is the same if you prefer without it.
$(document).mouseup(function(event) {
var condition = $(event.target).parents(/* element_in_question */).length;
if (condition == 0) { // 0 means the event is not originated from the element in question
// Do what you need to do
}
}
});
document.getElementById('click').onclick = function(event) {
event.stopPropagation();
}
document.onclick = function() {
alert('click somewhere else');
}
jsFiddle.
This will send a click anywhere (except on #click) to the document.onclick handler, which will fire the alert().
You can set a variable, clickedin, on an element's click handler, and then have a click handler for the document that is checking if clickedin is true, and if it is, handle appropriately.
There may be a better way to accomplish the same end, though.

A quick question about keypress and jQuery

$(document).keydown(function(e) {
Well, that's my code - I was wondering if it is possible to have something like:
$(document).not('#pinkElephant').keydown(function(e) {
(Except, that doesn't work...)
Any Ideas?
Thanks very much!
p.s. All that function has inside it, is a switch statement.
[edit] Hey guys n gals - I cannot return false; because the element I need to type in is an <input> text, so the keyboard still needs to return here.
It's really confusing me :(
Here's an alternate way to do what you require by checking to see that the target element's id isn't pinkElephant. Since this doesn't use the universal selector '*' it should perform better:
$(document).keydown(function(e) {
if (e.target.id !== "pinkElephant") {
alert("I'm not pink!");
}
});
Here's a working example.
(updated from comment)
If you really want to bind a keydown event handler to all nodes in your markup, with the exception of #pinkElephant you need to do it like this:
$(document).find('*').not('#pinkElephant').keydown(function() ..
or short
$(':not(#pinkElephant').keydown(function() ...
which implicitly uses the universal selector *.
Note, that this is never ever any good in terms of performance. I don't know your markup but I hope it's not very crouded using that kind of selector.
update
inspired by a comment, you could also do it like:
$(document).click(function(event) {
if( event.target.id === 'pinkElephant' || $.contains($('#pinkElephant')[0], event.target) )
return false;
// ...
});
Last snippet checks whether #pinkElephant itself or a child node was clicked and prevents the propagation + the default action. This is done by invoking $.contains()help
I assume you don't want elements inside pinkElephant to trigger the keydown.
Place a handler on #pinkElephant that stops propagation of the event.
$('#pinkElephant').bind('keydown',false);
Note that passing false to .bind() requires jQuery 1.4.3 or later.
If you're using an older version, do this:
$('#pinkElephant').bind('keydown',function(){return false;});
Try this instead:
$(':not(#pinkElephant)').keydown(function(e) {
// ...
});

Categories

Resources