By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
426,226 Members | 1,166 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 426,226 IT Pros & Developers. It's quick & easy.

AJAX 'getElementById()' problem

P: 7
First, let me state that this is not necessarily a Firefox problem, as I haven't fully tested in IE just yet.

Second, let me state that this is not the typical "getElementById not working Firefox" post.

Third, there are pieces of this code that I am not at liberty to display, change, discuss, or re-implement. As far as this question is concerned, this means that (1) I cannot use 3rd party libraries, which is why I've implemented my own Ajax script... besides, it's simple and effective... and (2) I know coding HTML tables to display layout is a snafu, but since I'm not alone on this, the tables won out over DIVs.

And finally... the scenario:

I've got something over 2000 lines of code (HTML & JS) that pertains to this, but using alert() and various server-side debugging methods, I've come to the comfortable realization that my problem lies in this function within my Ajax function.

Expand|Select|Wrap|Line Numbers
  1. /* This function is called asynchronously when the server returns a result from an AJAX request */
  2. function ajaxRequestCallback(){
  3.    if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete") {
  4.       var str = xmlHttp.responseText;
  5.       var strparts = str.split( "&" );
  6.       var numParts = strparts.length;
  7.       for( var j = 0; j < numParts; j++ ) {
  8.          var item = strparts[j];
  9.          var elems = item.split( ":" );
  10.          var name = elems[0];
  11.          var value = Base64Decode( elems[1] );
  12.  
  13.          /* The situation in question will display "infoUserName" for 'name' */
  14.          alert( "Getting object with ID '" + name + "'." );
  15.  
  16.          /* The problem is here */
  17.          var o = document.getElementById( name );
  18.  
  19.          /* 'if' removed for testing using Firefox's error console */
  20.          /* if( o ) { */
  21.             /* Firefox Error Console says 'o is null' at this point.
  22.             o.innerHTML = value;
  23.          /* } */
  24.       }
  25.    }
  26. }
And the coresponding section of HTML (Note that this is produced by PHP, but it is produced this same way every time):
Expand|Select|Wrap|Line Numbers
  1.     <table class='bodyContainer'>
  2.      <tr>
  3.       <td style='text-align: right; vertical-align: top; width: 100px;'>
  4.        <label for='tbUserName'>User Name:</label></td>
  5.       <td style='text-align: left; vertical-align: top; width: 197px;'>
  6.        <input id='tbUserName' name='tbUserName' type='text' OnKeyUp='checkUserName();' class='textbox' style='width: 193px' value='' /></td>
  7.       <td style='text-align: left; vertical-align: top; width: 297px;'>
  8.  
  9.  
  10.        <!-- Here is the element being retrieved from the JavaScript -->
  11.        <span id='infoUserName'>User name must be supplied.</span></td>
  12.  
  13.  
  14.      </tr>
  15.      <tr>
  16.       <td style='text-align: right; vertical-align: top; width: 100px;'>
  17.        <label for='tbPassword'>Password:</label></td>
  18.       <td style='text-align: left; vertical-align: top; width: 197px;'>
  19.        <input id='tbPassword' name='tbPassword' type='password' OnKeyUp='checkPasswd();' class='textbox' style='width: 193px' /></td>
  20.       <td style='text-align: left; vertical-align: top; width: 297px;'>
  21.        <span id='infoPassword'>Your password is too short</span></td>
  22.      </tr>
  23.      <!-- More rows occur, but they work perfectly! -->
  24.     </table>
  25.  
Note that the 'tbPassword' input calls the 'checkPasswd()' function, which uses getElementById( 'tbPassword' ), and it works with no problems. My problem is just in the javascript code up top. The HTML in bold shows where the element 'infoUserName' exists.

Any thoughts?

I apologize for not being able to provide a 100% working model here. It may be noteworthy for recreating this problem that the checkPasswd function just checks for length and compares against a RegEx for 'strong' vs. 'weak' and checkUserName() initiates the AJAX request to see if the UserName exists already.

TIA
Cy
Aug 23 '08 #1
Share this Question
Share on Google+
8 Replies


P: 7
After posting the original post, I went and changed the javascript to show alerts whenever 'o' is null and removed the comments around the 'if' block. Now, the javascript looks like this:
Expand|Select|Wrap|Line Numbers
  1. function stateChanged(){
  2.     if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete") {
  3.         var str = xmlHttp.responseText;
  4.         var strparts = str.split( "&" );
  5.         var numParts = strparts.length;
  6.         for( var i = 0; i < numParts; i++ ) {
  7.             var item = strparts[i];
  8.             var elems = item.split( ":" );
  9.             var name = elems[0];
  10.             var value = Base64Decode( elems[1] );
  11.             alert( "Getting object with ID '" + name + "'." );
  12.  
  13.             var o = document.getElementById( name );
  14.             if (o) {
  15.                 o.innerHTML = value;
  16.             } else {
  17.                 alert("Variable 'o' is null!");
  18.             }
  19.         }
  20.     }
  21. }
  22.  
