We help IT Professionals succeed at work.

Need help to tailor ajax code for Firefox

alateos
alateos asked
on
498 Views
Last Modified: 2008-04-24
Hi,

I've developed a web app completely in ajax. I tested it in IE and it worked fine. Problem is, when I tried to use Firefox and Opera hell broke loose. I'm sure my XMLHttp object takes into account Firefox but still, the whole application behaves strangely. Here's part of the code that I would like to see at least working:

==========
index.php
==========

<?php
session_start();
//session_destroy();

include ("ajaxlogin.js");
include ("functions.js");
include ("CreateTicketMenu.js");
include ("SaveNewTicket.js");
include ("LocationsMenu.js");
include ("EquipmentMenu.js");
include ("viewTicket.js");
?>
<html>
<link rel="stylesheet" type="text/css"
href="style.css" />
<FORM method="POST" name="ajax">
<body OnLoad="document.ajax.username.focus();">
<table class='shade' border="0" align="center">
<td width=200>
<span class=a id="txtresponse">
<font color=#8B0000><b> Username </b></font>  
<INPUT TYPE="text" NAME="username" onkeypress="pressenter(username.value,password.value)"><BR>
<font color=#8B0000><b> Password </b></font>  
<INPUT TYPE="password" NAME="password" onkeypress="pressenter(username.value,password.value)"><BR> <br>
<INPUT TYPE="button" VALUE="Authenticate" OnClick="Authenticate(username.value,password.value)">
<span class=a id="nologin" width=75px align="left"></span><br>
</span>
</td>
<span id="listissues"></span>
</table><br>
</body>
</FORM>
</html>


===========
ajaxlogin.js
===========

<script type="text/javascript">



