Fire an event on input.checked=true/false _without_ jQuery - javascript

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

Related

Capturing a button click as part of a field validation

I have an onblur='validate(this)' on a text field but I do not want the validate code to run when a cancel button is clicked.
function validate(oField) {
if (document.getElementById('Cancel').clicked != true) {
console.log("Cancel clicked");
}
}
<input id='reviewername'
name='reviewername'
type='text'
class='$class'
value='$reviewername'
tabindex=1
size=$size
onkeydown='setKeyCode(event)'
onblur='validate(this)'/>;
<input type='submit'
name='Button'
id='Cancel'
value='Cancel'>;
The document.getElementById('Cancel').clicked is always 'undefined'.
I have tried addListener(), probably incorrectly, as well as other newbie tricks with no success!
What I am trying to do is check whether the Cancel button is clicked while the text field has the focus. Immediately I click the button, the text field event 'onblur' runs. I want to check for the button click as the first part of the javascript validate() function.
Is what I am attempting even possible?
Please help before I lose the rest of my hair.
You can use àddListener() if you name it correctly as addEventListener().
Then, you can set some variable when the cancel button is clicked and use that variable in replacement to your document.getElementById(...).clicked.
cancel_clicked = false;
function validate(oField) {
if (cancel_clicked != true) {
console.log("Cancel not clicked");
} else {
console.log("Cancel clicked");
}
}
<input id='reviewername'
name='reviewername'
type='text'
class='$class'
value='$reviewername'
tabindex=1
size=$size
onkeydown='setKeyCode(event);'
onblur='validate(this);'/>
<input type='submit'
name='Button'
id='Cancel'
value='Cancel'
onclick='cancel_clicked = true;'/>
Browsers are removing direct event listener attachment to DOM elements, it's better to use javascript to add the event listeners, instead of the onlick or onblur attributes on DOM elements, this is what I've noticed lately.. So you are more safe with using addEventListener, also do watch out for your spelling too incases where you get undefined,or you are loading your script before your DOM tree.. As a thumb rule, load your javascript file last.

Why doesn't checkbox select all not working on Firefox at the first time?

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" />

How do I check when an input is changed?

I tried using the "input" event on the text box but it doesn't work. I've read a few posts on Stack Overflow but none of them worked.
Here's my most recent HTML and Javascript code using onchange:
function updateResults(){
document.write("Wroks");
}
<input id="search-box" onchange="updateResults();"> </input>
I tried changing HTML to onchange="updateResults;" but didn't work.
I also tried changing HTML to onchange="updateResults(event);" and then Javascript to function updateResults(event){...}
Nothing that I tried worked.
Looks fine to me. If you make any changes then you'll see the function get called as soon as you lose focus (onchange only happens when you blur). If you want more immediate results you can use oninput instead, like so:
function updateResults(){
document.write("Wroks");
}
<input id="search-box" oninput="updateResults();" />
Another way is to use event listeners, if you want to keep javascript out of the markup:
function updateResults() {
document.write("Wroks");
}
document.getElementById("search-box").addEventListener("input", updateResults);
<input id="search-box" />
The above however will only work if the DOM has already been loaded when the javascript is run. You could put it in an onload event, or include the javascript after the DOM markup.
Alternatively you could attach the event listener to the document and check for the ID whenever the event is triggered. There are pros and cons to this method. Since the function doesn't attach to the element directly, the DOM will not need to be loaded yet. If the element is removed and a new one with the same ID is added, it will still work. Also, if you add your content dynamically after the page loads, you will not need to worry about attaching the listener later. However, this function will be called every time any input on the page is registered, which theoretically could slow the page down (e.g. if you have a lot of these types of listeners), although probably minimally.
function updateResults() {
document.write("Wroks");
}
document.addEventListener("input", function(e) {
if (e.target.id === "search-box") {
updateResults();
}
});
<input id="search-box" />
document.write("Wroks"); will replace everything in your window with "Wroks".
try this:
<input id="search-box" onchange="updateResults();"> </input>
<script>
function updateResults(){
console.log('Works');
}
</script>
You also may want to consider using jQuery because then you could do a lot more out of the box with this. for example:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<input id="search-box">
<script>
$('#search-box').on('change',function(){
console.log($(this).val());
})
</script>
The above code will give you the value of the input on change.
try:
<input id="search-box" onchange="javascript:updateResults();"> </input>
or:
<input id="search-box" onchange="javascript:document.updateResults();"> </input>
It is a bit unclear whether you want the JavaScript to fire when the user finishes updating the textbox, or after every character is input.
This will fire after the user "commits" to their input, often by clicking something else.
HTML
<input id="search-box" />
JavaScript
function updateResults(){
alert("Works");
}
document.getElementById("search-box").addEventListener("change", updateResults, false);
This will fire after every key is pressed (and so forth).
HTML
<input id="search-box" />
JavaScript
function updateResults(){
alert("Works");
}
document.getElementById("search-box").addEventListener("input", updateResults, false);
As far as I understand the question, you want to know when a user types in one letter/number and then call your function.
This would be "onkeyup":
<input type="text" onkeyup="myFunction()">
You could also use onkeydown. See also http://www.w3schools.com/jsref/dom_obj_event.asp
When you use onchange, this works too, but only after the input is finished. Either when the user presses enter or after leaving the textbox.
If all of this doesn't work, turn on Javascript in your Browser.

