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>
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>
Share
Improve this question
asked Dec 21, 2017 at 4:58
SteveyGSteveyG
591 gold badge1 silver badge6 bronze badges
3
- Do you have some kind of backend where you are retrieving these values? – Nick Tucci Commented Dec 21, 2017 at 5: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 Commented Dec 21, 2017 at 5:05
- A bit old but the principles are still the same: tympanus.net/codrops/2009/10/03/… – Jon P Commented Dec 21, 2017 at 5:11
4 Answers
Reset to default 8You 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>
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.
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");
});
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();
}