The result is that both Firefox and IE are showing 'infoUserName' as the element ID and both are showing 'o is null'.

I thought this additional information might help someone to identify any potential problems.

Again, TIA
Cy
Aug 23 '08 #2

acoder
Expert Mod 15k+
P: 16,027
What does the server-side script return? Can you give an example string?
Aug 23 '08 #3

P: 7
The server side script returns a string that is in the format:

elementId2:[Base64_Value]&elementId2:[Base64_Value]

If you look at the original javascript function, the first thing that happens is the string is split on the '&', leaving "elementId:[Base64 Value]"

When the value is decoded, it's in HTML format. I've used Alert() to make sure these values are correct, and they do come back. So with regards to my original question, the value of the query was:
Expand|Select|Wrap|Line Numbers
  1.         var strparts = str.split( "&" );
  2.         var numParts = strparts.length;
  3.  
In the above code, strparts evaluates to str (since there's no '&' in the query).
'numParts' evaluates to '1'.

Expand|Select|Wrap|Line Numbers
  1.             var item = strparts[i];
  2.             var elems = item.split( ":" );
  3.             var name = elems[0];
  4.             var value = Base64Decode( elems[1] );
  5.  
  6. /* After running, we have:
  7.    item = (string:) 'infoUserName:{base64_string}'
  8.    elems = (array:) [0] => 'infoUserName', [1] => '{base64_string}'
  9.    name = (string:) 'infoUserName'
  10.    value = (string:) 'This user name is available.'
  11. */
  12.  
So, in short, 'name' and 'value' are what we're using in the failing code. 'value' is just what the element will display, and 'name' is the ID of the element. With my alert() tests, the ID stored in 'name' was the exact same as the ID written to the HTML file. But the assignment fails:
Expand|Select|Wrap|Line Numbers
  1.             var o = document.getElementById( name );
  2.             if (o) {
  3.                 o.innerHTML = value;
  4.             } else {
  5.                 alert("Variable 'o' is null!");
  6.             }
  7.  
This shows only "Variable 'o' is null!" in both IE and Firefox.

Thank you for looking at this. If I can provide any more information, please let me know.

Cy
Aug 23 '08 #4

acoder
Expert Mod 15k+
P: 16,027
To rule out the possibility that it's grabbing the wrong element, try replacing:
Expand|Select|Wrap|Line Numbers
  1. var o = document.getElementById( name );
with
Expand|Select|Wrap|Line Numbers
  1. var o = document.getElementById("infoUserName");
Aug 23 '08 #5

P: 7
To rule out the possibility that it's grabbing the wrong element, try replacing:
Expand|Select|Wrap|Line Numbers
  1. var o = document.getElementById( name );
with
Expand|Select|Wrap|Line Numbers
  1. var o = document.getElementById("infoUserName");
I took your advice, and hard-coded 'infoUserName'. This actually worked, so obviously it's not using the same text, even though the alert test says it's the same thing. I'm going to guess it's a binary issue. Something in the process of dealing with base64 strings converts ASCII to UTF-8. Would this really make a difference?

Thanks for getting me pointed in the right direction.

Cy
Aug 24 '08 #6

P: 7
Alright, I've done some testing to check into the UTF-8 theory. Ultimately, the answer is 'No, it's not in UTF-8'. However, there are 6 bytes coming back at the beginning of my Ajax response text. These bytes are EF BB BF EF BB BF

Does this look familiar to anyone? These 6 bytes are the ONLY bytes in my response text that I did not explicitly send back from the server. I can strip them out, but I want/need to know a few details first. To begin with, what do they mean? Should I use them for anything? Are they significant? Are the always only 6-bytes long?

For now, I'll just strip them out until they either cause a problem or I can find out more about them. Until then... thanks for all the help.
Cy
Aug 24 '08 #7

P: 7
Ok, I officially feel like a dunce.

I guess this is a typical solution pattern.
Step 1: Have problem.
Step 2: Post problem.
Step 3: Publicly humiliate yourself.
Step 4: Find solution.

So, the EF BB BF pattern is the BOM for UTF-8... I should have recognized this, since I'm familiar with BOM patterns, but I was thrown by the fact that this was present in the DECODED text (ASCII).

Solution: Amend my decode_utf8() function to strip the BOM.

Cy
Aug 24 '08 #8

acoder
Expert Mod 15k+
P: 16,027
Hehe, not necessarily step 3. This thread may well prove useful to someone.

Glad you got it working and thanks for posting!
Aug 24 '08 #9

Post your reply

Sign in to post your reply or Sign up for a free account.