what order do events fire on radio button click?

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

onchange not working with radio button

I have a few radio buttons which should call hider(something); when they change, meaning when they are checked or unchecked. This works, i.e. when checked they call the JS function, however, if they're unchecked due to selecting another radio button from that group, it does not call the js script again.
Do I need to use something else than onchange?
This is what the radio buttons look like at the moment:
<input name="ostype" type="radio" value="0" onchange="hider(solaris);">solaris
<input name="ostype" type="radio" value="1" onchange="hider(linux);">linux
My hider function is currently:
function hider(divid) {
if ($(divid).is('.hidden')) {
$(divid).removeClass('hidden');
} else {
$(divid).addClass('hidden');
}
}
Since this question is still not answered correctly yet ranks quite high for me in Google for "radio button onchange", here's a proper solution for anyone still looking.
If you're using jQuery, just use jQuery's attribute selector as noted by Flavius Stef.
OP, it's not entirely clear what your code does. Let's assume in your code you want to add the "hidden" class to whatever radio button is active.
$("your selector here").change(function() {
$('input[name="' + this.name + '"]').removeClass("hidden");
$(this).addClass("hidden");
});
Please note the difference between $(this) (the jQuery object) and this (the DOM object). Basically I'm removing the "hidden" class from every input that goes by the same name, and then I add the "hidden" class to the current input.
Of course I'm assuming here that you're not using duplicate names for different inputs on the page. Also note that this would only work for radio buttons, as the radio button "change" event only fires when activated, not when deactivated.
Listening for onchange on both checkboxes and radio buttons
In my case, I wanted to add a "checked" class to active radio buttons and checkboxes. Since the checkbox fires the "onchange" event both when checked and unchecked, I needed a bit of extra code.
$('input[type="radio"]').change(function() {
$('input[name="' + this.name + '"]').removeClass("checked");
$(this).addClass("checked");
});
$('input[type="checkbox"]').change(function() {
$(this).toggleClass("checked", ($(this).is(":checked")));
});
The latter function uses toggleClass to set the "checked" class if .is(":checked") is true.
Alternatively you might want to combine the two functions into something like:
$('input[type="radio"], input[type="checkbox"]').change(function() {
if(this.type == "radio")
$('input[name="' + this.name + '"]').removeClass("checked");
$(this).toggleClass("checked", ($(this).is(":checked")));
});
Either way, always be careful when listening for an onclick event as it will not fire when the input is activated through keyboard navigation.
Use onclick.
Also as the argument of your function call you'll need to either use a string with the id as a jQuery selector ('#solaris') - better yet use this:
<input name="ostype" type="radio" value="0" onclick="hider(this);">solaris
Bind change event to ALL radio buttons on document ready:
$(function(){
$('input[name=list_type]:radio').on("change", function(){
showHideBlock();
});
showHideBlock();
});
Show -- hide block depends on ONE radio button status:
function showHideBlock(){
if ($("#Option").is(':checked')){
$('#Block').show();
} else {
$('#Block').hide();
}
}
<input name="ostype" type="radio" value="0" onclick="hider('solaris');">solaris
<input name="ostype" type="radio" value="1" onclick="hider('linux');">linux
function hider(divid) {
$( 'div.div_class' ).hide();
$( '#' + divid ).show();
}
Make sure you add a class to call the divs and make sure you put quotes around solaris and linux in the function calls
Here's a version that you might draw inspiration from (tested on Chrome and FF):
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js">
</script>
</head>
<body>
<input type="radio" name="ostype" checked="checked" onclick="hider('linux')">linux
<input type="radio" name="ostype" onclick="hider('solaris');">solaris
<div id="content">
<div id="linux">linux</div>
<div id="solaris" style="display:none;">solaris</div>
</div>
<script>
function hider(divname) {
$('#content div').each(function(){
$(this).hide();
});
$('#'+divname).show();
}
</script>
</body>
</html>
If I understand you correctly you can just use an onClick on every button and hide the others while showing the one your clicking on.
Like this:
function showInfo(info)
{
var info = document.getElementById("1");
info.style.display = "block";
var info = document.getElementById("2");
info.style.display = "none";
}
So the first one is showing and the second one is hiding.
Then just add one for every div that should be hidden.
You can also do this with jQuery.
function showAndHide(val1, val2)
{
$(val1).hide();
$(val2).show();
}
And don't forget to have style="display:none" in every div.
did you declare the vars solaris and linux?
otherwise your browser should show you an Error

Categories

Resources