function Authenticate(user,pass)
{

xmlHttp=GetXmlHttpObject();
var url="menu.php";
var userpass = "username=" + user + "&password=" + pass;


xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("POST",url,true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", userpass.length);
xmlHttp.setRequestHeader("Connection", "close");
 

xmlHttp.send(userpass);


}


function getMainMenu()
{

xmlHttpcc=GetXmlHttpObject();

var url="getmainmenu.php";


xmlHttpcc.onreadystatechange=stateChangedcc;
xmlHttpcc.open("GET",url,true);
xmlHttpcc.send(null);


}


function pressenter(user,pass) {
  if (window.event && window.event.keyCode == 13)
    Authenticate(user,pass);
  else
    return true;}


function voidaction()
{
 exit();
}



function navigate()
{

window.location = "index.php";
}



function stateChangedcc()
  {

try
{
  if(xmlHttp.readyState==4)
    {


  document.getElementById("txtresponse").innerHTML=xmlHttpcc.responseText;



    }
}

catch (e)

{



}

  }



function stateChanged()
  {

try
{
  if(xmlHttp.readyState==4)
    {
      
      
    var response = xmlHttp.responseText;
            
    document.getElementById("txtresponse").innerHTML=xmlHttp.responseText;

    }
}

catch (e)

{

setTimeout(navigate,1450);


document.getElementById("nologin").innerHTML="<font color= red><i><b>Authentication Failed. Please try again!</b></i></Font>";


}

  }



function GetXmlHttpObject()
{
var xmlHttp=null;
try
 {
 // Firefox, Opera 8.0+, Safari
 xmlHttp=new XMLHttpRequest();
 }
catch (e)
 {
 // Internet Explorer
 try
  {
  xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
  }
 catch (e)
  {
  xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
 }
return xmlHttp;
}
</script>


===========
style.css
===========

h1,h2,h3,h4,h5,h6
{
color: blue;
}

p
{
width: 994;
}

img
{
width: 50;
height: 50;
}

.whatever
{
background-image: url('Criska.jpg');
background-repeat: repeat-x;

}

table.list
{
background-color: #000000;
 
text-align: center;
position: fixed;
width: 1000px;
}

table.shade
{
background-color: #B0E2FF;

/*
text-align: center;
position: fixed;
*/
}

span.b
{
width: 1000px;
background-color: #FFFFFF;
}

span.a
{
width: 200px;
background-color: #B0E2FF;
 
text-align: center;
position: fixed;
}




tr.odd
{
background-color: #B0E2FF;
}

tr.even
{
background-color: #DBDBDB;
}

tr.solution
{
background-color: Lime;
}

tr.top
{
background-color: #FFF68F;
}

Comment
Watch Question

Commented:
What exactly is wrong?  What error messages to do you get?

Author

Commented:
It just doesn't work well. The whole layout looks weird. I'll be more than happy to provide you the code of the other files upon request. Maybe then you can test it out yourself and see what i mean.

Commented:
Is the first line of your file a DOCTYPE?

The whole layout may be wierd because the html code and css were designed to look good in IE quirks-mode only.

If there isn't a doctype, and you put one on, it will look bad in IE as well.

Author

Commented:
chetOS82,
I'm not sure I understand your question. What first line are you referring to? There are 3 files above. The main page is index.php and all the code is listed. I did not explicitly state a doctype. What should I put there in your opinion?

Commented:
Ok, I see.

By default, Internet Explorer renders websites in what is known as "quirks mode".  This is a very loose rendering method that is supposed to be backwards compatable with IE3, 4, 5.  If something doesn't make sense, it guesses at what your intentions were (like, forgetting to put "px" at the end of a size measurement, it will assume you wanted that).

Firefox and Opera (and others) are much more strict about rendering, they interpret what you write exactly as it was written.  If you forgot the px, oh well, it doesn't render.

In order to get Internet Explorer to render like Firefox, you have to put it into "strict-mode", you do this by providing a DOCTYPE.  I suggest:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
But there are several (xhtml is another major one).

Once you put that on your site, it probably won't look right in IE or FF, but at least then they will render much closer to each other.  As you fix rendering issues in IE, FF will start looking correct.

So, this isn't an AJAX issue, and isn't really a PHP issue either.  It is an HTML issue.

Author

Commented:
I tried the doctype thing u mentioned... the IE version still looks the same

Author

Commented:
In addition, when I even take out the style sheet completely and I fail to login into my applcation, it doesn't do what it's supposed to.

Commented:
You put
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
immediately before your html tag and nothing happened?  It changed on my local copy.

It should be:
include ("viewTicket.js");
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<link rel="stylesheet" type="text/css" href="style.css" />
...

Author

Commented:
yep i added it like u said... nothing happened. It still looks the same.
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
I have just looked over this quickly but is your question about getting AJAX to work in Firefox or getting the page to look right?  The ajax script is incomplete for Firefox and non-IE browsers because the onreadystatechange property doesn't exist in the object they use.  A little modification will make the script cross-browser compatible and I will work on that.  However the recent comments make it sound like the question is about the appearance of the page and not getting the AJAX script to work in Firefox.  Please clarify this and I will provide details of what I mentioned above if AJAX is the issue.

Let me know if you have a question or need more information.

bol

Author

Commented:
b0lsc0tt,

I think after having taken out the style sheet I realized that the problem is twofold. One must be the stylesheet, but more importantly, the way ajax is behaving is strange. Instead of the main menu being in the center it's shifted to the right and you can't reach it all the way to the end of the screen on the right. Plus, the font has a white background and the whole area is blue. I guess let's work on this step by step.
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
Let's just work on getting the AJAX to work in this question and then you can open another for the style issues.  The script below is your ajaxlogin.js file modified.  I am pretty sure I caught all of the additions and there was an error or two also.  Let me know how that works in Firefox and then make sure it still works in IE.  Let me know if you have a question about any specific part or need more information.

bol

<script type="text/javascript">



function Authenticate(user,pass)
{

xmlHttp=GetXmlHttpObject(stateChanged);
var url="menu.php";
var userpass = "username=" + user + "&password=" + pass;


xmlHttp.open("POST",url,true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", userpass.length);
xmlHttp.setRequestHeader("Connection", "close");
 

xmlHttp.send(userpass);


}


function getMainMenu()
{

xmlHttpcc=GetXmlHttpObject(stateChanged);

var url="getmainmenu.php";


xmlHttpcc.open("GET",url,true);
xmlHttpcc.send(null);


}


function pressenter(user,pass) {
  if (window.event && window.event.keyCode == 13)
    Authenticate(user,pass);
  else
    return true;}


function voidaction()
{
 exit();
}



function navigate()
{

window.location = "index.php";
}



function stateChangedcc()
  {

try
{
  if(xmlHttpcc.readyState==4 || xmlHttpcc.readyState=="complete")
    {


  document.getElementById("txtresponse").innerHTML=xmlHttpcc.responseText;



    }
}

catch (e)

{



}

  }



function stateChanged()
  {

try
{
  if(xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
    {
     
     
    var response = xmlHttp.responseText;
           
    document.getElementById("txtresponse").innerHTML=xmlHttp.responseText;

    }
}

catch (e)

{

setTimeout(navigate,1450);


document.getElementById("nologin").innerHTML="<font color= red><i><b>Authentication Failed. Please try again!</b></i></Font>";


}

  }



function GetXmlHttpObject(handler)
{
var xmlHttp=null;
try
 {
 // Firefox, Opera 8.0+, Safari
 xmlHttp=new XMLHttpRequest();
 xmlHttp.onload=handler;
 xmlHttp.onerror=handler;
 }
catch (e)
 {
 // Internet Explorer
 try
  {
  xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
  xmlHttp.onreadystatechange=handler;
  }
 catch (e)
  {
  xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
  xmlHttp.onreadystatechange=handler;
  }
 }
return xmlHttp;
}
</script>

Author

Commented:
thanks for that piece of advice... but the above code made no difference.
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
Change the start of index.php to ...

<?php
session_start();
//session_destroy();
?>
<html>
<head>
<?php
include ("ajaxlogin.js");
include ("functions.js");
include ("CreateTicketMenu.js");
include ("SaveNewTicket.js");
include ("LocationsMenu.js");
include ("EquipmentMenu.js");
include ("viewTicket.js");
?>

Don't forget to close the head tag right before the line with the body tag.  What is the result?  The way it was setup would put the script before the html tag and could certainly cause problems.  The doctype tag ChetOS82 had you add would be above the html tag.

Do you get any javascript errors?  If so what are they?  You use try/catch a lot in just the javascript above and I assume it is probably in the other files too.  That is good for a production page but might be hiding the problem in this case.  I am not sure where to suggest you start to remove them.

Ignoring style problems what specifically happened when you tried the AJAX part of the page?  Does it still work in IE?

bol
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
Make sure you have valid html.  If your current html editor or the program you use to make the pages doesn't have one you can use the validator at http://validator.w3.org and have it look at the browser source (e.g. View Source in your browser).  It will not be able to use the PHP script but the browser source will be enough to point out errors.

The reason I mention this is I notice you have the form tag before the body tag.  That should be fixed.  The body tag needs to be first.  Make sure you correct the closing tags too.

I can't guarantee that valid html will fix this but I can tell you it will cause browsers to have problems and should be the first thing fixed.

bol

bol

Author

Commented:
Now it still doesn't work in Firefox plus it's very bad in IE... but still worse in Firefox
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
>> Now it still doesn't work in Firefox plus it's very bad in IE... but still worse in Firefox <<

"Very bad."  What is that suppose to mean?  What doesn't work?

If you can't be specific about what isn't working then I give up.  This is obviously a complex page and it is impossible to guess.  Even with all of your pages, scripts, etc we probably can't duplicate it since it seems like some authentication is involved (i.e. logging in).  You probably didn't see my last comment about valid html before posting your last comment.  Valid html will help the pages appearance, especially cross-browser.  That could be the fix to your layout/style issues.  At the very least it should be the start.  However this question is about the Ajax (isn't it?).

Please answer if this is a problem when the Ajax part of the page is run or if this is just about layout/style.  This has been asked before with no reply.  After that provide details of the problem if you want us to be able to help.

Let me know if you have a question or need clarification on anything I have said.  I can't help more if you don't provide details and reply to questions.

bol

Author

Commented:
it's very simple... In IE when it doesn't authenticate, it redirects you to the same index.php with an error message. In Firefox it does not do that. Instead, the username and password boxes start shifting to the right on each invalid try, until they're off the screen. In addition to this, the ajax part seems to work in firefox, but, the information starts appearing with a completely blue background behind a white font background. In addition, the tables, are all shifted to the right and can't be accessed completely bec. they're out of the screen on the right side. All the code you've given me hasn't helped the Firefox scenario - it remained constant. In terms of IE, all of the code you've given me hasn't changed anything (meaning it worked like it should) until that last piece of code you gave me. That made it similar to the bad layout in Firefox but the IE one still managed to give the error message in the misvalidation plus it did not shift the text input boxes. I hope that this helps clarify my problems.
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
That does help.  Thanks!

Try changing the function below (I have modified it).  Instead of redirecting let it run.

function stateChanged()
  {

try
{
  if(xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
    {
     
     
    var response = xmlHttp.responseText;
    alert(response);        
    document.getElementById("txtresponse").innerHTML=xmlHttp.responseText;

    }
}

catch (e)

{

}

I also added the alert so we could see what the response was.  Since the page in Firefox is shifting there might be some message that is being "hidden" by bad html.  Try viewing the source and look in the span with the id txtresponse.  What is the html in there after trying to run the Ajax script once?

What does menu.php do?

Let me know if you have any questions about this.

bol

Author

Commented:
1) I tried your suggestion. That does what it's supposed to do in IE, which is not redirect and not notify you of misvalidation.
2) I looked at the source. It doesn't show anything other than my source code. The menu.php page is the folllowing:

<?php
session_start();
?>
<html>
<?php
include("adldap.php");


$adldap = new adLDAP($options);


$username = $_POST['username'];
$password = $_POST['password'];






if ($adldap -> authenticate($username,$password))
{
$result=$adldap->user_info($username);
$displayname = $result[0][displayname][0];

      if ($adldap->user_ingroup($username,"Engineering"))
      
      {

      $_SESSION['username'] = $username;
      $_SESSION['displayname']=$displayname;
      $_SESSION['group']="Engineering";
 echo "<span class=b id=txtresponse>Logged in as Engineer, " . $displayname . " <a href=index.php>Log Out</a><br>";
        echo "<br><br><a href=JAVASCRIPT:getTicketMenu()>Create Ticket</a>";
        echo "<br><br><a href=JAVASCRIPT:viewTicket()>View Ticket</a>";
        echo "<br><br><a href=JAVASCRIPT:getTickets()>View Unresolved Tickets</a>";
        echo "<br><br><a href=JAVASCRIPT:locationsMenu()>Manage Locations</a>";
        echo "<br><br><a href=JAVASCRIPT:equipmentMenu()>Manage Equipment</a>";
        echo "</span>";
      echo "<span class=b><br><br></span>";
      
      }
      else
      {

      $_SESSION['username'] = $username;
      $_SESSION['displayname']=$displayname;
      $_SESSION['group']="Users";
      echo "<span class=b>Logged in as User, " . $displayname . " <a href=index.php>Log Out</a><br>";
      echo "<br><br><a href=JAVASCRIPT:getTicketMenu()>Create Ticket</a>";
        echo "<br><br><a href=JAVASCRIPT:viewTicket()>View Ticket</a></span>";
        echo "<span class=b><br><br></span>";
      }      



echo "<table class='list' border='0'>";

echo "</table>";
}


else
{

header ('Location: index.php?login=Authentication Failed');

}


?>
</html>

Author

Commented:
With point 1) in my last message, I forgot to mention that nothing is different in Firefox.
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
Did you see the alert in either browser?

Thanks for the menu.php page.  Some of the php isn't immediately familiar to me but I don't think that is a problem.  I can tell you that this page needs to be changed.  Unless I am wrong you want the AJAX script to "run" menu.php and then the results are sent back to index.php in the span (txtresponse).  That is the way AJAX usually works but menu.php is acting like it is writing out a whole page.

First, remove the html tags from the page.  They are not needed since it isn't sending a complete page to the browser.  It is just sending a response to the AJAX script to be used in part of your existing page.  The html sent does need to be good html (i.e. no missing tags, etc) but can't be a complete html page.

Also, the else statement at the end seems to be used if "login" isn't succesful.  That is a little bit of a guess since I am not sure what all the php script is doing so correct me if I am wrong.  The problem here is trying to "redirect".  That would be fine if this script was making a page for the browser but won't work for the AJAX script.  Instead you need to just send a message.  Change the else to something like ...

else
{

echo "Menu.php failed.";

}

You can change that part later but use it for now and see if that message shows up in the span.  The reason I asked you to change the stateChanged function is because that isn't the right way to know if the login failed.  The response from menu.php is the best way.

I would still like to see the browser source for index.php after you run the AJAX script (i.e. press the Authenticate button).  At the very least the html body or form.  In case you didn't know you can upload files (sometimes you have to zip them) to www.ee-stuff.com.  That site is just for EE members but if you want to provide some info that can't go in a comment or would make the comment too long then use that site.  Then post a message here to inform the experts the file is there.  Just some information that may help as we work on this.

Let me know if you have a question about any of this.

bol

Author

Commented:
View source just shows me the original source code. Is there any way that you can create a fake validation script... just something very simple that doesn't need to talk to any system. I'm really starting to feel like there's little hope to fix this code for Firefox.

Author

Commented:
btw... on a side note, in which part of the statechange function can I put like "server processing request..." before the final output is given on the screen?
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
Did you get the alert?

Did you make the changes I mentioned in the last post (and even the others)?  Is your html validating now?

Try changing the authenticate function to ...

function Authenticate(user,pass)
{

xmlHttp=GetXmlHttpObject(stateChanged);
var url="menu.php";
var userpass = "username=" + user + "&password=" + pass;


xmlHttp.open("POST",url,false);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

xmlHttp.send(userpass);


}

Notice I removed 2 lines from the header and change true to false in the open line.  What is the result?

>> Is there any way that you can create a fake validation script... just something very simple that doesn't need to talk to any system. I'm really starting to feel like there's little hope to fix this code for Firefox. <<

Yes, I can but what do you mean validate without talking to a system.  The parts of the script that I have provided and the things I have described are from AJAX scripts that I use or have made for others that work in both browsers.  The changes I suggested above were used for logging in with another AJAX script I have made that even logged in.  Have you verified menu.php will work?  For example test it by making a form page to submit to menu.php.  Do you get the results you expect (i.e. the table with the info or even the error)?  One of the nice things about an ajax "app" is you can test parts to make sure they work or to narrow down the problem.

Let me know if you have a question or need info on something.

bol
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
>> btw... on a side note, in which part of the statechange function can I put like "server processing request..." before the final output is given on the screen? <<

Do you mean a "waiting" type thing?  The specifics depend on where you want it, etc but you would basically put something in the authenticate function to show the "message" and then have it removed in the stateChanged function in the If that writes to the span.  For example if you had a hidden div with the waiting message on the page (id is hiddenDiv) then you add the line below to the beginning of Authenticate().

document.getElementById('hiddenDiv').style.display = 'block';

Then in the stateChanged function you would have the If look like this ...

  if(xmlHttpcc.readyState==4 || xmlHttpcc.readyState=="complete")
    {
  document.getElementById('hiddenDiv').style.display = 'none';
  document.getElementById("txtresponse").innerHTML=xmlHttpcc.responseText;
    }

That is just a suggestion of how you could do it but should provide an idea.

bol

Author

Commented:
I recall having read something about status = 200... I didn't really get how to do that. I just want a temporary message to appear in the txtresponse when the server is processing.

Author

Commented:
When I removed the 2 lines the result was exactly the same. Nothing changed. I think it will take me some good time to figure out the root of the problem.
b0lsc0ttIT Manager
CERTIFIED EXPERT

Commented:
>> I think it will take me some good time to figure out the root of the problem. <<

Let me know what you find out or if there is a way I can help.  If you want me to help you need to answer the questions I have asked in earlier comments and provide the details.  I won't continue to ask the same questions and guess at the problem and what is happening.

>> I just want a temporary message to appear in the txtresponse when the server is processing. <<

You can adapt what I provided to do that.  You don't need to worry about the status.  For example a change in the Authenticate function will work for what you want.

function Authenticate(user,pass)
{

document.getElementById("txtresponse").innerHTML = "server processing request...";
xmlHttp=GetXmlHttpObject(stateChanged);
var url="menu.php";
var userpass = "username=" + user + "&password=" + pass;


xmlHttp.open("POST",url,false);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

xmlHttp.send(userpass);


}

Let me know what you find and I hope this helps.

bol

Author

Commented:
bol... just wanted to let you know that I kind of started from scratch to make this application work in firefox. I took out all the coloring and formatting (therefore not using the css sheet).

With regards to the second point, I guess that makes sense.

I have one more question for you, which I've struggled with quite a lot. How can I make my javascript code react to the xmlHttp.response. That is, if the server replies with the text "no" javascript will do something and if it replies with a "yes" response javascript will do something else. I've really tried hard in the past with no avail.
IT Manager
CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.