4

Whether or not it's easily possible and done with Javascript I'm not sure but..

As shown in the code below, I've 5 players, each with a different score. I'm looking to code it so that it will automatically relist the players based off how high their score is. IDEALLY, I would also want to colour the first 3 rows to be gold-silver-bronze if that was possible.

Any help making this or pointing me in the right direction would be much appreciated. I'm not sure where I should start.

#container {
 width: 600px;
 height: auto;
}

.row {
 position: relative;
 display: block;
 width: 100%;
 height: 40px;
 border-bottom: 1px solid #AFAFAF;
}

.name {
 position: relative;
 display: inline-block;
 width: 75%;
 line-height: 45px;
}

.score {
 position: relative;
 display: inline-block;
 width: 25%;
}
<div id="container">
    <div class="row">
        <div class="name">Player1</div><div class="score">430</div>
    </div>
    
    <div class="row">
        <div class="name">Player2</div><div class="score">580</div>
    </div>
    
    <div class="row">
        <div class="name">Player3</div><div class="score">310</div>
    </div>
    
    <div class="row">
        <div class="name">Player4</div><div class="score">640</div>
    </div>
    
    <div class="row">
        <div class="name">Player5</div><div class="score">495</div>
    </div>
</div>
SteveyG
  • 69
  • 1
  • 1
  • 6
  • Do you have some kind of backend where you are retrieving these values? – Nick Tucci Dec 21 '17 at 05:04
  • 1
    Ideally, you should be showing some attempt at solving this yourself. StackOverflow is **not** a code writing service. For a start, you should consider using an HTML table as you do have tabular data. Are you populating the table with javascript or just looking to reorder it? As it stands your question is too broad for StackOverflow. – Jon P Dec 21 '17 at 05:05
  • A bit old but the principles are still the same: https://tympanus.net/codrops/2009/10/03/33-javascript-solutions-for-sorting-tables/ – Jon P Dec 21 '17 at 05:11

4 Answers4

9

You can make the first 3 rows the color you want by using nth-child()

/* Gold */
.row:nth-child(1) {background: gold;}
/* Silver */
.row:nth-child(2) {background: #c0c0c0;}
/* Bronze */
.row:nth-child(3) {background: #cd7f32;}

Next to sort the items you can put the rows into an array, then use sort to sort the items.

document.addEventListener('DOMContentLoaded', () => {
  let elements = []
  let container = document.querySelector('#container')
  // Add each row to the array
  container.querySelectorAll('.row').forEach(el => elements.push(el))
  // Clear the container
  container.innerHTML = ''
  // Sort the array from highest to lowest
  elements.sort((a, b) => b.querySelector('.score').textContent - a.querySelector('.score').textContent)
  // Put the elements back into the container
  elements.forEach(e => container.appendChild(e))
})
#container {
  width: 600px;
  height: auto;
}

.row {
  position: relative;
  display: block;
  width: 100%;
  height: 40px;
  border-bottom: 1px solid #AFAFAF;
}

.name {
  position: relative;
  display: inline-block;
  width: 75%;
  line-height: 45px;
}

.score {
  position: relative;
  display: inline-block;
  width: 25%;
}

.row:nth-child(1) {
  background: gold;
}

.row:nth-child(2) {
  background: #c0c0c0;
}

.row:nth-child(3) {
  background: #cd7f32;
}
<div id="container">
  <div class="row">
    <div class="name">Player1</div><div class="score">430</div>
  </div>

  <div class="row">
    <div class="name">Player2</div><div class="score">580</div>
  </div>

  <div class="row">
    <div class="name">Player3</div><div class="score">310</div>
  </div>

  <div class="row">
    <div class="name">Player4</div><div class="score">640</div>
  </div>

  <div class="row">
    <div class="name">Player5</div><div class="score">495</div>
  </div>
</div>
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
  • 2
    There is some css that required the divs to be on the same line for some reason (didn't look into it). But I fixed it. – Get Off My Lawn Dec 21 '17 at 05:20
  • 1
    Ah thank you so much for that buddy that's perfect. Sorry to get you to write all of the script. I just wasn't sure where to start and couldn't find anything overly similar/simple on the web to go about it. Upvoted :) – SteveyG Dec 23 '17 at 02:35
4

I do believe you will have a much more pleasant time here if you represent your data structure with Javascript rather than HTML. What you are describing to me sounds like a collection of data, and in this case I'd make it a Javascript array of objects.

const playerArray = [
  {name: "Player1", score: "430", id:"player1"},
  {name: "Player2", score: "580"}, id:"player2"},
  {name: "Player3", score: "310"}, id:"player3"},
  {name: "Player4", score: "640" id:"player4"},
  {name: "Player5", score: "495", id:"player5"}
]

