Forum Moderators: open

Message Too Old, No Replies

Javascript error in IE only?

"object expected"

         

doodlebee

7:36 pm on Jun 4, 2007 (gmt 0)

10+ Year Member



IE drives me batty. I have a script that I've used for a long time, and works rather well. I've modified it slightly (for accessibility reasons) and so far, it works in everything I've tested it in - except IE7. In Firefox (2 and 1.5) Netscape 7 & 8 and Opera 7, 8 & 9 (all on PC) it works just as it should. But I'm starting to check everything in IE (I start with 7 and go down), and the script keeps giving me an "object expected" error.

I've messed with it a bit, and apparently, it's because of my "onload" statement in the body tag. If I remove it, the error goes away, but the script still doesn't work, except now on all browsers.

If someone could take a peek for me, I'd *really* appreciate it.

So here goes:


showhideID.js

function show(id) {
var e = document.getElementById(id);
if(e.style.display == "none") {
e.style.display = "block";
}
}

function hide(id) {
var e = document.getElementById(id);
if(e.style.display == "block") {
e.style.display = "none";
}
}

I'm using a CMS, so it's dynamically called in like so:


header.php

<script type="text/javascript" src="<?php bloginfo('home');?>/contact/showhideID.js"></script>
</head>

<?php if($mailto == "email@domain.com" ¦¦ $mailto == "" ) {?>
<body id="page" onload="hide('services_inquiry');">
<?php } else {?>
<body id="page" onload="show('services_inquiry');">
<?php }?>

and later, to call in the toggle:

...
<select class="form" name="mailto">
<?php if (isset($_POST['mailto'])) echo '<option selected>'.(($_POST['mailto'])).'</option>';?>
<option class="select_option" value="">&nbsp;----------------------------</option>
<option value="general" onclick="hide('services_inquiry');">General Information</option>
<option value="services" onclick="show('services_inquiry');">Inquiry for Services</option>
</select>
</div>

<div id="services_inquiry" style="display:block;">
(stuff to show/hide here)
</div>

Now, as you can see, it's php-based CMS. So if the page is loaded and it's a freshly opened page, the section I want will be hidden until the end user selects a certain element in the dropdown box (Inquiry for Services). That element is associated in the PHP script with a certain email address. So if the dropdown selection is chosen, it'll look at the item selected (mailto) and determine whether or not to show or hide the div. If an error is thrown up, then whatever the end user selected it retained and passed on return, which will also retain the div's visibility.

I have it set onload to have it hide on initial load, because the div itself *must* have a "display" setting. I have to have it set to "block" so that, if the end user has javascript shut off, then whole form will be seen (hidden area is exposed).

So the kicker is, why, in IE, does the visibility toggle not function? It gives me an "object expected" error, but for the life of me, I can't figure out what the hell it's expecting.

Any insight would be appreciated.

[edited by: encyclo at 1:37 am (utc) on June 5, 2007]

mehh

7:46 pm on Jun 4, 2007 (gmt 0)

10+ Year Member



I modified it slightly to check id does refer to an element is an object. The only i can think of is that IE is doing a "Dry Run" of the script before it actually fires it up.

function show(id) {
var e = document.getElementById(id);
if(e¦¦e.style.display == "none") {
e.style.display = "block";
}
}

function hide(id) {
var e = document.getElementById(id);
if(e¦¦e.style.display == "block") {
e.style.display = "none";
}
}

doodlebee

8:00 pm on Jun 4, 2007 (gmt 0)

10+ Year Member



Thanks mehh -

