views:

123

answers:

2

I am still learning to do javascript and django and yesterday I tried to do a simple hello world ajax exercise.

Server logs show that python code is being called but somehow django/python does not return anything when I check the xmlhttp.responseText and responseXML in firebug.

UPDATE: I removed the checking of the http status returned so that code immediately goes to print the output from the server

<html>
<head>
 <title>Javascript example 1</title>
 <script type="text/javascript">
  function doAjax() 
  {
   xmlhttp = new XMLHttpRequest();
   xmlhttp.onreadystatechange = function() {
       alert("response text: "+xmlhttp.responseText+"\n"
             +"response XML: "+ xmlhttp.responseXML);
       if (xmlhttp.responseText!="") {
            $("thediv").innerHTML=xmlhttp.responseText;
       }      
   }   
   xmlhttp.open("GET","http://127.0.0.1/test/",true);
   xmlhttp.send(); 
  }
  function $(element){
    return document.getElementById(element);
  }
 </script>
</head>
<body>

 <input type="button" value="click me" onClick=javascript:doAjax()>
 <br/><br/>

 <div id="thediv">
  some test
 </div>

</body>
</html>

my views.py

from django.http import HttpResponse

def test(request):
 response_string="hello"
 return HttpResponse(response_string,mimetype='text/plain')

my urls.py

from django.conf.urls.defaults import *
from project1.views import test

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
        (r'^test/$', test)
    # Example:
    # (r'^project1/', include('project1.foo.urls')),

    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
    # to INSTALLED_APPS to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    # (r'^admin/', include(admin.site.urls)),
)

UPDATE

Here is the code in action

alt text

+2  A: 

I just tested your code. When I clicked the "click me" button, a request was indeed made to the test view. I was able to confirm this. However, unlike what you said the view is returning the HttpResponse. To verify this yourself, access the http://localhost:8000/test/ url using your web browser. See what happens.

At first blush your problem seems to be JavaScript related. I don't know what exactly is going wrong but I'll try to debug the JS code and see.

Update

I was able to confirm that the error is indeed with the JavaScript that you are using. I found two errors. First:

if (xmlhttp.readyState==4 && xmlhttp.status==0)

Shouldn't the status be 200? So I changed it to:

if (xmlhttp.readyState==4 && xmlhttp.status==200)

Update 2

Found that I missed the $ function.

The problem is that there are two if conditions. When first evaluates to true, the contents of the div are indeed updated to "hello". However the second if (xmlhttp.responseXML!="") also evaluates to true (null is != "", hence) and wipes out the contents of the div.

Manoj Govindan
Yes, when I go to the http://localhost:8000/test/ the browser indeed returns the "hello" string but when I do an ajax call using the button above, firebug shows that the responseText and responseXML are not showing anything.
Jeune
@Jeune: updated my answer. See above.
Manoj Govindan
My files are at home so I'll be able to check them tonight when I get back from the office. Will get back to you. I have a few comments though on your update, I checked my javascript in firebug and it does go through inside the if (xmlhttp.status=200) statement. Regarding the ($) shortcut key, I made a function in javascript that will return the element, see my code above --> function $(element) {...} Cheers :D
Jeune
@Jeune: gotcha. See my second update above.
Manoj Govindan
I tried setting the xmlhttp.status==200 in the if statement but nothing happens. So I am still using the xmlhttp.status==0 comparison. Like you I also placed an alert within inside the if statement and unlike you, as you can see above, nothing is being returned.
Jeune
@Jeune: for what it is worth I tested the code in Chrome (6.0.472.62) and Firefox (3.6.10, Mozilla Firefox for Ubuntu Canonical - 1.0) both on Ubuntu Jaunty.
Manoj Govindan
Obviously it's a problem on MY end, as a developer. I tried this on two installations --- linux mint and as you can see above windows xp and both didn't work! :)) There's something I am doing wrong here :))
Jeune
@Jeune: I also tested the answer given by @skimnetster It works :)
Manoj Govindan
Are there settings I have to tweak? Should I put my index.html in a folder where the views.py is?
Jeune
@Jeune: No need to tweak any settings. `Index.html` should preferably reside in your templates directory and not in the same directory as `views.py`.
Manoj Govindan
I made a last change to the javascript code, would like to ask for your opinion before I try something new. I basically removed the if statement that checks the httpstatus and ready state.
Jeune
@Jeune: looks good to me :) Try and see if it works for you. Although in the long run you'd be better off using a library like jQuery.
Manoj Govindan
haha well actually my code change didn't work. Maybe I'll try some other way to do this. Thanks for all the help +1
Jeune
+1  A: 

Its good to use core JavaScript when learning but you should definitely use some framework such as jQuery or Prototype as you progress. Frameworks allow to keep your code concise, develop faster and also insulate you from the cross-browser compatibility issues.

Using jQuery your code would have been something like this:

<html>
<head>
 <title>Javascript example 1</title>
 <script type=”text/javascript” src=”http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js”&gt;&lt;/script&gt;
 <script type="text/javascript">
  function doAjax() 
  {
    $.ajax({
      url: 'http://localhost:8000/test/',
      success: function(data) {
        $('#thediv').html(data); //jQuery equivalent of  document.getElementById('thediv').innerHTML = data
      }
    });
  }
 </script>
</head>
<body>

 <input type="button" value="click me" onClick="javascript:doAjax()"/>
 <br/><br/>

 <div id="thediv">
  some test
 </div>

</body>
</html>

Since jQuery provides with a default $() function, you do not need to define them in your code in case you use the framework.

Though this answer is slightly off-track, I hope it will be useful to you.

skimnetster
+1 for putting the jquery code. Yes I do plan to move on to using a framework but of course after I get my hands dirty with handmade javascript :D
Jeune
This works....but not on Firefox 3.6.10 which I am using! Sucks :( I tried it on IE and it suddenly worked! @_@
Jeune