I know this is different between browsers; e.g. If I attach a function to the onclick and onchange event of a radio button, then click on it, Chrome fires onchange then onclick, while Firefox does the opposite.
Is there a resource anyone knows of that breaks down this firing order by browser?
Here's a JSFiddle that will tell you if you run it in each browser:
http://jsfiddle.net/BUkHz/
<label for="myRadio">Radio Button</label><input type="radio" name="myRadio" id="myRadio"/>
<label for="myRadio">Radio Button 2</label><input type="radio" name="myRadio" id="myRadio2"/>
var myRadio = document.getElementById('myRadio');
var myRadio2 = document.getElementById('myRadio2');
myRadio.addEventListener('change', interceptRadioEvent);
myRadio.addEventListener('click', interceptRadioEvent);
myRadio2.addEventListener('change', interceptRadioEvent);
myRadio2.addEventListener('click', interceptRadioEvent);
function interceptRadioEvent(e){
//do anything else you want to here...
radioEventHandler(e);
}
function radioEventHandler(e){
console.log(e.type);
}
I have a hunch that the order depends on what you're doing - for example if you only have one radio button on first click it will be : change, click then further clicks would be 'click' only as it responds to the click but can't unset it.
I hope that helps.
On a Mac :
Chrome:
change then click
Safari:
change then click
iOS(6):
change then click
Related
I have a gridview, I've added a Checkbox column.
With checkbox select all, I am using jQuery to check all the checkboxes.
Following code is what i have tried,
function checkBoxSelectAll() {
$("#chkSelectAll").click(function () {
$('input:checkbox').not(this).prop('checked', this.checked);
});
}
I used DevExpress Gridview in MVC5, This is my code in View
#(Html.DevExpress()
.GridView(settings =>
{
//settings.Settings.ShowVerticalScrollBar = true;
settings.Height = Unit.Percentage(100);
settings.SettingsPager.Mode = GridViewPagerMode.ShowAllRecords;
settings.Settings.ShowFooter = true;
settings.Name = "gvw1";
settings.Width = Unit.Percentage(100);
settings.CallbackRouteValues = new
{
Controller = "Vehicle",
Action = "ListPartial"
};
settings.SettingsBehavior.AllowGroup = false;
settings.SettingsBehavior.AutoExpandAllGroups = true;
settings.KeyFieldName = "Id";
settings.Columns.Add("VehicleGroupName", Html.GetResource("group")).GroupIndex = 0;
settings.Columns.Add(column =>
{
column.SetHeaderTemplateContent(content =>
{
ViewContext.Writer.Write(string.Format("<input type='checkbox' name='chkSelectAll' id='chkSelectAll' onchange='checkBoxSelectAll()'/>"));
});
column.SetDataItemTemplateContent(c =>
{
ViewContext.Writer.Write(string.Format("<input type='checkbox' name='chkID' id='" + #c.KeyValue + "' />"));
});
});
Devexpress Gridview generate HTML below
<tr id="gvw1_DXDataRow1" class="dxgvDataRow_DevEx">
<td class="dxgvIndentCell dxgv" style="width:0px;border-left-width:0px;border-bottom-width:0px;"> </td>
<td id="gvw1_tccell1_1" class="dxgv" style="border-left-width:0px;">
<input type="checkbox" name="chkID" id="1657">
</td>
</tr>
It works good in Chrome, Safari, Opera, IE11, Microsoft Edge.
But in firefox, at the first time, It doesn't work. (When I click on the checkbox select all, all checkbox in this gridview doesn't checked).
Then I unchecked the Checkbox Select All, then I checked it again, It worked, All checkbox in gridview be checked.
Anyone can tell me why?
I am using jQuery 1.9.1.
Sorry for my bad English.
Thanks a lot,
Truong Mai
You are calling javascript function checkBoxSelectAll for every click on select all checkbox and registering click handler every time. Instead you need to register click handle or change handler only once when document get loaded.
try below code
$(document).ready(function(){
$("#chkSelectAll").change(function () {
$('input:checkbox').not(this).prop('checked', this.checked);
});
});
As given above the problem is how you are registering the event handler. You are adding the handler which actually sets the checked property only on change of the all checkbox, so when the first click happens the handler which really changes the checked property is not present so it is not fired.
When the second click happens, you have already added a click handler which will add the desired click behavior, but now you are adding an additional click handler so the 3rd click will trigger the jQuery handler twice.
As discussed above the solution is to use a single click handler which is registered in the dom ready handler like
jQuery(function ($) {
$("#chkSelectAll").click(function () {
$('input:checkbox').not(this).prop('checked', this.checked);
});
})
But going back to why it is working in chrome, I think it is because of the choice of event handler you have choose, you are calling checkBoxSelectAll in an onchange handler, but it looks like the order of change and click handler order defers in FF and other browsers. In chrome the change event is fired first then the click handlers... so by the time the click handlers are triggered your checkBoxSelectAll would have already added the jQuery handlers causing the click to work. But in FF the click handlers is fired first then the change handler so when click is processed there is no jQuery handler.
$("#chkSelectAll").on('click change', function(e) {
snippet.log('event: ' + e.type)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<input id="chkSelectAll" type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
I need to check my radio button manually like below. But the problem is that the event is not fired (when checked manually).
$(function () {
// always check the 1st element
$("input:radio[name=MatrixID]:first").attr('checked', true).click();
});
$('.editor-field > input[type=radio]').change(function () {
// !!! not fired when checked by code!!??
p.mustSave = true;
});
My question: how to check manually (by code) my radio button and also trigger change event?
My html:
<p>
<span class="editor-field">
<input name="MatrixID" id="MatrixID873" type="radio" checked="checked" value="873"/>
</span>
</p>
Thanks a lot.
.click() trigger click event, but you are using change(). Try this instead :
$("input:radio[name=MatrixID]:first").prop('checked', true).trigger('change');
I have a checkbox that I do not want the user to have direct access to. I want them to accept some terms. To do this I want them to be able to click on a disabled checkbox which opens this mini popup (not checking the box) that contains the terms so the reader can read them and accept them. Once they accept them the popup will close and the checkbox will be checked. The issue I have is i cant figure out to run a function onclick of the disabled checkbox.
Handling the click on a disabled element is indeed tricky ... but I don't think it's the desirable user experience anyway. If a checkbox is disabled, some users will see that and be disinclined to even attempt clicking it. Instead, consider intercepting the click event and using it for your own purposes using preventDefault.
<input type='checkbox' id="cb" name="cb" />
$(document).ready(function() {
$("#cb").click(function(e) {
// cancel click event so that checkbox remains unchecked
e.preventDefault();
// display popup here, then manually check the checkbox if needed
}
});
$('#chk').click(function () {
if (confirm('Accept')) {
$(this).attr('checked', 'checked');
}
else {
$(this).attr('checked', false); }
});
A disabled checkbox might not handle click events properly and would be displayed as "disabled".
But, you could try this:
add an attribute to the checkbox to store if the popup was displayed (e.g. data-popup="0")
handle the onclick event on the checkbox
if the popup was displayed (data-popup="1" ) simply return true to allow to use to check it
if the popup was not displayed (data-popup="0" ), then prevent the default behaviour, set data-popup="1" and display the popup with the terms and conditions
Another improvement, depending on the design of your popup, could be the add a new checkbox in that popup and when the user reads the terms and conditions, he can accept the terms and conditions directly from the popup. If you do that, you need to treat the click event on the checkbox in the popup and automatically check the checkbox on your page as well.
#dbaseman
Here is my code.
Take a look.Here,I get the alert on div but not on checkbox.
<html>
<head>
<script type="text/javascript" src="jQuery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#checkbox, #hello").click(function(){
alert("hello");
});
});
</script>
</head>
<body>
<div id="checkbox">
<p> hello</p>
<input type="checkbox" id="hello" disabled="disabled" />
</div>
</body>
</html>
Consider the following code (http://jsfiddle.net/FW36F/1/):
<input type="checkbox" onchange="alert(this.checked)">
<button onclick="document.getElementsByTagName('input')[0].checked=!document.getElementsByTagName('input')[0].checked;">toggle</button>
If you click the checkbox, you get an alert telling you if it's checked or not. Great. However, if you click the toggle button, the checkbox changes it's checked state but the onchange event is NOT fired.
Essentially, the onchange for a checkbox only fires if the user actually clicks the checkbox, not if the checkbox is changed via JavaScript. This is be true in IE, FF, and Chrome. It appears that this behavior is to specification also.
However, I really need some kind of event to fire if, for any reason, the checkbox's checked state changes. Is this possible?
Oh yeah, and jQuery is not allowed. And please no setTimeout/setInterval based solutions either...
Update: Also, I should make it clear that the code above is for illustration only. In the real code, we need to ensure the state of the checkbox is checked or unchecked -- not just toggle it. Perhaps this would be better code to illustrate that:
<input type="checkbox" onchange="alert(this.checked)">
<button onclick="document.getElementsByTagName('input')[0].checked=true;">check</button>
<button onclick="document.getElementsByTagName('input')[0].checked=false;">un check</button>
Moreover, there may be code in other areas we don't fully control, which might do a simple .checked=true/false -- we'd like to make sure we see that also.
The existing answers work just fine, even with your update. Just be smart about it and don't call click if you don't need to. Also, please don't use inline JS. That was OK 10 years ago.
<input type="checkbox" onchange="alert(this.checked)">
<button id='check'>check</button>
<button id='uncheck'>uncheck</button>
document.getElementById('check').onclick = function() {
if (!this.checked) {
this.click();
}
}
If you need to be modified when a script changes the value, in Firefox, you can use https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch
Example here http://jsfiddle.net/PPuZ8/
// In FF $ is a shortcut for document.getElementById
// It doesn't fire when set from the UI, you have to use a regular handler for that
$('cb').watch("checked", function(){
console.log('Checked state changed from script', arguments);
return true;
});
For IE you can use onpropertychange http://msdn.microsoft.com/en-us/library/ie/ms536956(v=vs.85).aspx (Thanks to jivings for the reminder)
Example: http://jsfiddle.net/PPuZ8/1/
document.getElementById('cb').onpropertychange = function() {
if (event.propertyName == 'checked') {
console.log('Checked state changed onproperty change');
}
};
For other browsers, you have to poll using setInterval/setTimeout
Have the toggle button actually click the checkbox:
<input type="checkbox" onchange="alert(this.checked)">
<button onclick="document.getElementsByTagName('input')[0].click()">
toggle
</button>
If you wanted any change to the checkbox to inform you of its new position, then I would create a global method for changing the value of the checkbox, and deal with it as a proxy:
<script>
function toggleCB( state ) {
var cb = document.getElementById("cb");
arguments.length ? cb.checked = state : cb.click() ;
return cb.checked;
}
</script>
<input id="cb" type="checkbox" />
<input type="button" onClick="alert( toggleCB(true) )" value="Check" />
<input type="button" onClick="alert( toggleCB(false) )" value="Uncheck" />
<input type="button" onClick="alert( toggleCB() )" value="Toggle" />
Now anytime you set or toggle the checkbox, you'll get the checked state back.
One last thing, I would avoid using the onClick attribute, and instead bind the click events up from within your JavaScript.
Use click()
<button onclick="document.getElementsByTagName('input')[0].checked=!document.getElementsByTagName('input')[0].click();">toggle</button>
oninput is the event you need to handle ...
https://developer.mozilla.org/en/DOM/DOM_event_reference/input
Let's say I have a group of two radio buttons:
<input type="radio" name="radioButtonGroup" value="button1" checked="true"/>
<input type="radio" name="radioButtonGroup" value="button2"/>
It seems that clicking the second button triggers an event handler on that button only. However, the first button does become deselected, and visually does change. Can anyone verify that events are fired only on the button that was selected, and not any of the other buttons in the group which become deselected as a result of the click? Any clever ways to watch a radio button for a deselecting event?
Although it cannot be confirmed, but the event change triggers don't happen on the entire group.
If you want that to happen, you can do it using various JS libraries like jQuery, YUI, etc. or even plain javascript, as follows:
function buttonGroupChange(){
var radioElements = document.getElementsByName("radio_group_name");
for(var i = 0; i < radioElements.length; i++){
if(radioElements[i].checked == true){
//do something
}
else{
//do something
}
}
}
This function can be called on the onClick or the onChange event.
I hope that solves your problem.
Firstly, it is important to note that a "Click" event on any of the radios fires AFTER the "checked" value is already updated. This is important - because it means you can't detect the previous item once the event is already fired. If you Cancel the event, you are actually changing the value BACK - not stopping it initially. This is important to how you approach the problem.
Example:
<input type="radio" name="radioButtonGroup" value="button1" checked="true"/>
<input type="radio" name="radioButtonGroup" value="button2"/>
// At this point, the ':checked' item is button1.
$('input[type=radio]').bind('click', function (ev) {
// If you click on button2 - by this point, the ':checked' item is already button2.
ev.preventDefault(); // These two lines will stop the radio from actually
ev.stopPropagation(); // changing selection.
// At this point, the ':checked' item is set BACK to button1.
});
Because of this, the easiest solution is to track the "last" selected item in a closure alongside your event handlers, as follows:
<input type="radio" name="radioButtonGroup" value="button1" checked="true"/>
<input type="radio" name="radioButtonGroup" value="button2"/>
<script type="text/javascript">
var $last = $('[name=radioButtonGroup]:checked');
// Select the radio buttons as a group.
var $radios = $('[name=radioButtonGroup]').bind('change', function (ev) {
// Click event handler
var $clicked = $(ev.target); // This is the radio that just got clicked.
$last.trigger('unclick'); // Fire the "unclick" event on the Last radio.
$last = $('[name=radioButtonGroup]:checked'); // Update the $last item.
// Should see the clicked item's "Value" property.
console.log("Clicked " + $clicked.attr('value'), $clicked, ev);
}).bind('unclick', function (ev) {
// Handler for our new "unclick" event.
// - fires whenever a radio loses focus.
var $unclicked = $(ev.target); // The radio losing it's checked status.
// Should see the unclicked item's "Value" property.
console.log("Unclicked " + $unclicked.attr('value'), $unclicked, ev);
});
</script>
For a working example, see:
http://jsfiddle.net/TroyAlford/wvrtC/
I can't confirm that an event is only fired for the selected button, but if you needed to do something with the button that was just deselected, the following would work:
$(document).ready(function(){
var selectedRadio = null;
$("input:radio").change(function(){
if(selectedRadio != null){
alert(selectedRadio.val());
}
selectedRadio = $(this);
});
});
In action here.
If you need to keep track of multiple groups of radio buttons, you could do it with an array of currently selected buttons and match within that array when a change is detected.
The simple nature of the radio button set is that only one button can be selected at a time. Selecting a button automatically means the others are not selected, but there is no specific action for deselecting. Therefore, you only need to worry about the one event, because it affects all the buttons in the set at one time.
If you would like to use an element that allows for multiple selections try checkboxes.