views:

571

answers:

6

I'm doing some maintenance coding on a webapp and I am getting a javascript error of the form: "[elementname] has no properties"

Part of the code is being generated on the fly with an AJAX call that changes innerHTML for part of the page, after this is finished I need to copy a piece of data from a hidden input field to a visible input field. So we have the destination field: <input id="dest" name="dest" value="0">
And the source field: <input id="source" name="source" value="1">
Now when the ajax runs it overwrites the innerHTML of the div that source is in, so the source field now reads: <input id="source" name="source" value="2">

Ok after the javascript line that copies the ajax data to innerHTML the next line is: document.getElementById('dest').value = document.getElementById('source').value;

I get the following error: Error: document.getElementById("source") has no properties

(I also tried document.formname.source and document.formname.dest and same problem)

What am I missing?

Note1: The page is fully loaded and the element exists. The ajax call only happens after a user action and replaces the html section that the element is in.

Note2: As for not using innerHTML, this is how the codebase was given to me, and in order to remove it I would need to rewrite all the ajax calls, which is not in the scope of the current maintenance cycle.

Note3: the innerHTML is updated with the new data, a whole table with data and formatting is being copied, I am trying to add a boolean to the end of this big chunk, instead of creating a whole new ajax call for one boolean. It looks like that is what I will have to do... as my hack on the end then copy method is not working.

Extra pair of eyes FTW.

Yeah I had a couple guys take a look here at work and they found my simple typing mistake... I swear I had those right to begin with, but hey we live and learn...

Thanks for the help guys.

A: 

Generally you shouldn't use innerHTML, but create elements using DOM-methods. I cannot say if this is your problem.

Erik
This is how the codebase was handed to me, I don't have time or authority to rewrite all of the ajax calls.
Jim Ford
+2  A: 

Make sure your code runs AFTER the page fully loads. If your code runs before the element you are looking for is rendered, this type of error will occur.

Diodeus
+1  A: 

What your describing is this functionality:

<div id="test2">
    <input id="source" value="0" />
</div>
<input id="dest" value="1" />

<script type="text/javascript" charset="utf-8">
//<![CDATA[
function pageLoad()
{
    var container = document.getElementById('test2');
    container.innerHTML = "<input id='source' value='2' />";
    var source = document.getElementById('source');
    var dest = document.getElementById('dest');
    dest.value = source.value;
}
//]]>
</script>

This works in common browsers (I checked in IE, Firefox and Safari); are you using some other browser or are you sure that it created the elements correct on innerHTML action?

the ajax call is kicked off by a user action, after the entire page is loaded. The whole string is copied with the innerHTML action, even the input tag that I am trying to get data from.
Jim Ford
+3  A: 

"[elementname] has no properties" is javascript error speak for "the element you tried to reference doesn't exist or is nil"

This means you've got one or more of a few possible problems:

  1. Your page hasn't rendered yet and you're trying to reference it before it exists
  2. You've got a spelling error
  3. You've named your id the same as a reserved word (submit on a submit button for instance)
  4. What you think you're referencing you're really not (a passed variable that isn't what you think you're passing)
Steropes
spelling error.... yeah
Jim Ford
...Nice...those are one of my faves!
Jason Bunting
A: 

It sounds like the DOM isn't being updated with the new elements to me.

For that matter, why are you rewriting the entire div just to change the source input? Wouldn't it be just as easy to change source's value directly?

R. Bemrose
A whole table preformatted with html and data is being copied, I am adding 1 more piece of info to the same ajax call, my goal was not to introduce a second ajax call for just one boolean value. The values get written, and are visible on the page after the ajax runs...
Jim Ford
A: 

This is a stretch, but just may be the trick - I have seen this before and this hack actually worked.

So, you said:

Ok after the javascript line that copies the ajax data to innerHTML the next line is: document.getElementById('dest').value = document.getElementById('source').value;

Change that line to this:

setTimeout(function() {
   document.getElementById("dest").value = document.getElementById("source").value;
}, 10);

You really shouldn't need this, but it is possible that the time between your setting the innerHTML and then trying to access the "source" element is so fast that the browser is unable to find it. I know, sounds completely whack, but I have seen browsers do this in certain instances for some reason that is beyond me.

Jason Bunting
the delay didn't help... I must be missing something else.
Jim Ford
Sorry my delay idea wasn't useful! Hope you get a handle on this, JavaScript is one of those things that drives some people to drink.
Jason Bunting
I don't recommend timeouts except as a last resort or when dealing with plugins.
mwilcox
@mwilcox - what? I don't understand why your comment is relevant; not to mention setTimeout is an extremely valuable function in JavaScript. Your statement is rather useless since you give no backup reasons or qualifications. A last resort for what? And how do they help when dealing with plugins? Your comment is out of context and seemingly pointless.
Jason Bunting