-1

I originally set out to do an XML parse (single node) using jQuery, but had no luck so I ended up using plain Javascript instead. The code is found in this thread: Parse XML using JS

Now I can see that the way I use XMLhttpRequest function is deprecated and might be removed in the future, which would ruin quite a lot on my homepage XMLhttpRequest and Google inspector also reports

Synchronous XMLHttpRequest outside of workers is in the process of being removed from the web platform as it has detrimental effects to the end user's experience

I would like to re-open the original question, and get help rewriting the below to load my XML without using the async=false in my code

xhttp.open("GET",filename,false);

The code is being invoked about 9/10 down in my HMTL-code, but simply changing "false" to "true" is no good, as nothing loads at all (I guess the code moves on before it has a chance to insert the XML-data?). With my weak abilities in JS I had to google to find some answers that points to: W3C on send/get

How would I change my code to avoid using the "false" statement?

The XML would look like:

<scoreresults>
<topscorePicture>100</topscorePicture>
<topscoreFeature>100</topscoreFeature>
<topscoreUI>100</topscoreUI>
<item>
<title>
<![CDATA[ Test sample 1 ]]>
</title>
<link>    Somelink    </link>
<guid isPermaLink="true">   Somelink      </guid>
<scorePicture>82</scorePicture>
<scoreFeature>90</scoreFeature>
<scoreUI>85</scoreUI>
<measurePowerOTB>180</measurePowerOTB>
<measurePowerCAL>160</measurePowerCAL>
<measurePowerSTANDBY>0.2</measurePowerSTANDBY>
<measureContrastOTB>2000</measureContrastOTB>
<measureContrastCAL>2200</measureContrastCAL>
<measureBrightnessOTB>210</measureBrightnessOTB>
<measureBrightnessCAL>130</measureBrightnessCAL>
</item>
</scoreresults>

The script reads:

