2

I got some great help parsing some RSS into a menu yesterday using jQuery Parse RSS feed with JS, and inspired by this I would like to use something similar to control some chart bars on a website.

Some background:

We are aiming to use a floating score in our upcoming tech reviews on a webpage, meaning that you assign a product an absolute score (lets say 67) and then the maximum score would be able to move as new and better products hit the market. This way you would still be able to read a review from last year and use the score for something meaningful, as the score of 67 is now measured against this years max-score. Hope it makes sense.

Anyhow, our CMS only permits javascript to be embedded in news entries, so I can't store our review scores in SQL or use php, and I was thinking of using XML instead (not optimal, but it should work). Each review would then contain a certain number of results including the beforementioned final score (and some intermediate sub-scores as well). I need to be able to insert a piece of JS code that extracts the scores for a specific review from the XML file and inserts the HTML code needed to draw the bars.

I have a JSfiddle set up, that contains the XML, it has the chart (hardcoded though), and using the jQuery code from my previous question I can sort of extract the results, but the code loops through all the XML and I don't really have a clue how to pick out the specific review number I need nor how to get things measured against the max-score, so it just prints everything right now and calculates a score based on a max-score of 100. I haven't tied the values to my chart yet, so the test version just prints the results in a ul/li.

Link to JSFiddle

So basically I need some sort of code that I can invoke from my HTML that goes along the lines of

ShowScores(testno)

that would write everything inside the first

<div class="row">..</row> 

containing the bars, where the %-width of the bars would be calculated as the score assigned divided by the maxscore:

  • Each item has 3 assigned scores: scorePicture, scoreFeature, scoreUI, and 1 calculated total score (weighted average)
  • A global max score exists for each of the 3 scores: topscorePicture, topscoreFeature, topscoreUI

As I suck at JS, I have spent 5 hours getting to this point, and I have no clue how to make things load from e.g. a testscore.xml file instead and then extract what I need with jQuery - and I probably also need some help making my HTML load the script i.e. how to invoke it afterwards. The documentation on jQuery is concerned with loading all content in the XML and not just a specific node?

All help is appreciated.

My own thoughts on some pseudo code would be a script that, when envoked from my HTML document would do something like

function(reviewNo)
var max1 = load maxscore1 from XML
var max2 = load maxscore2 from XML
var max3 = load maxscore3 from XML

var score1 = load assignedscore1 for reviewNo from XML
var score2 = load assignedscore2 for reviewNo from XML
var score3 = load assignedscore2 for reviewNo from XML

Calculate % width of bar 1, bar 2 and bar 3 and save as variables as math.round()
write HTML DIV code and subsitute the width of the bars with the calculated values from above
Community
  • 1
  • 1

2 Answers2

0

Ok, so I figured that jQuery was not going to give me what I needed, so I turned to plain JS loading the XML with

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;
}

I then use the code in my HTML as:

<script>
    // Which test no should be loaded
    var testNo = 1;

    //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);

    //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+"%"+";\">"+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+"%"+";\">"+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+"%"+";\">"+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+"%"+";padding-top: 4px;\">"+scoreTotal+"%</div>";

    //Write the HTML
    document.write(HTMLchunkStart + pictureBar + HTMLchunk1+featureBar+HTMLchunk2+UIbar+HTMLchunk3+totalBar);
</script>

Currently I put this directly in my HTML, but I would like to put it in a separate file and simply call the code by e.g.

<script>showScore(1)</script>

To get the second entry in the XML. I am so close, but I would like a push in the right direction on how to make my code into a function that can accept a single input, which would be used as the "testNo" variable and then return all the HTML-code I have in my document.write at the end.

I also realise that my JS might not be the most efficient nor pretty, so any advice regarding clean-up is also welcome.

Another feature that comes to mind, would be the possibility to change the color of the bars according to the score. The current "progress-bar" class is just plain blue, but I could append another class to only change the colour. In my mind this would be possible by creating some classes for colours and then dependent on the % score the appropriate colour class would be added to the HTML code. If someone has an idea on how to do this I would also appreciate some input. Would I use a switch to pick the class names from an array or what?

0

Alright... talking a bit to myself here, but in the spirit of telling the entire story to anyone who might venture in here in the future, the current piece of code now uses a switch to set the HTML color for each of the four bars and the code is then inserted using the code described above, tossed into a function that is invoked using

<script>showScore(reveiwNo);</script>

inside my HTML. It works pretty well. I would like to link to the final code, but it is being used on our working templates for our new website, so I would rather keep them to myself until the site goes live - and I am not trying to advertise either.