I am looking for a way to Show/ Hide some of the Radio buttons of a Radio button group using JavaScript.
How can this be achieved?
Thanks
The id attribute identifies the individual radio buttons. All of them will be related to the group by the name attribute
You can get the individual radio buttons using something like
var rbtn = document.getElementById('radioButton1');
Then set the display or visibility style to hide or show.
rbtn.style.display = 'none'; // 'block' or 'inline' if you want to show.
document.getElementById('myRadioButtonId').style.display = 'none'; //hide it
document.getElementById('myRadioButtonId').style.display = 'block'; //show it
That's a very generic question, so I can only offer a very generic answer. Using jQuery, for example:
$("#some-selector .of-some-kind .for-the-things-you-wish-to-hide").hide();
Of course, what you're selecting, and under what circumstances you want to hide it can dramatically impact the best way to go about the problem.
Apply a CSS class to the radiobuttons then use a loop to set the display = 'none' for each radiobutton.
Firstly, we need a cross-browser getElementsByClassName function
/*
Developed by Robert Nyman, http://www.robertnyman.com
Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/
var getElementsByClassName = function (className, tag, elm){
if (document.getElementsByClassName) {
getElementsByClassName = function (className, tag, elm) {
elm = elm || document;
var elements = elm.getElementsByClassName(className),
nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
returnElements = [],
current;
for(var i=0, il=elements.length; i<il; i+=1){
current = elements[i];
if(!nodeName || nodeName.test(current.nodeName)) {
returnElements.push(current);
}
}
return returnElements;
};
}
else if (document.evaluate) {
getElementsByClassName = function (className, tag, elm) {
tag = tag || "*";
elm = elm || document;
var classes = className.split(" "),
classesToCheck = "",
xhtmlNamespace = "http://www.w3.org/1999/xhtml",
namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
returnElements = [],
elements,
node;
for(var j=0, jl=classes.length; j<jl; j+=1){
classesToCheck += "[contains(concat(' ', #class, ' '), ' " + classes[j] + " ')]";
}
try {
elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
}
catch (e) {
elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
}
while ((node = elements.iterateNext())) {
returnElements.push(node);
}
return returnElements;
};
}
else {
getElementsByClassName = function (className, tag, elm) {
tag = tag || "*";
elm = elm || document;
var classes = className.split(" "),
classesToCheck = [],
elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
current,
returnElements = [],
match;
for(var k=0, kl=classes.length; k<kl; k+=1){
classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
}
for(var l=0, ll=elements.length; l<ll; l+=1){
current = elements[l];
match = false;
for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
match = classesToCheck[m].test(current.className);
if (!match) {
break;
}
}
if (match) {
returnElements.push(current);
}
}
return returnElements;
};
}
return getElementsByClassName(className, tag, elm);
};
then use like so
var radioButtons = getElementsByClassName('myClassName', 'input');
var len = radioButtons.length;
for (var i = 0; i < len; i++)
radioButtons[i].style.display = 'none';
Everybody else has nailed it, so I'll put in a plug for the frameworks.
Using jquery or mootools or another framework makes this super easy:
MooTools:
$$('input[name=myRadioName]).setStyle('display','none');
or
$$('input[name=myRadioName]).fade('out');
You can try something like
<span id="myspan"><input id="radioButton1" type="radio" />Some label goes here</span>
Then
document.getElementById('myspan').style.display="none"; //inline or block to display again
If you are using JQuery then
$('myspan').hide(); // show() to display again
Related
I wan to collect all text from a list of elements obtains using
var elements =document.body.getElementsByTagName("*");
What I've done so far:
var text = '';
for (var i = 0; i < elements.length; i++) {
text = text + ' ' + elements[i].innerText
}
This will return duplicated text because it get the own text of each element plus its children's. I want to know if there is a way to get element's owntext using pure javasript?
I think the issue is that nested matching elements of a particular tag are being counted twice. The solution is to check if we've already visited a parent element and to skip the child if that's the case.
var text = '';
var visited = [];
for (var i = 0; i < elements.length; i++) {
var found = false;
for (var e = elements[i]; e != null; e = e.parentNode) {
if (visited.indexOf(e) > -1) {
found = true;
break;
}
}
if (!found) {
text = text + ' ' + elements[i].innerText;
visited.push(elements[i]);
}
}
http://jsfiddle.net/h8k0xx82/
I have this little javascript to add some classes to some hyperlinks to give them a nice effect. It works on any links inside an element with the class linkroll. However, when the link is nested within some elements and div's, it doesnt apply the effect. I am finding that querySelectorAll is not very consistent.
I was thinking if I rewrite this and use something like jQuery's each() function, I may have better results. Here's how it looks now:
var supports3DTransforms = document.body.style['webkitPerspective'] !== undefined || document.body.style['MozPerspective'] !== undefined;
function linkify() {
if (supports3DTransforms) {
var selector = '.linkroll a';
var nodes = document.querySelectorAll(selector);
for (var i = 0, len = nodes.length; i < len; i++) {
var node = nodes[i];
var sibling = node.nextSibling; // Do not apply to images
if (sibling.nodeName != "img") {
if (!node.className || !node.className.match(/roll/g)) {
node.className += ' roll';
node.innerHTML = '<span data-title="' + node.text + '">' + node.innerHTML + '</span>';
}
}
};
}
}
linkify();
How could I possibly rewrite document.querySelectorAll(selector); and use something like jQuery's each() instead?
Try this:
var supports3DTransforms = $('body').css('-webkit-perspective') !== undefined || $('body').css('MozPerspective') !== undefined;
function linkify() {
if (supports3DTransforms) {
$('.linkroll a').each(function (i, el) {
var $el = $(el),
$sibling = $el.next();
!$sibling.is('img') && !$el.hasClass('roll') && $el.addClass('roll').wrap('<span data-title="' + $el.text() + '"></span>');
});
}
}
linkify();
Example fiddle
Is it possible to generate the most specific XPath expression automatically from the position of the cursor on the web page?
The XPath expression would change with "onMouseMove event".
If it's possible, how would you implement it? Or is it already implemented in some Javascript or Python library? I would prefer it in Python with a combination of some web library but Javascript would be good and acceptable too.
See the Get XPath thread in DZone Snippets for finding the XPath. See the How do I check if the mouse is over an element in jQuery? question here for identifying when the mouse cursor is over an element.
I have answered an almost identical question (using jQuery) at Return XPath location with jQuery? Need some feedback on a function
If you change the click event to mouseenter you would have what you ask for..
$(document).delegate('*','mouseenter',function(){
var path = $(this).parents().andSelf();
var xpath='/';
for (var i = 0; i < path.length; i++)
{
var nd = path[i].nodeName.toLowerCase();
xpath += '/';
if (nd != 'html' && nd != 'body')
{
xpath += nd;
if (path[i].id != '')
{
xpath += '#' + path[i].id;
}
else
{
xpath += '['+ ($(path[i-1]).children().index(path[i])+1) +']';
}
if (path[i].className != '')
xpath += '.' + path[i].className;
}
else
{xpath += nd;}
}
$('#xpath').html(xpath); // show the xpath in an element with id xpath..
return false;
});
Demo at http://jsfiddle.net/gaby/hsv97/25/
Update with no jQuery used.. (for modern browsers)
function getXpath(event){
var hierarchy = [],
current = event.srcElement||event.originalTarget;
while (current.parentNode){
hierarchy.unshift(current);
current = current.parentNode;
}
var xPath = hierarchy.map(function(el,i){
return el.nodeName.toLowerCase() + ((el.id !== '') ? '#'+el.id : '') + ((el.className !== '') ? '.'+el.className.split(' ').join('.') : '');
}).join('/');
document.getElementById('xpath').innerHTML = xPath;
return xPath;
}
if (document.addEventListener){
document.addEventListener('mouseover', getXpath, false);
} else {
document.onmouseover = getXpath;
}
Demo at http://jsfiddle.net/gaby/hsv97/29/
vanilla javascript (with indices) http://jsfiddle.net/nycu2/1/
function nodeindex(element, array) {
var i,
found = -1,
element_name = element.nodeName.toLowerCase(),
matched
;
for (i = 0; i != array.length; ++i) {
matched = array[i];
if (matched.nodeName.toLowerCase() === element_name) {
++found;
if (matched === element) {
return found;
}
}
}
return -1;
}
function xpath(element, suffix) {
var parent, child_index, node_name;
parent = element.parentElement;
if (parent) {
node_name = element.nodeName.toLowerCase();
child_index = nodeindex(element, parent.children) + 1;
return xpath(parent, '/' + node_name + '[' + child_index + ']' + suffix);
} else {
return '//html[1]' + suffix;
}
}
function xpathstring(event) {
var
e = event.srcElement || event.originalTarget,
path = xpath(e, '');;
document.querySelector('.xpathresult').value = path;
highlight();
}
I am having issues figuring out how to resolve the getElementsByClassName issue in IE. How would I best implement the robert nyman (can't post the link to it since my rep is only 1) resolution into my code? Or would a jquery resolution be better? my code is
function showDesc(name) {
var e = document.getElementById(name);
//Get a list of elements that have a class name of service selected
var list = document.getElementsByClassName("description show");
//Loop through those items
for (var i = 0; i < list.length; ++i) {
//Reset all class names to description
list[i].className = "description";
}
if (e.className == "description"){
//Set the css class for the clicked element
e.className += " show";
}
else{
if (e.className == "description show"){
return;
}
}}
and I am using it on this page dev.msmnet.com/services/practice-management to show/hide the description for each service (works in Chrome and FF). Any tips would be greatly appreciated.
I was curious to see what a jQuery version of your function would look like, so I came up with this:
function showDesc(name) {
var e = $("#" + name);
$(".description.show").removeClass("show");
if(e.attr("class") == "description") {
e.addClass("show");
} else if(e.hasClass("description") && e.hasClass("show")) {
return;
}
}
This should support multiple classes.
function getElementsByClassName(findClass, parent) {
parent = parent || document;
var elements = parent.getElementsByTagName('*');
var matching = [];
for(var i = 0, elementsLength = elements.length; i < elementsLength; i++){
if ((' ' + elements[i].className + ' ').indexOf(findClass) > -1) {
matching.push(elements[i]);
}
}
return matching;
}
You can pass in a parent too, to make its searching the DOM a bit faster.
If you want getElementsByClassName('a c') to match HTML <div class="a b c" /> then try changing it like so...
var elementClasses = elements[i].className.split(/\s+/),
matchClasses = findClass.split(/\s+/), // Do this out of the loop :)
found = 0;
for (var j = 0, elementClassesLength = elementClasses.length; j < elementClassesLength; j++) {
if (matchClasses.indexOf(elementClasses[j]) > -1) {
found++;
}
}
if (found == matchClasses.length) {
// Push onto matching array
}
If you want this function to only be available if it doesn't already exist, wrap its definition with
if (typeof document.getElementsByClassName != 'function') { }
Even easier jQuery solution:
$('.service').click( function() {
var id = "#" + $(this).attr('id') + 'rt';
$('.description').not(id).hide();
$( id ).show();
}
Why bother with a show class if you are using jQuery?
Heres one I put together, reliable and possibly the fastest. Should work in any situation.
function $class(className) {
var children = document.getElementsByTagName('*') || document.all;
var i = children.length, e = [];
while (i--) {
var classNames = children[i].className.split(' ');
var j = classNames.length;
while (j--) {
if (classNames[j] == className) {
e.push(children[i]);
break;
}
}
}
return e;
}
I used to implement HTMLElement.getElementByClassName(), but at least Firefox and Chrome, only find the half of the elements when those elements are a lot, instead I use something like (actually it is a larger function):
getElmByClass(clm, parent){
// clm: Array of classes
if(typeof clm == "string"){ clm = [clm] }
var i, m = [], bcl, re, rm;
if (document.evaluate) { // Non MSIE browsers
v = "";
for(i=0; i < clm.length; i++){
v += "[contains(concat(' ', #"+clc+", ' '), ' " + base[i] + " ')]";
}
c = document.evaluate("./"+"/"+"*" + v, parent, null, 5, null);
while ((node = c.iterateNext())) {
m.push(node);
}
}else{ // MSIE which doesn't understand XPATH
v = elm.getElementsByTagName('*');
bcl = "";
for(i=0; i < clm.length; i++){
bcl += (i)? "|":"";
bcl += "\\b"+clm[i]+"\\b";
}
re = new RegExp(bcl, "gi");
for(i = 0; i < v.length; i++){
if(v.className){
rm = v[i].className.match(bcl);
if(rm && rm.length){ // sometimes .match returns an empty array so you cannot use just 'if(rm)'
m.push(v[i])
}
}
}
}
return m;
}
I think there would be a faster way to iterate without XPATH, because RegExp are slow (perhaps a function with .indexOf, it shuld be tested), but it is working well
You can replace getElementsByClassName() with the following:
function getbyclass(n){
var elements = document.getElementsByTagName("*");
var result = [];
for(z=0;z<elements.length;z++){
if(elements[z].getAttribute("class") == n){
result.push(elements[z]);
}
}
return result;
}
Then you can use it like this:
getbyclass("description") // Instead of document.getElementsByClassName("description")
I have system-generated links which I hide manually. Now I want to remove the link's title attributes sicne those are copied when the user copies surrounding text.
<html>
<head>
<script type="text/javascript">
var getElementsByClassName = function (className, tag, elm){
if (document.getElementsByClassName) {
getElementsByClassName = function (className, tag, elm) {
elm = elm || document;
var elements = elm.getElementsByClassName(className),
nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
returnElements = [],
current;
for(var i=0, il=elements.length; i<il; i+=1){
current = elements[i];
if(!nodeName || nodeName.test(current.nodeName)) {
returnElements.push(current);
}
}
return returnElements;
};
}
else if (document.evaluate) {
getElementsByClassName = function (className, tag, elm) {
tag = tag || "*";
elm = elm || document;
var classes = className.split(" "),
classesToCheck = "",
xhtmlNamespace = "http://www.w3.org/1999/xhtml",
namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
returnElements = [],
elements,
node;
for(var j=0, jl=classes.length; j<jl; j+=1){
classesToCheck += "[contains(concat(' ', #class, ' '), ' " + classes[j] + " ')]";
}
try {
elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
}
catch (e) {
elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
}
while ((node = elements.iterateNext())) {
returnElements.push(node);
}
return returnElements;
};
}
else {
getElementsByClassName = function (className, tag, elm) {
tag = tag || "*";
elm = elm || document;
var classes = className.split(" "),
classesToCheck = [],
elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
current,
returnElements = [],
match;
for(var k=0, kl=classes.length; k<kl; k+=1){
classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
}
for(var l=0, ll=elements.length; l<ll; l+=1){
current = elements[l];
match = false;
for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
match = classesToCheck[m].test(current.className);
if (!match) {
break;
}
}
if (match) {
returnElements.push(current);
}
}
return returnElements;
};
}
return getElementsByClassName(className, tag, elm);
};
function notitle() {
var mylist=document.getElementsByClassName("notitle");
for (j=0; j<mylist.length; j++) {
var listitems= mylist[j].getElementsByTagName("a");
for (i=0; i<listitems.length; i++) {
listitems[i].removeAttribute("title");
}
}
}
</script>
</head>
<body onLoad="notitle()">
<p>Before hidden link 1: <span class="notitle" style="display: none;">
This link should have no title attribute
</span>After hidden link 1.</p>
<p>Before hidden link 2: <span class="notitle" style="display: none;">
This link should have no title attribute
</span>After hidden link 2.</p>
<p>Before hidden link 3: <span class="notitle" style="display: none;">
This link should have no title attribute
</span>After hidden link 3.</p>
</body>
</html>
How should the function look like correctly?
I once got it working using this
function notitle() {
var mylist=document.getElementById("notitle");
var listitems= mylist.getElementsByTagName("a");
for (i=0; i<listitems.length; i++) {
listitems[i].removeAttribute("title");
}
}
but that only applied to the first link.
that is because you should't give the same id attribute to multiple elements. The id attribute must be unique all over your document. if not it only finds the first element with this id.
try class="notitle" instead of id="notitle" and you JS should look like this:
function notitle() {
var mylist=document.getElementsByClassName("notitle");
for (j=0; j<mylist.length; j++) {
var listitems= mylist[j].getElementsByTagName("a");
for (i=0; i<listitems.length; i++) {
listitems[i].removeAttribute("title");
}
}
}
As I've just learned this would not work cross browser, I would suggest to use a Javascript framework for this kind of propblem, because such a framework is crossbrowser compatible.
You can add the following script to your website to make it work in all browsers:
http://code.google.com/p/getelementsbyclassname/downloads/detail?name=getElementsByClassName-1.0.1.js
It's far easier if you would use some JavaScript Framework. Here an example for jQuery:
function notitle() {
$(".notitle a").removeAttr("title");
}
Your approach is correct but you're using the same id multiple times. Either make sure the id's are different, or use a generic class name and retrieve the elements that way.