Andrew C Andrew C - 1 month ago 9
Javascript Question

Is there a way to create rating images (5 stars, 4 stars, 3 stars, etc...) inside an array in JavaScript and output it all as a table in HTML?

The code below is what I've been working on. I think my logic is flawed when I rate products based on their calculated scores, which is where I'm getting mixed up. And I'm also unsure how to create rating images based on the scores. The first column in the arrays is the score value, the second column is the product ID, the third column is the name of the product, and the fourth column is the link to the brand websites. I want to output an image in the fifth column that will reflect the score of the product. For example, if I'm sorting the products based on score and I want the products with the highest scores listed first, then it should be products[1] with a 5 star image, products[3] with a 4 star image, products[0] with a 3 star image, products[4] with a 2 star image, and products[2] with a 1 star image. NOTE: for some reason language="JavaScript" works for me and type="text/javascript" does not. If someone could provide any guidance for this code I would sincerely and greatly appreciate. Thank you very much in advance :)

HTML:

<table id="table">
<tr id="tbody">
<th>Score</th>
<th>ID</th>
<th>Name</th>
<th>Website</th>
<th>Rating</th>
</tr>
</table>


JAVASCRIPT:


var products = new Array(5);
products[0] = [26, 4859, "Panasonic TV", "http://www.panasonic.com"];
products[1] = [37, 4762, "Sony TV", "http://www.sony.com"];
products[2] = [9, 4899, "LG TV", "http://www.lg.com"];
products[3] = [34, 5001, "Samsung TV", "http://www.samsung.com"];
products[4] = [22, 3425, "Vizio TV", "http://www.vizio.com"];

function Comparator(a,b) {
if (if (a[0] > b[0]) return -1;
if (a[0] < b[0]) return 1;
return 0;
}

var productsSorted = products.sort(Comparator);

for (i=0; i<products.length, i++) {
if (products[0] === 37) {
document.getElementById("IMG5");
} else if (products[0] === 34) {
document.getElementById("IMG4");
} else if (products[0] === 26) {
document.getElementById("IMG3");
} else if (products[0] === 22) {
document.getElementById("IMG2");
} else {
document.getElementById("IMG1");
};


table.appendChild(tbody);
productsSorted.forEach(function(item) {

var row = document.createElement("tr");

var score = document.createElement("td");
score.textContent = item[0];

var ID= document.createElement("td");
ID.textContent = item[1];

var name = document.createElement("td");
name.textContext = item[2];

var link_td = document.createElement("td");
var link = document.createElement("a");
link.textContent = item[3]
link.href = item[3]
link_td.appendChild(link);

var rating = new Array(5);
var rating_td = document.createElement("td");
var rating[0] = document.createElement("IMG5");
rating.setAttribute("src","http://dkcoin8.com/images/five-star-clipart-4.png");
var rating[1] = document.createElement("IMG4");
rating.setAttribute("src","http://aliviogroup.com.au/wp-content/uploads/2016/04/four-stars.jpg");
var rating[2] = document.createElement("IMG3");
rating.setAttribute("src","https://waytoomuchtelevision.files.wordpress.com/2011/01/3star.jpg");
var rating[3] = document.createElement("IMG2");
rating.setAttribute("src","https://authorjanedoe.files.wordpress.com/2012/07/2star.jpg");
var rating[4] = document.createElement("IMG1");
rating.setAttribute("src","http://clipart.printcolorcraft.com/wp-content/uploads/stars/smooth%20star.jpg");
rating_td.appendChild(rating);


row.appendChild(score);
row.appendChild(ID);
row.appendChild(name);
row.appendChild(link);
row.appendChild(rating);

table.appendChild(row);
});

Answer Source

Create a png of a star where the background is white and the star is transparent. Put a row of 5 of them side-by-side in the div (or td in your case). Create another image of a yellow rectangle. Set the background of the div/td of stars to the yellow rectangle. Set the background-size parameter of the div/td as a percentage based on the score. So if the average score is 70% then 70% of the background will be yellow, resulting in 3 yellow stars, one star partially filled in yellow, and one unfilled star.

Speaking of the score... they appear to be sums of scores. If that's the case then you should either calculate the average instead of the sum and put that in the first column, or include a count of the number of ratings so you can calculate the average score. For example if the score 9 is the result of a 4/5 and a 5/5, then your actual score is 9/10 or 90%.

function createRows() {
  var products = new Array(5);
  products[0] = [84, 4859, "Panasonic TV", "http://www.panasonic.com"];
  products[1] = [73, 4762, "Sony TV", "http://www.sony.com"];
  products[2] = [90, 4899, "LG TV", "http://www.lg.com"];
  products[3] = [88, 5001, "Samsung TV", "http://www.samsung.com"];
  products[4] = [44, 3425, "Vizio TV", "http://www.vizio.com"];
  var items = document.getElementById("items");

	Array.prototype.forEach.call(products, function(prod) {
    var row = document.createElement("div");
    row.className = "row";
    var fields = new Array(4);
    var field_num = 0;
    Array.prototype.forEach.call(prod, function(field) {
    	fields[field_num] = document.createElement("div");
    	fields[field_num].className = "field";
      if (field_num > 0) {
      	fields[field_num].innerHTML = prod[field_num];
        fields[field_num].id = "field" + field_num;
      }
      row.append(fields[field_num]);
      field_num++;
    });
    fields[0].id = "rating";
    fields[0].style.backgroundSize = prod[0] + "% 50px";
    for (i=0; i < 5; i++) {
      var star = document.createElement("img");
      star.src = "https://i.imgur.com/jxqW2CC.png";
      fields[0].append(star);
    }
    items.append(row);
  });
}
createRows();
.field {
  display: inline-block;
  line-height: 19px;
  vertical-align: top;
  padding: 3px 5px;
}
#field1 {
  width: 50px;
  border-right: 1px solid black;
  height: 100%;
}
#field2 {
  width: 100px;
  border-right: 1px solid black;
}
.row {
  border: 1px solid black;
  margin: 5px;
  font: 14px Arial, sans-serif;
  background: white;
}
#rating {
  height: 25px;
  width: 125px;
  padding: 0px;
  border-right: 1px solid black;
  background: #ccc url(http://weclipart.com/gimg/827E9394EC65E95F/12e902ef8c564cdfb22cf736428a35cf-800.png) no-repeat;
}
#rating img {
  height: 25px;
  padding: 0px;
}
<div id="items">
</div>