I have a form with thousands of checkboxes, and when one is checked, I want to check all the boxes below it.
This works:
<html>
<body>
<form name="myform">
<input type="checkbox" name="box1" onClick="redrawboxes(this);">1<br>
<input type="checkbox" name="box2" onClick="redrawboxes(this);">2<br>
...
</form>
</body>
</html>
<script>
function redrawboxes(obj){
//check all boxes below
var foundit=false;
for (e=0; e<document.myform.elements.length; e++){
if (foundit==false){ //search for checked obj
if(obj == document.myform.elements[e]){
foundit=true;
}
}else{ //continuing below checked box
if(obj.checked){ //are we checking or unchecking
document.myform.elements[e].checked = true;
}else{
document.myform.elements[e].checked = false;
}
}
}
}
</script>
but for more than a few thousand boxes, IE is unacceptably slow. (Firefox works fine.)
Is there a better way to find the original box besides iterating through the whole list?
Both of the jQuery suggestions are pretty good. For DOM wrangling like this, you're really better off using a good library.
And the comment about the dubious wisdom of putting thousands of checkboxes on a form is pretty good as well...
But, on the off-chance that you do have a good reason for doing this, and you can't use jQuery or similar, here's a fast, straight JS method:
function redrawboxes(obj)
{
//check all boxes below
var next = obj;
while ( (next = next.nextSibling) )
{
if ( next.nodeName.toLowerCase() == "input"
&& next.type.toLowerCase() == "checkbox" )
next.checked = obj.checked;
}
}
tested in FF3, FF3.1, IE6, Chrome 1, Chromium 2
i might get down voted for this, but try using jquery. it has selectors optimized for that.
Advertising inside !
If you are using jQuery, you can try my plugin to make your loop asynchronous, this will allow to run a long loop without freezing the browser.
http://mess.genezys.net/jquery/jquery.async.php
If you don't want to use jQuery, you can download the plugin and modify the code for your own needs, it does not really depend on jQuery.
You can read out the name of the selected checkbox like this:
function redrawboxes(obj) {
var name = obj.name;
var state = obj.checked;
// get that index
var index = name.substr(3) * 1; // just to be sure it's a number
var length = document.myform.elements.length;
var allElements = document.myform.elements
// (un)check all elements below
for (var i = index; i < length; i++) {
allElements[i].checked = state;
}
}
You could have sped up your code quite a bit by using local variables and there's an if-statement that can be replaced.
Edit: Actually that one-off-error isn't an error because that specific checkbox was (un)checked by the user himself.
Dunno how fast it is, but you could try the jQuery-way, grab jQuery from www.jquery.com and insert the following code on the page:
$(function(){
$("input:checkbox").click(function(){
$(this).nextAll("input:checkbox").each(function(){
this.checked = true;
});
});
});
Related
I have a jsp page on which table is coming dynamically and have checkboxes on that page when you click on that box it should save in array and when it uncheck the box it should remove value from array.
I have tried this by creating a method but it is not working perfectly can you please help me..
function addCheckboxVAlues(checked){
var split = checked.value.split("|");
var key =split[0];
var value=split[1];
var chks = $("input[name='"+key+"']:checked");
if (chks.length > 0) {
uninvoiced.push(value);
} else {
uninvoiced.pop(key);
}
console.log(uninvoiced);
}
You need to use splice to remove the element from the array
function addCheckboxVAlues(checked){
var split = checked.value.split("|");
var key =split[0];
var value=split[1];
var chks = $("input[name='"+key+"']:checked");
var index = uninvoiced.indexOf(key);
if (chks.length > 0) {
uninvoiced.push(value);
} else if(index > -1){
uninvoiced.splice(index, 1);
}
console.log(uninvoiced);
}
This code looks way more complex than it needs to be. Presumably the checkbox has a click listener on it, so it should be called with the checkbox as this. All you have to do is add the value if the checkbox is checked, or remove it if it's unchecked.
That will be hugely more efficient than running a checked selector every time.
The following uses an inline listener for convenience, likey you're attaching them dynamically but it seems to be called the same way.
var uninvoiced = [];
function addCheckbox(el) {
var value = el.value.split('|')[1];
if (el.checked) {
uninvoiced.push(value);
} else {
uninvoiced.splice(uninvoiced.indexOf(value), 1);
}
console.log(uninvoiced);
}
foo|bar: <input type="checkbox" value="foo|bar" onclick="addCheckbox(this)">
fee|fum: <input type="checkbox" value="fee|fum" onclick="addCheckbox(this)">
There is a polyfill for indexOf on MDN.
With this code and chk1 and chk2 as 0, is impossible to me to guess what is wrong with this simple code function.
As i know, there are many js ways to use click, like ".click()", ".on('click')" or ".onClick" but none of them works at all. Take a look of this example:
regbtn.click(function() {
if(chk1 == 0){
if(chk2 == 1){
box2.reverse();
chk2 = 0;
}
box1.restart();
chk1 = 1;
}
});
logbtn.click(function() {
if(chk2 == 0){
if(chk1 == 1){
box1.reverse();
chk1 = 0;
}
box2.restart();
chk2 = 1;
}
});
Is there any reason why this doesnt work properly? and which way is the newest and best to use of this 3 ways of click js functions.
EDIT
regbtn and logbtn are 2 buttons that open 2 diferent boxes, box1 and box2 respectively, chk1 and chk2 is to check if the other box is open and reverse it first if so.
Alert doesnt work at all in any place.
This is the initial code variables to work with:
var regbox = document.getElementById("regbox"),
logbox = document.getElementById("logbox"),
regbtn = document.getElementById("regbtn"),
logbtn = document.getElementById("logbtn");
var chk1 = 0,
chk2 = 0;
You are trying to apply JQuery methods to DOM elements.
Try using JQuery selectors instead:
var regbox = $("#regbox"),
logbox = $("#logbox"),
regbtn = $("#regbtn"),
logbtn = $("#logbtn");
These return JQuery objects connected to the relevant DOM elements. The extensive (cross-browser) methods on JQuery object are what make it so powerful. If you find yourself using DOM elements directly that is often a sign of something that is less portable.
Before appending more code, I want to make sure:
<a href='index.php?option=com_content&view=article&id=36'>Hello</a>
isn't already on the html page inside the div where id='faqs'
<div id='faqs'>
<a href='index.php?option=com_content&view=article&id=36'>Hello</a>
</div>
What is the best way of doing this with jquery or javascript?
Thanks
The easiest way would be to use jQuery to select the element, and check the length property of the resulting object:
var anchor = $('#faqs a[href="index.php?option=com_content&view=article&id=36"]')
if(anchor.length == 0) {
// element isn't on the page
}
You could search using indexOf
var inBlock = $('#faqs').html();
if (inBlock.indexOf("<a href='index.php?option=com_content&view=article&id=36'>Hello</a>") == -1) {
$('#faqs').append ("<a href='index.php?option=com_content&view=article&id=36'>Hello</a>");
}
if (!$('a[href$="view=article&id=36"]', '#faqs').length) {
//does'nt exist
}
If the goal is to end up with the a tag as a child in the div tag, and thats it, then don't bother checking, just re add it, like this:
$('#faqs').html('');
$('<a />')
.attr('href', 'index.php?option=com_content&view=article&id=36')
.html('hello')
.appendTo($('#faqs'));
However, if you genuinely need to check if it exists, then you can do something like this:
var exists = $('#faqs a[href="index.php?option=com_content&view=article&id=36"]').length > 0;
UPDATE
Finding the string in the html can be done as follows, but this is not a recommended solution. You may run into issues with different browsers encoding html in different ways etc (tested in chrome):
var stringToFind = 'Hello';
// need to replace the & ...
stringToFind = stringToFind.replace(/&/g, '&');
var exists = $('#faqs').html().indexOf(stringToFind) > -1;
if (exists) {
// do something
} else {
// do something else
}
Here's a working example -> http://jsfiddle.net/Uzef8/2/
I'm wondering if it's possible for a script to enable/disable all input elements on the page with some sort of toggle button.
I googled it but didn't find anything too useful except for this:
http://www.codetoad.com/javascript/enable_disable_form_element.asp
but I'm not sure how to edit it for the toggle.
Something like this would work:
var inputs=document.getElementsByTagName('input');
for(i=0;i<inputs.length;i++){
inputs[i].disabled=true;
}
A working example:
$().ready(function() {
$('#clicker').click(function() {
$('input').each(function() {
if ($(this).attr('disabled')) {
$(this).removeAttr('disabled');
}
else {
$(this).attr({
'disabled': 'disabled'
});
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<input type='text'></input>
<input type='text'></input>
<input type='text'></input>
<div id='clicker' style='background-color:#FF0000; height:40px; width:100px;'></div>
Here is a function to toggle all inputs on the page:
function toggle_inputs() {
var inputs = document.getElementsByTagName('input');
for (var i = inputs.length, n = 0; n < i; n++) {
inputs[n].disabled = !inputs[n].disabled;
}
}
It works by using the logical NOT operator (the exclamation point), which returns the opposite of the operand. For example, !true will return false. So by using !inputs[n].disabled, it will return the opposite of what it's currently set to, thereby toggling it.
If you need code to bind the click event to the button:
document.getElementById('your_button_id').onclick = toggle_inputs;
You can also use addEventListener, but see the linked page for more information, including compatibility with Internet Explorer. The code I gave above should work across all browsers with no trouble.
for (var i = 0; i < document.getElementyByTagName('input').length; i++) {
document.getElementsByTagName('input')[i].disabled = 'disabled';
}
http://code.google.com/p/getelementsbyclassname/
^^Robert Nyman has a "get elements by class" script. Basically you'd just assign all those input elements to the same class, and then do something like:
//Collapse all the nodes
function collapseNodesByClass(theClass){
var nodes = getElementsByClassName(theClass);
for(i = 0; i < nodes.length; i++){
nodes[i].style.display='none';
}
}
This is a piece of code I'm actually currently using to collapse everything with a given class name (it uses the script I mentioned above). But in any case I think the key to your problem is being able to refer to multiple elements at once, which that script will help you with.
Also the link in your question didn't work for me :(.
I'm a bit of a novice when it comes to Javascript, but I've managed to create this script which 'greys out' text and inputs found in a div. It accepts a boolean (show) to declare whether the elements are being hidden or reshown, as well as the name of the div(s) to hide.
It works exactly as intended in Chrome and Firefox, but IE won't do a thing. Through 'debugging' using alerts, I think the issue lies with this line:
var div = document.getElementsByName(divName);
...of the following code:
function hideAndShow(show, divName) {
var hideColor = "#DFDFDF";
// Find all matching divs and loop through
var div = document.getElementsByName(divName);
for (var count1 = 0; count1 < div.length; count1++) {
// Find and loop through all elements in div
var elements = div[count1].getElementsByTagName("*");
for (var count2 = 0; count2 < elements.length; count2++) {
if (elements[count2].tagName == "TEXTAREA" || elements[count2].tagName == "INPUT") {
elements[count2].disabled = !show; //Disable
elements[count2].style.borderColor = (show) ? "" : hideColor; // Change border colour
elements[count2].value = ""; //Clear existing text
}
}
// Change the colour of anything left, such as text
div[count1].style.color = (show) ? "" : hideColor;
alert(div[count1].id);
}
}
Can anybody please help or point me in the right direction? I'm stumped!
It's possible that IE is getting confused by your page: http://www.romantika.name/v2/javascripts-getelementsbyname-ie-vs-firefox/
afaik the IE implementation of getElementsByName actually searches on id
In IE7 at least:
// works in IE but not Chrome
<div id="test"></div>
alert(document.getElementsByName('test').length);
// doesn't work in IE, works in Chrome
<div name="test"></div>
alert(document.getElementsByName('test').length);
Libraries like jQuery deal with all this nonsense for you and make selecting DOM elements trivial.
If you want to do it in pure JS, you might want to look at providing an implementation of getElementsByClassName (see here for an example) to solve the problem.