Show/Hide <div> - Now working in IE

Script Code


function showHideField(fieldId,tag)
{
	var obj = getRefById(fieldId);
	if(tag == 1)
	{
		obj.style.visibility = (obj.style.visibility == 'hidden')?'visible':'hidden';
	}
	else if(tag == 2)
	{
		obj.style.visibility = (obj.style.visibility == 'hidden')?'visible':'hidden';
		obj.style.display = (obj.style.display == 'none')?'inline':'none';
	}
	else
	{
		obj.style.display = (obj.style.display == 'none')?'inline':'none';
	}
}

HTML


<a href="#case_{$value.ID}" onClick="javascript:showHideField('case_1',2);">+</a>
<div id="case_1" style="visibility:hidden;display:none;">
Some Text
</div>

Working in FireFox but not in IE

You don’t need to have “javascript:” in an onclick attribute, that might be a problem. Normally to show a <div>, you set style.display=“block”, not style.display=“inline”.

Why are you setting visibility and display? Wouldn’t just display do what you need?

Also, how is getRefById defined? Have you checked it works in IE? Why don’t you just use document.getElementById(), or Prototype’s $() function?

Douglas

I dont know what $() function?

I was just testing to see what would work as I am not expert in Javascript.

getRefById function


function getRefById(id)
{
	var ref = (document.getElementById && !document.all)?document.getElementById(id):
			((document.all)?document.all[id]:((document.layers)?document.layers[id]:null));
	return ref;
}

you are right. its not returning the object reference in IE.

Can you please tell how to do that? I have posted the function which I use to get ID Reference in IE.

It looks like getRefById contains browser-detection code. There is no need for that nowadays, unless you still support Netscape 4.0 (hay, it’s only 10 years old…) so just use the W3C methods instead.

Just use this:

function getRefById(id)
{
	return document.getElementById(id);
}

Many people think that “document.getElementById” is too long (as in the number of characters you have to type in) for every-day use, so in the modern Javascript libraries, a function like this is often defined:

function $(elementOrId) {
  if (typeof elementOrId == 'string') {
    return document.getElementById(elementOrId);
  } else {
    return elementOrId;
  }
}

Just calling $(“my-element”) is nice and short.

It is becoming something of a standard. One advantage over the getRefById method, is that you can use elements and IDs interchangeably with $(). It means that you can write functions which accept elements, but you can also call them directly with an element ID, which is often handy.

Prototype is a useful Javascript library, which adds useful things to the language. Get it here: http://www.prototypejs.org/

Regards,
Douglas

thanks its working now.

I don’t want to open a new thread, but is there a way to show ALL the <div> the same time?
let’s say i have 3 divs (and 1 embedded for each)


<div id="div_1">
 Some Text 1
 <div id="div_in_1">
  Insider 1
 </div>
</div>
<div id="div_2">
 Some Text 2
 <div id="div_in_2">
  Insider 2
 </div>
</div>
<div id="div_2">
 Some Text 2
 <div id="div_in_2">
  Insider 2
 </div>
</div>

So, is there a way to open ALL the <div> simultaneously?

I am generating this page dynamically in case I need to have them add in a function on the fly.

Yes, it’s possible to show all of them at the same time. How to do that would depend on what your function looks like now.

I wouldn’t bother setting the visibility property.

A also would suggest not setting the display property to “inline”. I’d set it to an empty string instead (“”).

It’s best to avoid using inline event handlers. I suggest you read up on Unobtrusive JavaScript and other JavaScript Best Practices.

No, it contains object detection code. There’s a difference.

Yes, functions like that are obsolete. Besides document.layers doesn’t work like document.all in all situations, so unless you actually test in Netscape 4.x including it in your code is just plain silly.

So, what would you suggest?

Is there something like unlimited parameters without defining them?

so, I can do something like


function showHideArr()
{
  loop through array 
   showHideField(id[i]);
}

if it is, is it a good idea to do that or is there some better way?

Yes, you could use the arguments object.

wonderful.

just one last question. there might come a point that I have to pass 50 arguments to the function and process them.

Would it have any impact on the performance?
[offtopic]
BTW, framework at http://www.prototypejs.org/ you mentioned, how deep and useful it is? i assume you have used it so how much helpful was it?
[/offtopic]

It may use that mechanism, but the intent clearly is browser detection. If not, first condition would contain only one object check, looking for document.getElementById, not this more complex condition:

document.getElementById && !document.all

there might come a point that I have to pass 50 arguments to the function and process them

In that case, it might be easier to give them a class name, and look for them like this:

function showHide(className, parentElement)
{
  var parentElement = parentElement || document;
  var divs = parentElement.getElementsByTagName("div");
  for (var i = 0; i < divs.length; i++) {
    if (divs[i].className == className) {
      showHideField(divs[i]);
    }
  }
}

This gets all the divs in the document, (or divs inside parentElement if you know where they are, to save going through the shole page), and then call showHideField on the ones with the correct className.

So, you could call it like this:

showHide("showHideContents");

And, yes, I do find Prototype useful. For example, it contains a getElementsByClassName method, which you could use to simplify the above code. (Though internally it still uses getElementsByTagName and an if(className).)

hth,
Douglas

Thanks.
But, can you elaborate className?

in my example that I showed above, what would be the className??

do you mean that I use <div class=“className”> rather than <div id=“idName”>??

if yes, then how would i still implement individual display without an id name??

or should I use BOTH?

Yes, that would work. Another option would be to use class names instead of div_in_n, and then just use id’s on the div_n divs. For example:

<div id="div_top">
<div id="div_1">
 Some Text 1
 <div class="div_in">
  Insider 1
 </div>
</div>
<div id="div_2">
 Some Text 2
 <div class="div_in">
  Insider 2
 </div>
</div>
<div id="div_3">
 Some Text 3
 <div class="div_in">
  Insider 3
 </div>
</div>
</div>

Then you could expand the second one using:

var div = document.getElementById("div_2");
toggleFields(div, "div_in", true);

Or expand them all using:

var div = document.getElementById("div_top");
toggleFields(div, "div_in", true);

toggleFields is defined like this:

function toggleField(el, show) {
  if (show) {
    el.style.display = "";
  } else {
    el.style.display = "none";
  }
}

function toggleFields(parentElement, className, show) {
  var parentElement = parentElement || document;
  var divs = parentElement.getElementsByTagName("div");
  for (var i = 0; i < divs.length; i++) {
    if (divs[i].className == className) {
      toggleField(divs[i], show);
    }
  }
}

hth,
Douglas

wonderful.

thanks.

Just to post that I tried it and it worked.

Thanks. Thanks. Thanks