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.
Related
So I have a site that is using a select menu for the mobile navigation. I'm needing to hide a few options from the list, and have been able to so on all browsers and devices except for Safari and iPhone.
Here's the css I used to remove items 7-11 on the list:
select.select-menu option:nth-child(n+7):nth-child(-n+11){
display: none !important;}
This is working as expected in Chrome and on my android phone. However, when you view the site in Safari or on an iPhone the options are not hidden and still show up.
I've tried several options and done a lot of research on the matter and can't find a solution. I tried removing items from the list using jQuery and couldn't get that to work either.
Is there a way I can hide the options on iPhone and Safari as well?
EDIT:
Here's a fiddle:
https://jsfiddle.net/cv6rubua/3/
Only this works for me - wrap in element you need to hide it. "if-check" for not wrapping it twice if hiding connected with some action on page.
Hide for iOS with jQuery:
if( !($(this).parent().is('span')) ) $(this).wrap('<span>');
Unhide for iOS with jQuery:
if( ($(this).parent().is('span')) ) $(this).unwrap();
With Jquery you can use prop("disabled", true) together with hide(). Like this:
$(this).prop("disabled", true); // for safari
$(this).hide();
This way options will be hidden in most browsers. In Safari they will be visible but disabled.
I think this is a nice alternative.
I also had difficulties in Safari while trying to hide option in my select (from an extension) and decided to go this route.
To "hide" the option in my select I replace the option with div, and then back again to option if I want to show it again.
//if any div exists change back to option
function showAll(){
var nodesSnapshot = document.evaluate("//select/div", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < nodesSnapshot.snapshotLength; i++) {
var nodeA = nodesSnapshot.snapshotItem(i);
var elemA = document.createElement('option');
elemA.innerHTML = nodeA.innerHTML;
nodeA.parentNode.replaceChild(elemA, nodeA);
}
}
//replace all option that contain text with div
function hideSome(){
var nodesSnapshot = document.evaluate("//select/option[text()[contains(.,'HideMe')]]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < nodesSnapshot.snapshotLength; i++) {
var nodeA = nodesSnapshot.snapshotItem(i);
var elemA = document.createElement('div');
elemA.innerHTML = nodeA.innerHTML;
nodeA.parentNode.replaceChild(elemA, nodeA);
}
}
//replace all option with div
function hideAll(){
var nodesSnapshot = document.evaluate("//select/option", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < nodesSnapshot.snapshotLength; i++) {
var nodeA = nodesSnapshot.snapshotItem(i);
var elemA = document.createElement('div');
elemA.innerHTML = nodeA.innerHTML;
nodeA.parentNode.replaceChild(elemA, nodeA);
}
}
<button onclick="showAll();">showAll</button>
<button onclick="hideSome();">hideSome</button>
<button onclick="hideAll();">hideAll</button>
<select>
<option>HideMe</option>
<option>HideMe</option>
<option>ShowMe</option>
<option>HideMe</option>
<option>ShowMe</option>
</select>
I found that removing the items rather than hiding them is easier.
$(this).remove();
You can solve this using JavaScript
var selectOption = document.querySelectorAll('.select-menu option');
for (var i = 0; i < selectOption.length; i++) {
var item = selectOption[i];
if (item.innerHTML.charAt(0) === "–") {
item.remove();
};
}
You have a number of options depending on what you want, from I have found display: none does not work on safari so here is an alternative method:
You can simply make it super small and invisible:
opacity: 0;
height: 0;
width: 0;
overflow: hidden;
This should work well, and should be supported by both chrome and safari!
Good luck!
You can't. Safari uses an overlay for dropdowns... You literally have to remove them.... There is a hack using spans as non-valid syntax... Wouldn't recommend using invalid syntax though
The solution that worked for me was to create another hidden select which all the options, and clone the relevant ones to the visible select. this way you display one the options you want to display but still keep a record of the other options in a hidden list.
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.
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.
so I'm writing an interface for updating and displaying a database table, and each row displayed on the client-side (using DataTables) has an "Edit" and "Delete" button. Every time you click on a single row's Edit, all the Edit and Delete buttons in other rows are disabled. This is the Javascript code I use to do it:
var editButtons = document.getElementsByName("EditRow");
var deleteButtons = document.getElementsByName("DeleteRow");
for (i in editButtons) {
editButtons[i].disabled = true;
}
for (i in deleteButtons) {
deleteButtons[i].disabled = true;
}
This works fine with Chrome and Firefox, but when I try it in IE9, it doesn't disable anything. I've tried many things to solve this, including grabbing the DOM objects using jQuery, but nothing has worked. Any help is appreciated.
document.getElementsByName returns a node list, which is Array-like. You should treat it as such:
var elements = document.getElementsByName('something'),
len = elements.length;
for (var i = 0; i < len; i++) {
elements[i].disabled = true;
}
Your example doesn't work in IE9, but this does:
Array.prototype.forEach.call(document.getElementsByName('EditRow'), function(el){
el.disabled = true;
});
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 :(.