0

Now when I have a user cast a vote the script updates my database but it won't display the following code below to tell the user its vote has been excepted everything else works correctly except my AJAX code.

How can I fix this problem to get the below code to display the new rating when user enters his or her vote?

I'm using PHP

Here is the JavaScript code.

    function vote(id, rating) {
        if (window.XMLHttpRequest) {
            http = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            http = new ActiveXObject("Microsoft.XMLHTTP");
        }
        var url = 'ajax.php?';
        var fullurl = url + 'id=' + id + '&rating=' + rating;
        //This will create the request to our file, with the information about the vote.
        http.open("GET", fullurl, true);
        http.send(null);
        http.onreadystatechange = statechange_rate;
    }

    function statechange_rate() {
        if (http.readyState == 4) {
            var xmlObj = http.responseXML;
            var html = xmlObj.getElementsByTagName('result').item(0).firstChild.data;
            var id = xmlObj.getElementsByTagName('result').item(0).getAttribute("id");
            var votes = xmlObj.getElementsByTagName('result').item(0).getAttribute("votes");
            var rating = xmlObj.getElementsByTagName('result').item(0).getAttribute("rating");
            //Before, you may have noticed we set votes="-1" if they had already voted, this was just to provide an easy way to check the return of our ajax.php script.
            if(votes != -1) {
                //This will inform the user about the vote they have cast.
                document.getElementsByName('output_' + id).item(0).innerHTML = "<br />" + html;
                //This will set a delay to make that message go away in 5000 miliseconds (5 seconds).
                window.setTimeout("document.getElementsByName('output_" + id + "').item(0).innerHTML = '';", 5000);
                //This will update the rating on the page to the new one.
                document.getElementsByName('rating_' + id).item(0).innerHTML = rating;
                document.getElementsByName('votes_' + id).item(0).innerHTML = votes;
            }else{
                document.getElementsByName('output_' + id).item(0).innerHTML = "<br />" + html;
                window.setTimeout("document.getElementsByName('output_" + id + "').item(0).innerHTML = '';", 5000);
            }
        }
    }
6
  • 5
    I know this is an aside but I strongly believe that jquery would make you a much happier camper. This code would be significantly smaller and easier to read in jQuery and you probably wouldn't be having this question since ajax is so much easier. Commented Dec 27, 2009 at 8:54
  • agreed, I skipped learning AJAX and went straight to jQuery -- I have never looked back. Commented Dec 27, 2009 at 9:13
  • I strongly suggest that you pick any library, not necessarily jQuery. Commented Dec 27, 2009 at 9:51
  • 1
    Time after time, I keep finding it amusing that people tell others to skip learning JavaScript the language, and instead use a library. It won't help you a bit when you run into real problems if you haven't mastered the language itself. Commented Dec 27, 2009 at 11:28
  • 2
    Indeed. What does jQuery give you here exactly? Oh, it can save you three lines of object-sniffing for XMLHttpRequest... wow, that's really worth dragging in over 4000 lines of framework code for, huh? Commented Dec 27, 2009 at 13:27

3 Answers 3

1

I have never seen what you are showing, so I don't know if this is your problem, but you have a tag called <result>...</result>?

You have this line, which leads to my question:

xmlObj.getElementsByTagName('result')...

It would be helpful if you could modify your statechange_rate thusly:

alert("votes result: " + votes);
if(votes != -1) {
  //This will inform the user about the vote they have cast.
  var elem = document.getElementsByName('output_' + id);
  elem.item(0).innerHTML = "<br />" + html;
  //This will set a delay to make that message go away in 5000 miliseconds (5 seconds).
  window.setTimeout("document.getElementsByName('output_" + id + "').item(0).innerHTML = '';", 5000);
  //This will update the rating on the page to the new one.
  elem = document.getElementsByName('rating_' + id);
  elem.item(0).innerHTML = rating;
  elem = document.getElementsByName('votes_' + id);
  elem.item(0).innerHTML = votes;

If you are using IE8 then bring up the javascript debugger (I press F12 to get it) and if using Firefox then use the Firebug plugin, which is my preferred approach.

After each elem = ... put a breakpoint and make certain that you are getting the items you want.

I expect that the first alert may be the problem though, as your result from the ajax call may be getting cached. You need to make certain that your browser won't cache the response, but, I have found it best to set the header in the response to no-cache, but also to pass the current seconds + milliseconds in my request, though I never check that value, but, by putting it there it is unlikely that it will be repeated and so won't be pulled from the browser cache.

If the fact that you are using getElementsByTagName is incorrect, as you aren't checking for there to be any elements returned, you may be getting an error when you try to get the first element. You should do a sanity check when you should have at least one in a list and make certain the list is not empty. Firebug will show an error on the console if you are throwing an exception, which would explain why your update is not showing up.

If you don't want to use jQuery, if you can set the ids of the elements it would be better to use document.getElementById.

Sign up to request clarification or add additional context in comments.

Comments

0

I can't be sure since I don't know what error you're getting but maybe you want to set http.onreadystatechange = statechange_rate; after you open the connection but before you call send.

1 Comment

Maybe I'm placing your code in the wrong place but I still can't get it to work :(
0

First off I should ask, Are you sending an XML Content type header such as "text/xml" with your response from PHP? If not the responseXML property will not contain any content.

Here is what I think this code should look like:-

function vote(id, rating) { var http = getXHR() var fullurl = 'ajax.php?id=' + id + '&rating=' + rating;

if (http) { http.open("GET", fullurl, true); http.onreadystatechange = statechange_rate; http.send(null); }

function statechange_rate() { if (http.readyState == 4) { var xmlObj = http.responseXML; var result = http.responseXML.documentElement; var html = result.firstChild.data; var id = result.getAttribute("id"); var votes = result.getAttribute("votes"); var rating = result.getAttribute("rating");

elem = document.getElementById('output_' + id);

elem.innerHTML = "<br />" + html;
window.setTimeout(function() {elem.innerHTML = '';}, 5000);
if (votes != -1)
{
 document.getElementById('rating_' + id).innerHTML = rating;
 document.getElementById('votes_' + id).innerHTML = votes;
}

} } }

function getXHR() { if (window.XMLHttpRequest) { http = new XMLHttpRequest(); } else if (window.ActiveXObject) { http = new ActiveXObject("Microsoft.XMLHTTP"); } }

Notes:-

  • Assigned the call back to onreadystatechanged before calling send
  • I suspect the "results" element is the root element of the XML.
  • Use id attributes on HTML elements and getElementById to find them.
  • Extracted duplicate code from If

Comments

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.