Then sorting this array based on the "score property of the objects is a bit tricky, but with the help of this stack overflow answer I'd say you can write it like this:

function compare(a,b) { return b.score - a.score }

playerArray.sort(compare);

You would then call this sort method each time a player joined , left, submitted a score, etc (anything that modifies the playerArray).

You could then remove all gold, silver, bronze styling from all the rows and then add add the gold color with

document.getElementById(playerArray[0].id).style.background: gold;
document.getElementById(playerArray[1].id).style.background: #c0c0c0;
document.getElementById(playerArray[2].id).style.background: #cd7f32;;

As a side note, a front-end framework such as angular or react could allow you more more easily keep your ui updated based on the Javascript collection and with a more declarative syntax.

Jim
  • 3,821
  • 1
  • 28
  • 60
2

you can use the highlight class for coloring your rows, here is the fiddle

http://jsfiddle.net/fgybyem2/15/

var $divs = $("div.row");
$(document).ready(function () {
    var numericallyOrderedDivs = $divs.sort(function (a, b) {
        return $(a).find(".score").text() > $(b).find(".score").text();
    });
    $("#container").html(numericallyOrderedDivs);    

   $("#container").find(".row:eq(0)").addClass("highLight");
   $("#container").find(".row:eq(1)").addClass("highLight") 
   $("#container").find(".row:eq(2)").addClass("highLight");



});
Om Ray
  • 21
  • 8
0

A naive approach would be dynamically create HTML elements for each row in the leader board when the data (the scores) changes.

    <div id="leaderboard" class="container">
        <!-- scores will be inserted by the script here -->
    </div>
    <button onclick="randomize()">Randomize</button>
    <script src="script.js"></script>

script.js

let scores = [
    {name: "Player 1", score: 300},
    {name: "Player 2", score: 370},
    {name: "Player 3", score: 500},
    {name: "Player 4", score: 430},
    {name: "Player 5", score: 340},
];

function updateLeaderboardView() {
    let leaderboard = document.getElementById("leaderboard");
    leaderboard.innerHTML = "";

    scores.sort(function(a, b){ return b.score - a.score  });
    let elements = []; // we'll need created elements to update colors later on
    // create elements for each player
    for(let i=0; i<scores.length; i++) {
        let name = document.createElement("div");
        let score = document.createElement("div");
        name.classList.add("name");
        score.classList.add("score");
        name.innerText = scores[i].name;
        score.innerText = scores[i].score;

        let scoreRow = document.createElement("div");
        scoreRow.classList.add("row");
        scoreRow.appendChild(name);
        scoreRow.appendChild(score);
        leaderboard.appendChild(scoreRow);

        elements.push(scoreRow);

    }

    let colors = ["gold", "silver", "#cd7f32"];
    for(let i=0; i < 3; i++) {
        elements[i].style.color = colors[i];
    }
}

updateLeaderboardView();
function randomize() {
    for(var i=0; i<scores.length; i++) {
        scores[i].score = Math.floor(Math.random() * (600 - 300 + 1)) + 300;
    }
    // when your data changes, call updateLeaderboardView
    updateLeaderboardView();
}