Tried it though - but no go. Still not working :(

or...should I say..

the error is now gone (yay!), but the visibility is not being toggled.

Dabrowski

8:04 pm on Jun 4, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Is there anything else in showhideID.js?

I can't see a single character out of place here, it could be something else in the same file?

mehh:
Shouldn't that tweak be:

if(e && e.style.display == "none") {

?

Also, another tweak so you don't have to set the style on the div, use '!=' instead:

if(e && e.style.display!= "block") {  
e.style.display = "block";
}

And do the same for the hide.

[edited by: Dabrowski at 8:09 pm (utc) on June 4, 2007]

rocknbil

9:08 pm on Jun 4, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The first thing I would do is copy the source of your output, put it in a temp file, then upload it to the validator to see if you have a coding error bunging up the workings of the page. If it works in one browser and not another, it could simply be a missing quote or poorly nested tag.

Next I'd start dropping in alerts to find out what object it's expecting.

doodlebee

10:13 pm on Jun 4, 2007 (gmt 0)

10+ Year Member



Is there anything else in showhideID.js?

Nope - that's all that's in the file - nothing else.

Also, another tweak so you don't have to set the style on the div,

Cool! I'll give that a try...

Well, it worked as well, but with the same result. The error is gone now, but in IE, the visibility still doesn't toggle - the short form remains, and I can't get the hidden div to show up on the select option.

I've even taken it a step further and completely removed the "if" statements, and that works, too (makes the code smaller, as well) - but still no error/no toggle in IE.

The first thing I would do is copy the source of your output, put it in a temp file, then upload it to the validator to see if you have a coding error bunging up the workings of the page.

I NEVER post questions until I've validated. Period.

So the response to that is I'm 100% valid in XHTML and CSS. Not a single error in place.

Dabrowski

11:03 pm on Jun 4, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Also, another tweak so you don't have to set the style on the div,


Cool! I'll give that a try...

I think that's your next step. If you've copied the actual HTML code as rocknbil suggested, and IE works but with no toggle, I think the problem may be that the style property may be overriding the JS. I can't see any other way.

Failing that, again as rocknbil suggested, put an alert inside your IF, so you can check that IE is at least getting that far.

Dabrowski

11:16 pm on Jun 4, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hah! I've got it!

if(e && e.style.display!= "block") {

What's wrong with this line?

Anyone?

How do we fetch a CSS value in IE?

Yes, that's right!

We use element.currentStyle.property!

I can believe none of us spotted that one!

So, in answer, my 'tweak' will fix it, but not for the right reason. You need to use e.currentStyle.display if you're in IE. Thanks again MS. Try this really handy function I wrote:

function uppercaseThis( str) { return str.toUpperCase(); }
function getProp( obj, prop) {
var str;

if( navigator.appVersion.indexOf( "MSIE")!= -1) { // Camel case for IE
prop = prop.replace( /-(.)/g, uppercaseThis);
prop = prop.replace( /(-)/g, "");
}

if( obj.currentStyle)
str = obj.currentStyle[ prop];

else if( window.getComputedStyle)
str = window.getComputedStyle( obj, null).getPropertyValue( prop);

return str;
}

doodlebee

1:36 am on Jun 5, 2007 (gmt 0)

10+ Year Member



Dabrowski - thanks for the help, but it's still not working.

I've done a few tests, and I believe the error is coming from how the *form* is handling the change. If I add in a link:

<a href="javascript:show('services_inquiry');">click me!</a><br />

It works fine in IE (and everything else). But I'm using a form option selection to toggle the display of the div. When I rely on *that*, it *doesn't* work in IE.

So it's not the script, from what I can tell ('cause it works hunky-dory with a link and onclick event)..it's how I'm calling into being...

doodlebee

2:00 am on Jun 5, 2007 (gmt 0)

10+ Year Member



Okay, further investigation shows I'm correct - it's the "onclick" I have set for each option.

So now this really sucks. I have to have my options set so that when each is chosen, they each have a different event attached to them.

So I have to do something like this:

<select class="form" name="mailto" onchange="show('services_inquiry');">
<?php if (isset($_POST['mailto'])) echo '<option selected>'.(($_POST['mailto'])).'</option>';?>
<option class="select_option" value="">&nbsp;----------------------------</option>
<option value="general">General Information</option>
<option value="services">Inquiry for Services</option>
</select>

However, this, of course, makes any selection you make show the div I want to show. But I want "general" to hide it, and "services" to show it.

So how do I get *that* to work? As it is above, it works in IE (and all else), but I can't figure out how to make the "onchange" event make each option do what it's supposed to do.

Dabrowski

10:53 am on Jun 5, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I must admit I've always used an onChange, never tried an onClick but I guess now I won't bother!

ok, try a 'wrapper' function, this will check which option is selected and either call show or hide:

function checkShowHide( name) {
var idx = document.formname.mailto.selectedIndex;
var opt = document.formname.mailto.options;

if( opt[ idx].value == "services") show( name);
else hide( name);
}

And change your onChange event to call this function instead. Remember to change "formname" to the name of your form!

Give that a go and let us know if that works.

doodlebee

2:22 pm on Jun 5, 2007 (gmt 0)

10+ Year Member



Dabrowski -

I love you. You are my hero and have saved me! (I found out from searching last night that "onclick" isn't something that's an option with "select/option" stuff - only "onchange", and IE is a stickler for it, I guess - just so you know :) )

For anyone else who might want the specifics, the final form section in question looks like so:

this is only the pertinent section of the form

<div class="form_field clear">

<?php if ($mailto_error == "1") { echo "<small class=\"error clear\">You must choose an option for your email type.</small>"; }?>
<span class="fieldname"><span class="required">*</span> Nature of Inquiry:</span>
<select class="form" name="mailto" onchange="showhide('services_inquiry');">
<?php if (isset($_POST['mailto'])) echo '<option selected>'.(($_POST['mailto'])).'</option>';?>
<option class="select_option" value="">&nbsp;----------------------------</option>
<option value="general">General Information</option>
<option value="services">Inquiry for Services</option>

</select>

</div>

<div id="services_inquiry">
(extra form fields here for the expanded part - this is the content that shows/hides)
</div>

and the script...

showhideID.js

function show(id) {
var e = document.getElementById(id);
if(e && e.style.display!= "block") {
e.style.display = "block";
}
}

function hide(id) {
var e = document.getElementById(id);
if(e && e.style.display!= "none") {
e.style.display = "none";
}
}

function showhide(id) {
var idx = document.contact.mailto.selectedIndex;
var opt = document.contact.mailto.options;

if( opt[idx].value == "services") show(id);
else hide(id);
}

I also have

<body id="page" onload="hide('services_inquiry');">
in the top of the page, so that the "expandable" part is hidden on page load - but if javascript is shut off, then it's expanded.

Thanks top everyone for all your help - I really appreciate it! :)

Dabrowski

3:52 pm on Jun 5, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There is a better way of doing the initial hide, with CSS only. At the moment the form will appear, then disappear when the page loads. Try this, I think it looks neater.

In your main CSS:

#services_inquiry {
display: none;
....
}

And then in your <head>:

<noscript>
<style>
#services_inquiry {
display: block;
}
</style>
</noscript>

You can even <link> in another stylesheet for this, just make sure you include it after the main stylesheet so the display gets overridden properly.

It's not quite as tidy code wise, but looks better on screen.

doodlebee

4:09 pm on Jun 5, 2007 (gmt 0)

10+ Year Member



Thanks again for that - works like a charm :) (And I think it *is* a little bit cleaner...but that's my opinion :) )

tomesto

12:02 pm on Jun 8, 2007 (gmt 0)

10+ Year Member



It seems that javascript in IE has problems when dealing with the display property of CSS if it is initially set to 'none', that is when the element is to be hidden on page load. The solution was to set it to block (or inline) in CSS and then hide it with javascript when the page loads. Then you'll have no problems showing and hiding that element later.

It's a hack but it works.