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 :(.
Related
Might be a strange setup, but I have a number of hyperlinks on the page with the same id (yeah, I know, but it was not my choice and I cannot change that at this time plus those hyperlinks are generated dynamically).
Example:
<div id="Links">
<div class="myItem">Some text</div>
<div class="myItem">More text</div>
<div class="myItem">Even more text</div>
</div>
Now I need to attach javascript to those links dynamically (the hyperlinks are also dynamically generated). The easiest way I see is by getting all hyperlinks on the page and then check the hyperlink id to ensure I only take care of those that have id of "myLink" (I have many other hyperlinks on the page).
I thought of using getElementById but that would only grab the first element with the specified id.
am attaching javascript to those links using the following:
window.onload = function() {
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
if (anchor.id='myLink')
{
if (anchor.getAttribute("LinkID") != null)
{
anchor.onclick = function() {
MyFunction(this.getAttribute("LinkID"), false);
return false;
}
}
}
}
}
The above function works fine, but it creates another issue - affects the styling of other hyperlinks on the page. So I was wondering if there is a way to accomplish the same thing but without affecting other elements on the page?
This is more modern and corrects your equality test:
window.onload = function() {
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
if (anchor[i].id==='myLink' && anchor[i].getAttribute("LinkID") !== null)
{
anchor[i].addEventListener("click", function() {
MyFunction(this.getAttribute("LinkID"), false);
}
}
}
}
Even with your original code, I don't see anything that would interfere with styling in the code. Can you elaborate as what styling changes you were getting?
You can use an attribute selector and document.querySelector([id=<id>]) pretty reliably depending on your browser support situation: http://codepen.io/anon/pen/YwLdKj
Then, of course, loop through that result and make subsequent changes or event bindings.
If not, you could use jQuery (referenced in above code pen).
You might also use JavaScript event delegation and listen for all click events, check if the user is clicking a link with the correct id.
If a combination of tag == 'a', class == "myItem" and presence of a LinkID attribute is sufficient to identify nodes requiring a click handler they could be identified using multiple CSS selectors. If this is not possible however, a query selector not using id can create a list of nodes to be checked for id, as for example:
function callMyFunction()
{ MyFunction(this.getAttribute("LinkID"), false);
}
function addClickHandlers()
{ var list = document.querySelectorAll("a[LinkID]")
var i, node;
for( i = 0; i < list.length; ++i)
{ node = list[i];
if(node.id == "myLink")
{ node.onclick=callMyFunction;
}
}
}
See also running a selector query on descendant elements of given node if of interest.
I know, it's not supported by IE, but I found a cool script online that someone was generous enough to provide for free, but I can't figure out why it's not working. I've been staring at this for hours, please point me in the right direction!
My code:
<script language="javascript" type="text/javascript" src="getbyclass.js"></script>
<script type="text/javascript" language="javascript">
function editToggle(toggle){
if (toggle == "off"){
getElementsByClassName("editp").style.display ="none";
document.getElementById('editToggle').innerHTML=">Edit Mode: <span style=\"color:red;\">OFF</span>";
toggle="on";
}else{
getElementsByClassName("editp").style.display ="inline";
document.getElementById('editToggle').innerHTML=">Edit Mode: <span style=\"color:green;\">on</span>";
toggle="off";
}
}
also:
echo "<span id=\"editToggle\">Edit Mode: <span style=\"color:red;\">OFF</span></span>";
The code from getbyclass.js can be seen here.
In response to the answers below, I've tried this:
function editToggle(toggle){
var list = getElementsByClassName("editp");
if (toggle == "off"){
//getElementsByClassName("editp").style.display ="none";
for (index = 0; index < list.length; ++index) {
list[index].style.display ="none";
}
document.getElementById('editToggle').innerHTML=">Editfalse;\">Edit Mode: <span style=\"color:red;\">OFF</span>";
toggle="on";
}else{
//getElementsByClassName("editp").style.display ="inline";
for (index = 0; index < list.length; ++index) {
list[index].style.display ="inline";
}
document.getElementById('editToggle').innerHTML=">Editfalse;\">Edit Mode: <span style=\"color:green;\">on</span>";
toggle="off";
}
}
But it's still not working.
getElementsByClassName returns a collection. You might need to loop through the results, like this:
var elements = document.getElementsByClassName('editp');
for(var i=0; i<elements.length; i++) {
elements[i].style.display='none';
}
elements is a live NodeList of found elements in the order they appear in the tree.
names is a string representing the list of class names to match; class names are separated by whitespace
getElementsByClassName can be called on any element, not only on the document. The element on which it is called will be used as the root of the search.
Should go through this.
getElementsByClassName returns a NodeList (or an array if it's not built-in), but you're using it as though it were an HTMLElement by referring directly to a style property on it:
getElementsByClassName("editp").style.display ="none";
// here ------------------------^
You should be seeing an error in the JavaScript console, since you're trying to retrieve the property display from undefined (since getElementsByClassName("editp").style will be undefined).
If you want to act on the first matching element:
var elm = getElementsByClassName("editp")[0];
if (elm) {
elm.style.display ="none";
}
...or if you want to act on all of them:
var index;
var list = getElementsByClassName("editp");
for (index = 0; index < list.length; ++index) {
list[index].style.display ="none";
}
Update:
At some point, you edited the question and removed var toggle = "off" from the code (at global scope, just above the function) and made toggle an argument to editToggle. But you're not passing anything into editToggle according to your quoted markup, and even if you were, setting toggle to a new value within the function won't have any lasting effect if it's a function argument, as nothing refers to it after the function returns.
There may be unterminated string literals in the markup you create. It also appears there may be other issues as mentioned in other posts.
Change:
"Edit Mode: <span style=\"color:red;>OFF</span>";
to
"Edit Mode: <span style=\"color:red;\">OFF</span>";
This situation is also present in the other markup you create.
Change:
"Edit Mode: <span style=\"color:green;>on</span>";
to
"Edit Mode: <span style=\"color:green;\">on</span>";
You seem to have a missing semicolumn after var toggle="off".
Make sure that you call editToggle() somewhere in your code.
I advise you to use inspectors built into browsers or extensions. For example Firebug extension for Firefox or Chrome Inspector. Use the console to debug and see if there are errors in your javascript.
I'm attempting to add target="_blank" to links on a page depending on a checkbox click.
On the javascript side I have:
function newTab(v) {
if(v.tab.checked == true) {
document.getElementsByTagName('a').setAttribute('target', '_blank');
} else {
document.getElementsByTagName('a').setAttribute('target', '_self');
}
} //end function
And on the HTML side I have:
<form>
<input type="checkbox" name="tab" onclick="newTab(this.form)" />
<label>Open Links In New Tab?</label>
</form>
Gmail
Naturally it isn't as simple as I thought it would be, so it doesn't work.
The page contains over a dozen links so I need the checkbox to apply to all links on the page - why I used getElementsByTagName(). Any help appreciated!
EDIT:
Code that works is as follows:
function newTab(f) {
var els = document.getElementsByTagName('a'); //read anchor elements into variable
if(f.tab.checked == true) { //If the box is checked.
for (var i in els) {
els[i].setAttribute('target', '_blank'); //Add 'target="blank"' to the HTML
}
} else { // not checked...
for (var i in els) {
els[i].setAttribute('target', '_self'); //Add 'target="self" to HTML
}
}
} //end function.
getElementsByTagName() returns a nodeset. You need to iterate over it and apply the change to each one in turn. What you currently have is more like jQuery syntax, which handles this internally for you.
This would have shown up in the console. With JS issues, always check the console before wondering what's wrong.
var els = document.getElementsByTagName('p');
for (var i=0, len = els.length; i<len; i++)
els[i].setAttribute('name', 'value');
Also, with checkboxes use change, not click events, as someone might toggle them via the keyboard, not mouse. Lastly, you should look into handling your events centrally, not inline DOM-zero events specified in the HTML. Numerous reasons for this that are beyond the scope of this question.
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.
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;
});
});
});