checkbox running script onclick before actually setting the checked flag - javascript

I have a combobox with checkboxes. I am using jQuery to add a Click event to all of the checkboxes. When the checkbox is checked, a script is supposed to run and check an attribute of the checked box to determine it's type and then perform functions accordingly:
function () {
$('.RcbTag').find('input[type="checkbox"]').click(function () {
var evtCB = $(this);
var id = $(this).closest(".rcbSlide").siblings(".RcbTag").attr("id");
var rcbObject = $find(id);
rcbObject.get_items().forEach(
function (item, index) {
if (item.get_attributes().getAttribute('GUIDType') == 'group' &&
item.get_checked()) {
alert("Checked");
}
});
});
The problem right now is that it appears that the script is running before the checkbox is actually flipped to "checked". So in this example, it looks to see if the item attribute is 'group' and if it's checked. This always returns false, but will return true when I uncheck it. So I'm missing some order of events here. How do I fix this?

I think you're mixing jQuery click handlers and the Telerik code. Let's try and just stick with the Telerik-sanctioned events and I think everything will work like you're expecting.
On your RadComboBox, add an event handler declaritively like this:
OnClientItemChecked = "ComboBoxRowClick"
Then declare the JS function as you have it now (except we want to name it and not keep it anonymous):
function ComboBoxRowClick(sender, args) {
if (args.get_item().get_attributes().getAttribute('GUIDType') == 'group' &&
args.get_item().get_checked()) {
alert("Checked");
}
}
For more info on the client side functions from Telerik, you can check this link: http://www.telerik.com/help/aspnet-ajax/listboxitem-client-api.html
Also, you might run into this small annoyance where you have to click in the little checkbox itself, and not anywhere on the row (as one might expect). You can find a workaround for that one here: http://www.msigman.com/2010/07/telerik-radlistbox-fix/

try using change instead of click? that way you will catch changes made via keybord as well. and it will solve ypur problem.

Related

Using jQuery to change the order of Select Options not working correctly

I have a friend that helped me code this as I am unable to get it working correctly. I am trying to edit the order of the Select list items as I am unable to edit the list manually because the list is populated within a Wordpress plugin called SellMedia. The code supplied currently works but when you click on the dropdown list it works, then if you click off and back on it change the order.
Is there a way to stop this from happening?
$(document).on('click','#sell_media_item_size',function(){
$("#sell_media_item_size option").slice(1, 19).each(function () {
var options = $('#sell_media_item_size option');
$(this).insertAfter($(options[0]));
});
});
Example here - https://jsfiddle.net/7bbxd42b/5/
You should order only once. You can use a flag on the global level to check that you have already ordered the entries:
var ordered = false;
$(document).on('click','#sell_media_item_size',function(){
if (!ordered) {
$("#sell_media_item_size option").slice(1, 19).each(function () {
var options = $('#sell_media_item_size option');
$(this).insertAfter($(options[0]));
});
ordered = true;
}
});
It would be even better, if you could check it some other way, so you would not need the global flag.
Update: I just found out, you can use .one() instead of .on() to bind the click event. So the handler will be fired only once.

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

Jquery lag on click function

I've got a table with different columns identified with different classes.
I've also a checkbox binded to every column.
I created a function which is called on the click of any checkbox. In this function I hide/show the column which is linked to this.
It doesn't have any javascript error, and the code is the following:
$(document).ready(function(){
$('ul input').click(function(){
//alert('yooo');
if ($(this).is(':checked')) {
//alert('checked');
$("td."+replaceAll(" ","_",$(this).val())).show();
$("th."+replaceAll(" ","_",$(this).val())).show();
//alert($("td").length);
}
else{
//alert('unselected');
$("td."+replaceAll(" ","_",$(this).val())).hide();
$("th."+replaceAll(" ","_",$(this).val())).hide();
}
});
});
However, after every click, the action has a lag (after many clicks it becomes tooooooo slow, many seconds).
I tried also with .css instead of hide-show, but it doesn't make any change.
I understood that the problem was linked only to checkbox, not on callback or on jquery function. I solved the problem simply by working with radio input, adding a "true" and a "false" radio input for every checkbox that was in the page.
Instead of running the jQuery selector on every click like below:
$("td."+replaceAll(" ","_",$(this).val()))
You could set up some sort of caching like:
var cache = {} //<-- declare this outside your click handler
//add the code below inside your click handler
className = replaceAll(" ","_",$(this).val())
if(!cache[className])
cache[className ] = $("td."+className + ", th."+className); //select all the elements once and store in the cache object
$el = cache[className];
if ($(this).is(':checked'))
$el.show();
else
$el.hide();

Input:Checked jQuery vs CSS?

Unless I am mistaken. jQuery and CSS handle the :checked selector very differently. In CSS when I use :checked, styles are applied appropriately as I click around, but in jQuery it only seems to recognize what was originally in the DOM on page-load. Am I missing something?
Here is my Fiddle
In jQuery:
$('input:checked').click(function () {
$('input:checked').css('background','#FF0000');
$('input:checked+label').css('background','#ff0000');
});
In CSS:
input:checked+label {font-weight:bold;color:#5EAF1E}
UPDATE:
I should clarify that what I am looking to do is trigger behavior if a user clicks an already selected radio button.
Try setting up the handler this way:
$('body').on('click', 'input:checked', function() {
// ...
});
The way you have it, you're finding all the elements that are checked when that code runs. The above uses event bubbling so that the test is made when each "click" happens.
Inside your handler, you're updating the style for all checked elements, even though any particular click will only change one. That's not a huge deal if the number of checkboxes isn't too big.
edit — some further thought, and a helpful followup question, makes me realize that inside an event handler for a radio button "click" event, the button will always be ":checked". The value of the "checked" property is updated by the browser before the event is dispatched. (That'll be reversed if the default action of the event is prevented.)
I think it'll be necessary to add a class or use .data() to keep track of a shadow for the "checked" property. When a button is clicked, you'd see if your own flag is set; if so, that means the button was set before being clicked. If not, you set the flag. You'll also want to clear the flag of all like-named radio buttons.
You bound the event only to the inputs that were initially checked. Remove :checked from the first selector and it works as intended (but ugly.)
http://jsfiddle.net/8rDXd/19/
$('input').click(function () {
$('input:checked').css('background','#FF0000');
$('input:checked+label').css('background','#ff0000');
});
you would of course need to "undo" the css change you made with jQuery to make it go away when the input is unchecked.
$('input').click(function () {
$('input').css('background','').filter(":checked").css('background','#FF0000');
$('input+label').css('background','');
$('input:checked+label').css('background','#ff0000');
});
http://jsfiddle.net/8rDXd/20/
AFTER UPDATE
Keep track of the status of the radio buttons. For example, use .data() to keep an in-memory state of the radio buttons.
$(function () {
var $radio = $(":radio");
$radio.filter(":checked").data("checked", true);
$radio.on("click", function () {
if ($(this).data("checked")) {
alert("Already selected");
}
$radio.data("checked", false).filter(":checked").data("checked", true);
});
});
See it live here.
BEFORE UPDATE
I think you want to use .change() here.
$('input:radio').change(function () {
$('input, input+label').css('background', '');
$('input:checked, input:checked+label').css('background', '#f00');
}).change();
See it live here.

Sequence of Events, alert is faster then removeAttr

i got following problem, i need to build a two checkboxes; where only one can be selected at a time, but onchange there will be a live calculation.
$('#calculator input, #calculator select').change(function() {
$('#calc_keller_true').click(function() {
$('#calc_keller_false').removeAttr('checked');
});
$('#calc_keller_false').click(function() {
$('#calc_keller_true').removeAttr('checked');
});
liveCalculate();
});
This is how it looks like, which is working but it seems to slow cause in my function liveCalculate i do this.
function liveCalculate() {
// Getting the value of the checked checkbox
var calc_keller = $('input[name=calc_keller]:checked').val();
alert(calc_keller);
}
So when i click on the false button the alert will trigger before my removeAttr and both Checkboxes will be 'checked' at the moment of the alert.
Anyone got a plan why exactly the liveCalculate function triggers faster then the removeAttr ?
Do i miss some basic knowledge in how the order works in javascript ?
Best Regards,
jay7
You only need to add click-handlers once. In your above example, you are adding them again and again, for every 'change' event you have on the select box.
Furthermore, you are not actually removing the attr on the change event, that happens during the click events. However, you fire liveCalculate after the change event.
Consider the following:
$('#calc_keller_true').click(function() {
$('#calc_keller_false').removeAttr('checked');
});
$('#calc_keller_false').click(function() {
$('#calc_keller_true').removeAttr('checked');
});
$('#calculator input, #calculator select').change(function() {
$('#calc_keller_false').removeAttr('checked');
$('#calc_keller_true').removeAttr('checked');
liveCalculate();
});
I'm not entirely sure if that accomplishes what you're expecting (simply because it isn't 100% clear to me what you do expect to happen).

Categories

Resources