function loadXMLDoc(filename)
{
if (window.XMLHttpRequest)
  {
  xhttp=new XMLHttpRequest();
  }
else // code for IE5 and IE6
  {
  xhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xhttp.open("GET",filename,false);
xhttp.send();
return xhttp.responseXML;
}



function showTVscore(testNo) {

    //Load the XML
    xmlDoc = loadXMLDoc("/testscores.xml");

    //Extract the highest score for picture
    tsp = xmlDoc.getElementsByTagName("topscorePicture")[0];
    topspvalue = tsp.childNodes[0];

    //Extract highest score for features
    tsf = xmlDoc.getElementsByTagName("topscoreFeature")[0];
    topsfvalue = tsf.childNodes[0];

    //Extract highest score for UI
    tsui = xmlDoc.getElementsByTagName("topscoreUI")[0];
    topsuivalue = tsui.childNodes[0];

    //Extract  picture score for the specific test no.
    sp = xmlDoc.getElementsByTagName("scorePicture")[testNo];
    spvalue = sp.childNodes[0];

    //Extract Feature score for the specific test no.
    sf = xmlDoc.getElementsByTagName("scoreFeature")[testNo];
    sfvalue = sf.childNodes[0];

    //Extract UI score for the specific test no.
    sui = xmlDoc.getElementsByTagName("scoreUI")[testNo];
    suivalue = sui.childNodes[0];

    //Calculate current scores
    scorePicture = Math.round(Number(spvalue.nodeValue) / Number(topspvalue.nodeValue) * 100);
    scoreFeature = Math.round(Number(sfvalue.nodeValue) / Number(topsfvalue.nodeValue) * 100);
    scoreUI = Math.round(Number(suivalue.nodeValue) / Number(topsuivalue.nodeValue) * 100);
    scoreTotal = Math.round(0.5 * scorePicture + 0.25 * scoreFeature + 0.25 * scoreUI);

    //Set color of Picture scorebar
    switch (Math.round(scorePicture / 10)) {
        case 1:
            pictureColor = "#934F00";
            break;
        case 2:
            pictureColor = "#C36900";
            break;
        case 3:
            pictureColor = "#F28200";
            break;
        case 4:
            pictureColor = "C38D00";
            break;
        case 5:
            pictureColor = "#F2AF00";
            break;
        case 6:
            pictureColor = "#07ABFB";
            break;
        case 7:
            pictureColor = "#008ED3";
            break;
        case 8:
            pictureColor = "#006699";
            break;
        case 9:
            pictureColor = "#00537B";
            break;
        case 10:
            pictureColor = "#003F5D";
            break;
    };
    //Set color of Feature scorebar
    switch (Math.round(scoreFeature / 10)) {
        case 1:
            featureColor = "#934F00";
            break;
        case 2:
            featureColor = "#C36900";
            break;
        case 3:
            featureColor = "#F28200";
            break;
        case 4:
            featureColor = "C38D00";
            break;
        case 5:
            featureColor = "#F2AF00";
            break;
        case 6:
            featureColor = "#07ABFB";
            break;
        case 7:
            featureColor = "#008ED3";
            break;
        case 8:
            featureColor = "#006699";
            break;
        case 9:
            featureColor = "#00537B";
            break;
        case 10:
            featureColor = "#003F5D";
            break;
    };
    //Set color of UI scorebar
    switch (Math.round(scoreUI / 10)) {
        case 1:
            uiColor = "#934F00";
            break;
        case 2:
            uiColor = "#C36900";
            break;
        case 3:
            uiColor = "#F28200";
            break;
        case 4:
            uiColor = "C38D00";
            break;
        case 5:
            uiColor = "#F2AF00";
            break;
        case 6:
            uiColor = "#07ABFB";
            break;
        case 7:
            uiColor = "#008ED3";
            break;
        case 8:
            uiColor = "#006699";
            break;
        case 9:
            uiColor = "#00537B";
            break;
        case 10:
            uiColor = "#003F5D";
            break;
    };
    //Set color of total scorebar
    switch (Math.round(scoreTotal / 10)) {
        case 1:
            totalColor = "#934F00";
            break;
        case 2:
            totalColor = "#C36900";
            break;
        case 3:
            totalColor = "#F28200";
            break;
        case 4:
            totalColor = "C38D00";
            break;
        case 5:
            totalColor = "#F2AF00";
            break;
        case 6:
            totalColor = "#07ABFB";
            break;
        case 7:
            totalColor = "#008ED3";
            break;
        case 8:
            totalColor = "#006699";
            break;
        case 9:
            totalColor = "#00537B";
            break;
        case 10:
            totalColor = "#003F5D";
            break;
    };

    //Construct HTML
    HTMLchunkStart = "<div style=\"float: Right; text-align: right; width: 40px; font-weight: 500; padding-left: 20px; color: #666;\"><i class=\"fa fa-picture-o\"></i></div><div class=\"progress\" style=\"background-color:#E2E2E2\">";
    pictureBar = "<div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"" + Number(spvalue.nodeValue) + "\" aria-valuemin=\"0\" aria-valuemax=\"" + Number(topspvalue.nodeValue) + "\" style=\"width:" + scorePicture + "%; background-color:" + pictureColor + ";\">" + scorePicture + "%</div>";
    HTMLchunk1 = "</div> <div style=\"float: Right; text-align: right; width: 40px; font-weight: 500; padding-left: 20px; color: #666;\"><i class=\"fa fa-cogs\"></i></div><div class=\"progress\" style=\"background-color:#E2E2E2\">";
    featureBar = "<div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"" + Number(sfvalue.nodeValue) + "\" aria-valuemin=\"0\" aria-valuemax=\"" + Number(topsfvalue.nodeValue) + "\" style=\"width:" + scoreFeature + "%; background-color:" + featureColor + "\">" + scoreFeature + "%</div>";
    HTMLchunk2 = " </div><div style=\"float: Right; text-align: right; width: 40px; font-weight: 500; padding-left: 20px; color: #666;\"><i class=\"fa fa-user\"></i></div><div class=\"progress\" style=\"background-color:#E2E2E2\">";
    UIbar = "<div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"" + Number(suivalue.nodeValue) + "\" aria-valuemin=\"0\" aria-valuemax=\"" + Number(topsuivalue.nodeValue) + "\" style=\"width:" + scoreUI + "%; background-color:" + uiColor + ";\">" + scoreUI + "%</div>";
    HTMLchunk3 = "</div> <div style=\"padding-top: 3px;float: Right; text-align: right; width: 40px; font-weight: 500; padding-left: 20px; color: #666;\"><i class=\"fa fa-star\"></i></div><div class=\"progress progress-lg\" style=\"background-color:#E2E2E2;height: 30px;\">";
    totalBar = "<div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"" + scoreTotal + "\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width:" + scoreTotal + "%; background-color:" + totalColor + ";font-size:1.1em;font-weight:600;\">Total: " + scoreTotal + "%</div></div>";

    //Write the HTML
    document.write(HTMLchunkStart + pictureBar + HTMLchunk1 + featureBar + HTMLchunk2 + UIbar + HTMLchunk3 + totalBar);
}
8
  • Parsing XML and retrieving data through AJAX are different tasks. Which one do you have difficulties with? Commented May 15, 2015 at 7:44
  • The above code works, but the function I use is being phased out. I was hoping to translate the above to jQuery instead e.g. by using $.get("testscores.xml", function(data) {... some code...} but I already tried getting there (see link in thread above) with no luck. I couldn't get jQuery to load the three global scores and neither simply exracting only one XML-item corresponding the whatever "testNo" is set to. Commented May 15, 2015 at 7:53
  • Simply put I would like to avoid being struck by browser phasing out XMLHttpRequest however possible. I just thought of jQuery as the obvious choice. Commented May 15, 2015 at 8:02
  • I've removed my answer since I failed to understand the question. I suggest you update the question and add an explanation of how exactly your code fails to work. Commented May 15, 2015 at 11:21
  • Question updated as I realised the same. The code works, but I get a warning in the console of my browsers because of the "false" statement used to open my XML. Commented May 15, 2015 at 11:24

2 Answers 2

0

Instead of returning a value from loadXMLDoc, pass it a callback function.

Add a readystatechange event handler and, when you have successfully loaded the data, call that function and pass it an argument.

function loadXMLDoc(filename, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", filename);
  xhr.onreadystatechange = function () {
    if (this.readyState === 4 && this.status === 200) {
       callback(this.responseXML);  
    }
  };
  xhr.send();
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your reply. I might not have pointed out clearly enough how much I suck at this, but how would that play out in the above, if I remove my current load-function and replace it with yours? Something else would need to be changed as well I imagine? What does the "responseXML" refer to?
Yes. You'd need to move the code that depends on the data into the callback function. responseXML refers to exactly the same thing it does in your existing code.
I apologize for being tad slow, but I have the showTVscore(var) that depends on the load, which writes the missing HTML code by document.write(...). So I move all of this code into the callback(...) brackets and instead of invoking the code by calling showTVscore(var) I would call the load function (and add the var I need to load the right node in the XML)?
0

OK, I figured out how to get things working with jQuery instead, so I will be using that method as all my other scripts use jQuery also.

Here is what I ended up with:

<script>
function showTVscore(x){
    // load the xml data. it is parsed by jquery
    $.get("testscores.xml", function(data) {
        var $xml = $(data);
        var y = $xml.find("item").length;
        topScorePic = parseInt($xml.find("topscorePicture").text());
        topScoreFeature = parseInt($xml.find("topscoreFeature").text());
        topScoreUI = parseInt($xml.find("topscoreUI").text());

        $xml.find("item").each(function(i, val) { // find the items in the xml and loop     
            // create an item object with all the necessary information out of the xml
            var $this = $(this),
                item = {
                    title: $this.find("title").text(),
                    link: $this.find("link").text(),
                    TopAward: $this.find("TopAward").text(),
                    RefAward: $this.find("RefAward").text(),
                    scorePic: parseInt($this.find("scorePicture").text(),10),
                    scoreFeature: parseInt($this.find("scoreFeature").text(),10),
                    scoreUI: parseInt($this.find("scoreUI").text(),10),
                    pricerunner: $this.find("pricerunnerLINK").text(),
                    year: $this.find("year").text(),
                };
            //Calculate scores relative to max values   
            scorePic = Math.round(item.scorePic / topScorePic*100);
            scoreFeature = Math.round(item.scoreFeature / topScoreFeature *100);
            scoreUI = Math.round(item.scoreUI / topScoreUI *100);           

            //Calculate total score
            totalScore = Math.round(0.5*item.scorePic + 0.25*(item.scoreFeature + item.scoreUI));

            // div with id "score" has the appropriate XML node added
            if(item.title == x){    
                $('#score').append($(
                    //HTML code that loads everything goes here...
                 ));
            }
            return i<(y-1); // (stop after y iterations)
        });
    });
};
</script>

And the code is then used on my page as

<div class="col-xs-12 col-sm-6">
    <div id="score">
    </div>
</div>
<script>showTVscore('title of node I want to load)');</script>

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.