7

I'm developing a web app that needs to do some backend processing while still displaying the information on screen. Obviously this is best suited for AJAX, which I'm using. However, prior to beginning the AJAX request, I'm making a few visual changes via Javascript. Specifically:

document.getElementById('calc').innerHTML = 'Calculating...'; document.getElementById('calc').disabled = true;

I then go on to call a servlet via AJAX.

This works fine in Firefox. However in Internet Explorer (version 8), the visual changes never take effect. The app just sits there for a minute or two until the AJAX processing is done. It seems like the AJAX code is executing before the page changes, but I don't know why that would be.

Any assistance would be greatly appreciated.

EDIT: Here's my best effort at a Short, Self Contained, Correct, Example

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<script>
var inEdit = 0;
var calcCurrent = false; 
function recalc() {
var xmlhttp=new XMLHttpRequest();
if (xmlhttp==null)
{
  var tmp = "Your browser does not support XML! ";
  tmp += "Please contact your Technical Support division for information on how to upgrade.";
  alert(tmp);
}
else
{
  document.getElementById('calc').innerHTML = 'Calculating...';
  document.getElementById('calc').disabled = true;
  var url = "http://www.nzherald.co.nz/";
  xmlhttp.open("GET",url,false);
  xmlhttp.send(null);
  if (xmlhttp.responseText.indexOf("Success")>=0) {
    alert(xmlhttp.responseText);
  }
  else
    alert(xmlhttp.responseText);
  document.getElementById('calc').value = 'Recalculate';
  document.getElementById('calc').disabled = false;
}
}
</script>
</head>
<body>
<a id='calc' class='Button' href="javascript:recalc()" >Recalculate</a>
</body>
</html>

The only issue example with this is that this URL returns almost instantly. On my app it's pointing to a page that does database processing for about a minute, and so the problem is a lot more obvious.

6
  • 1
    What is your calc element? It may not support innerHTML in IE8 Commented Jan 18, 2012 at 0:30
  • be sure you don't have any console.log statements in the javascript, or IE may not run the code after them. It will, if you open developer tools while you run it. If this is the problem Commented Jan 18, 2012 at 0:31
  • 3
    More code would be appreciated. Commented Jan 18, 2012 at 0:31
  • 1
    Please provide a Short, Self Contained, Correct (Compilable), Example. Commented Jan 18, 2012 at 0:40
  • calc is an anchor <a> element, I'm fairly certain that supports innerHTML. Also, the innerHTML does change eventually, it just takes a long time. Commented Jan 18, 2012 at 2:22

3 Answers 3

1

You are passing "false" for the async parameter to xmlhttp.open() call. Because the stack has not unwound since you set the innerHTML property of the calc element, IE has not had a chance to repaint the screen.

You have a few options.

  1. Restructure your code such that you make the ajax call async and get the result via a callback notification.

  2. OR.... Set the innerHTML property on calc, then call setTimeout with a delay of 0 and a callback function that is written to call xmlhttp.open as you have it now. This will allow the stack to unwind and IE will repaint the DOM changes followed by your ajax call executing. Below is a hacked up version of your code to demonstrate what I am talking about.

Below is some hacked up code demonstrating #2.

var xmlhttp;

function recalc() {
    xmlhttp=new XMLHttpRequest();
    if (xmlhttp==null)
    {
      var tmp = "Your browser does not support XML! ";
      tmp += "Please contact your Technical Support division for information on how to upgrade.";
      alert(tmp);
    }
    else
    {
      document.getElementById('calc').innerHTML = 'Calculating...';
      document.getElementById('calc').disabled = true;
      setTimeout(recalc_start, 0);
    }
}

function recalc_start() {
  var url = "http://www.nzherald.co.nz/";

  xmlhttp.open("GET",url,false);
  xmlhttp.send(null);
  if (xmlhttp.responseText.indexOf("Success")>=0) {
    alert(xmlhttp.responseText);
  }
  else {
    alert(xmlhttp.responseText);
  }
  document.getElementById('calc').value = 'Recalculate';
  document.getElementById('calc').disabled = false;
}
Sign up to request clarification or add additional context in comments.

3 Comments

If the above code snippit doesn't work, then try changing the timeout from "0" to "1" or something higher.
Awesome! This option (using a timeout) completely solves my problem. Good to know why this is occurring. Thanks so much.
@enjiner - Glad it worked. ideally you go with option #1. Otherwise, a very long delay in the ajax request will likely keep your web page "frozen" (or at least other javascript code from running) until the ajax call completes.
1

Those two lines of code are very straightforward. The are two things that comes to mind:

  1. Do you have the ID defined for another element. Can you double check that calc is not used anywhere else in the page? Preferably by doing a Ctrl+F in View Source.
  2. Validate your HTML. Make sure you are not missing any closing tags or quotes in an attribute.

1 Comment

Thanks for the suggestions epignosisx. I checked both of those issues. Validating revealed a lot of non-compliant HTML including missing tags. Unfortunately the problem I described is still present, but it was good to identify the validation problems! Thanks again.
0

I am assuming this is an <input id='calc' type='text' /> element:

document.getElementById('calc').value = 'Calculating...';
document.getElementById('calc').setAttribute('disabled','disabled');

For best mutli-browser compatibility, try using jQuery:

$("#calc").val('Calculating...').attr('disabled','disabled');  

2 Comments

Can't think of a browser that would take issue with the first example. jQuery is not doing anything helpful here
@ron—for "best browser compatability" just set the property directly, there is no need for setAttribtue or jQuery (or its messy attr function).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.