Reputation: 156
I'm in the process of making a tournament bracket programmatically based on data from a database. In my PHP code, it sets the top padding for each match in order to place each match in the correct position so that it looks like a tournament bracket. Within each match there are two divs that each contain two divs. One for the players' name and handicap, and another for the players' score. In order to make it so that the divs for the player's names and scores were side by side, I added
.player_1 div {
float: left;
}
.player_2 div {
float: left;
}
to the CSS file, but when doing so, it messed up the padding I had set previously. Strangely, I've found that removing float: left for either one of the divs will fix the padding, but having both creates a problem.
PHP/HTML code:
<?php
require_once 'core/init.php';
$con = mysqli_connect(Config::get('mysql/host'), Config::get('mysql/username'), Config::get('mysql/password'), Config::get('mysql/db'));
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
if(isset($_GET['id'])) {
// Figure out how many rounds are in the tournament
// if it's a single elimination format.
$query = "SELECT *
FROM `tournaments`
WHERE `id`=" . $_GET['id'] . ";";
$tournament = mysqli_fetch_array(mysqli_query($con, $query));
$format = $tournament['format'];
$total_players = $tournament['players'];
$rounds = 1;
while(pow(2, $rounds) < $total_players) {
$rounds++;
}
// Adjust amount of rounds if not single elimination
// format and create most of the HTML.
if($tournament['format'] == "Single Elimination") {
$margin_top = 0;
$margin_standard = 40;
for($i = 1; $i <= $rounds; $i++) {
echo "<div class='round'>";
for($j = 1; $j <= pow(2, $rounds - $i); $j++) {
$margin = 0;
$margin_bottom = 0;
if($j == 1) {
$margin = $margin_top;
} else {
$margin = $margin_standard;
}
if($j == pow(2, $rounds - $i)) {
$margin_bottom = 40;
}
echo "<div class='match' round='" . $i . "' num='" . $j . "' winner_side='true' style='padding-top:" . $margin . "px; padding-bottom:" . $margin_bottom . "px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div>";
}
$margin_top = $margin_standard + 3;
$margin_standard = $margin_top * 2 + 40;
echo "</div>";
}
} else if($tournament['format'] == "Single Modified (Reverse Seeded)") {
$rounds++;
}else if($tournament['format'] == "Single Elimination (Seeded)") {
$rounds++;
}else if($tournament['format'] == "Single Elimination (Split Bracket)") {
$rounds++;
} else if($tournament['format'] == "Double Elimination") {
$rounds++;
}
// Get ID numbers of all players in the tournament.
$players = array();
$query = "SELECT DISTINCT `winner_id` AS `id`
FROM `matches`
WHERE `tournament_id`=" . $_GET['id'] .
" UNION SELECT DISTINCT `loser_id` AS `id`
FROM `matches`
WHERE `tournament_id`=" . $_GET['id'] .
" ORDER BY `id` ASC;";
$ids = mysqli_query($con, $query);
while($row = mysqli_fetch_array($ids)) {
if($row['id'] != 0) {
array_push($players, array("id" => $row['id'], "name" => ""));
}
}
// Get names of players based on their ID numbers.
for($i = 0; $i < count($players); $i++) {
$query = "SELECT `first_name`, `last_name`
FROM `players`
WHERE `id`=" . $players[$i]["id"] . ";";
$players[$i]["name"] = mysqli_fetch_array(mysqli_query($con, $query))['first_name'] .
" " . mysqli_fetch_array(mysqli_query($con, $query))['last_name'];
}
// Retrieve match data
$matches = array();
$query = "SELECT *
FROM `matches`
WHERE `tournament_id`=" . $_GET['id'] . ";";
$match_data = mysqli_query($con, $query);
while($row = mysqli_fetch_array($match_data)) {
array_push($matches, array("winner_id" => $row['winner_id'],
"loser_id" => $row['loser_id'],
"winner_score" => $row['winner_score'],
"loser_score" => $row['loser_score'],
"winner_handicap" => $row['winner_elo'],
"loser_handicap" => $row['loser_elo'],
"spot" => $row['spot'],
"length" => $row['length'],
"round" => $row['round'],
"num" => $row['match_num'],
"winner_side" => $row['winner_side']));
}
}
mysqli_close($con);
?>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Bracket</title>
<link rel="stylesheet" type="text/css" href="css/bracket.css">
<script type="text/javascript">
var format = "<?php echo $format; ?>";
var players = <?php echo json_encode($players); ?>;
var match_data = <?php echo json_encode($matches); ?>;
var matches = document.getElementsByClassName("match");
function getMatch(round, num, winner_side) {
for(n = 0; n < matches.length; n++) {
if(matches[n].getAttribute("round") == round &&
matches[n].getAttribute("num") == num &&
matches[n].getAttribute("winner_side") == winner_side) {
return matches[n];
}
}
}
function getData(round, num, winner_side) {
if(winner_side = "true") {
winner_side = 1;
}
for(n = 0; n < match_data.length; n++) {
var data = match_data[n];
if(data["round"] == round &&
data["num"] == num &&
data["winner_side"] == winner_side) {
return data;
}
}
}
function getName(id) {
for(n = 0; n < players.length; n++) {
if(players[n]["id"] == id) {
return players[n]["name"];
}
}
}
for(i = 0; i < matches.length; i++) {
var match = matches[i];
var p1 = match.getElementsByClassName("player")[0];
var p2 = match.getElementsByClassName("player")[1];
var p1_score = match.getElementsByClassName("score")[0];
var p2_score = match.getElementsByClassName("score")[1];
var data = getData(match.getAttribute("round"),
match.getAttribute("num"),
match.getAttribute("winner_side"));
if(match.getAttribute("round") == 1 &&
match.getAttribute("winner_side") == "true") {
p1.innerHTML = getName(data["winner_id"]) + " " + Math.floor(data["winner_handicap"]);
p1_score.innerHTML = data["winner_score"];
if(data["loser_id"] != 0) {
p2.innerHTML = getName(data["loser_id"]) + " " + Math.floor(data["loser_handicap"]);
p2_score.innerHTML = data["loser_score"];
} else {
p2.innerHTML = "Bye";
p2_score.innerHTML = data["loser_score"];
}
p2.className = "player loser";
} else {
// Set winners and losers into next match.
switch(format) {
case "Single Elimination":
var feeder_match = getMatch(match.getAttribute("round") - 1, match.getAttribute("num") * 2 - 1, "true");
var feeder_data = getData(feeder_match.getAttribute("round"),
feeder_match.getAttribute("num"),
feeder_match.getAttribute("winner_side"));
var p1_id = feeder_data["winner_id"];
var p1_handicap = 0;
if(p1_id == data["winner_id"]) {
p1_handicap = Math.floor(data["winner_handicap"]);
p1_score.innerHTML = data["winner_score"];
} else {
p1_handicap = Math.floor(data["loser_handicap"]);
p1_score.innerHTML = data["loser_score"];
p1.className = "player loser";
}
p1.innerHTML = getName(p1_id) + " " + p1_handicap;
feeder_match = getMatch(match.getAttribute("round") - 1, match.getAttribute("num") * 2, "true");
feeder_data = getData(feeder_match.getAttribute("round"),
feeder_match.getAttribute("num"),
feeder_match.getAttribute("winner_side"));
var p2_id = feeder_data["winner_id"];
var p2_handicap = 0;
if(p2_id == data["winner_id"]) {
p2_handicap = Math.floor(data["winner_handicap"]);
p2_score.innerHTML = data["winner_score"];
} else {
p2_handicap = Math.floor(data["loser_handicap"]);
p2_score.innerHTML = data["loser_score"];
p2.className = "player loser";
}
p2.innerHTML = getName(p2_id) + " " + p2_handicap;
break;
case "Single Modified (Reverse Seeded)":
break;
case "Single Modified (Seeded)":
break;
case "Single Modified (Split Bracket)":
break;
case "Double Elimination":
break;
}
}
}
</script>
</head>
</html>
CSS file:
@CHARSET "ISO-8859-1";
.round {
float: left;
}
.match {
margin-right: 50px;
}
.player_1 div {
float: left;
}
.player_2 div {
float: left;
}
.player {
width: 160px;
height: 20px;
background: rgb(210,210,210);
border: 2px solid red;
}
.score {
width: 20px;
height: 20px;
background: rgb(210,210,210);
border-top: 2px solid red;
border-right: 2px solid red;
border-bottom: 2px solid red;
text-align: center;
}
.round .match:first-child {
margin-top: 40px;
}
.player_1 .player {
background: rgb(240,240,240);
border-bottom-width: 0px;
}
.player_1 .score {
background: rgb(240,240,240);
border-bottom-width: 0px;
}
.loser {
color: rgba(0,0,0,0.5);
}
Page Source:
<div class='round'><div class='match' round='1' num='1' winner_side='true' style='padding-top:0px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='1' num='2' winner_side='true' style='padding-top:40px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='1' num='3' winner_side='true' style='padding-top:40px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='1' num='4' winner_side='true' style='padding-top:40px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='1' num='5' winner_side='true' style='padding-top:40px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='1' num='6' winner_side='true' style='padding-top:40px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='1' num='7' winner_side='true' style='padding-top:40px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='1' num='8' winner_side='true' style='padding-top:40px; padding-bottom:40px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div></div><div class='round'><div class='match' round='2' num='1' winner_side='true' style='padding-top:43px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='2' num='2' winner_side='true' style='padding-top:126px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='2' num='3' winner_side='true' style='padding-top:126px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='2' num='4' winner_side='true' style='padding-top:126px; padding-bottom:40px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div></div><div class='round'><div class='match' round='3' num='1' winner_side='true' style='padding-top:129px; padding-bottom:0px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div><div class='match' round='3' num='2' winner_side='true' style='padding-top:298px; padding-bottom:40px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div></div><div class='round'><div class='match' round='4' num='1' winner_side='true' style='padding-top:301px; padding-bottom:40px'>
<div class='player_1'>
<div class='player'></div>
<div class='score'></div>
</div>
<div class='player_2'>
<div class='player'></div>
<div class='score'></div>
</div>
</div></div><html>
<head>
<meta charset="ISO-8859-1">
<title>Bracket</title>
<link rel="stylesheet" type="text/css" href="css/bracket.css">
<script type="text/javascript">
var format = "Single Elimination";
var players = [{"id":"1","name":"Etan Mizrahi"},{"id":"2","name":"David Rau"},{"id":"13","name":"David Richardson"},{"id":"20","name":"Glenn Umemoto"},{"id":"23","name":"Robert Farwell"},{"id":"29","name":"David Espinoza"},{"id":"31","name":"Kenny Ash"},{"id":"36","name":"Ron Ramirez"},{"id":"49","name":"Fernando Perez"},{"id":"52","name":"Andrew DiDomenico"},{"id":"57","name":"Mark Davidson"},{"id":"64","name":"Senai Tesfay"},{"id":"70","name":"Sam Paniccia Jr"},{"id":"71","name":"Jaynard Orque"},{"id":"74","name":"Daiby Fuentes"},{"id":"97","name":"Dan Ramirez"}];
var match_data = [{"winner_id":"74","loser_id":"13","winner_score":"5","loser_score":"1","winner_handicap":"58.2473","loser_handicap":"71.7218","spot":"1","length":"5","round":"1","num":"1","winner_side":"1"},{"winner_id":"1","loser_id":"23","winner_score":"6","loser_score":"5","winner_handicap":"83.1698","loser_handicap":"55.7582","spot":"2","length":"6","round":"1","num":"2","winner_side":"1"},{"winner_id":"71","loser_id":"49","winner_score":"5","loser_score":"4","winner_handicap":"148.935","loser_handicap":"39.8198","spot":"3","length":"5","round":"1","num":"3","winner_side":"1"},{"winner_id":"20","loser_id":"97","winner_score":"5","loser_score":"3","winner_handicap":"79.4228","loser_handicap":"69.4227","spot":"0","length":"5","round":"1","num":"4","winner_side":"1"},{"winner_id":"64","loser_id":"2","winner_score":"5","loser_score":"4","winner_handicap":"20.6482","loser_handicap":"53.0454","spot":"3","length":"5","round":"1","num":"5","winner_side":"1"},{"winner_id":"52","loser_id":"57","winner_score":"5","loser_score":"1","winner_handicap":"32.1528","loser_handicap":"66.9517","spot":"3","length":"5","round":"1","num":"6","winner_side":"1"},{"winner_id":"36","loser_id":"70","winner_score":"5","loser_score":"2","winner_handicap":"70.1245","loser_handicap":"59.2356","spot":"0","length":"5","round":"1","num":"7","winner_side":"1"},{"winner_id":"31","loser_id":"29","winner_score":"5","loser_score":"3","winner_handicap":"77.629","loser_handicap":"85.0481","spot":"0","length":"5","round":"1","num":"8","winner_side":"1"},{"winner_id":"1","loser_id":"74","winner_score":"4","loser_score":"2","winner_handicap":"83.7599","loser_handicap":"59.8936","spot":"1","length":"4","round":"2","num":"1","winner_side":"1"},{"winner_id":"20","loser_id":"71","winner_score":"5","loser_score":"4","winner_handicap":"80.3158","loser_handicap":"148.725","spot":"2","length":"5","round":"2","num":"2","winner_side":"1"},{"winner_id":"64","loser_id":"52","winner_score":"4","loser_score":"0","winner_handicap":"21.3373","loser_handicap":"33.4036","spot":"0","length":"4","round":"2","num":"3","winner_side":"1"},{"winner_id":"31","loser_id":"36","winner_score":"5","loser_score":"2","winner_handicap":"78.678","loser_handicap":"71.4888","spot":"0","length":"5","round":"2","num":"4","winner_side":"1"},{"winner_id":"20","loser_id":"1","winner_score":"5","loser_score":"1","winner_handicap":"80.7612","loser_handicap":"84.8921","spot":"0","length":"5","round":"3","num":"1","winner_side":"1"},{"winner_id":"31","loser_id":"64","winner_score":"5","loser_score":"4","winner_handicap":"80.1299","loser_handicap":"23.4533","spot":"3","length":"5","round":"3","num":"2","winner_side":"1"},{"winner_id":"20","loser_id":"31","winner_score":"5","loser_score":"2","winner_handicap":"82.7724","loser_handicap":"79.4895","spot":"0","length":"5","round":"4","num":"1","winner_side":"1"}];
var matches = document.getElementsByClassName("match");
function getMatch(round, num, winner_side) {
for(n = 0; n < matches.length; n++) {
if(matches[n].getAttribute("round") == round &&
matches[n].getAttribute("num") == num &&
matches[n].getAttribute("winner_side") == winner_side) {
return matches[n];
}
}
}
function getData(round, num, winner_side) {
if(winner_side = "true") {
winner_side = 1;
}
for(n = 0; n < match_data.length; n++) {
var data = match_data[n];
if(data["round"] == round &&
data["num"] == num &&
data["winner_side"] == winner_side) {
return data;
}
}
}
function getName(id) {
for(n = 0; n < players.length; n++) {
if(players[n]["id"] == id) {
return players[n]["name"];
}
}
}
for(i = 0; i < matches.length; i++) {
var match = matches[i];
var p1 = match.getElementsByClassName("player")[0];
var p2 = match.getElementsByClassName("player")[1];
var p1_score = match.getElementsByClassName("score")[0];
var p2_score = match.getElementsByClassName("score")[1];
var data = getData(match.getAttribute("round"),
match.getAttribute("num"),
match.getAttribute("winner_side"));
if(match.getAttribute("round") == 1 &&
match.getAttribute("winner_side") == "true") {
p1.innerHTML = getName(data["winner_id"]) + " " + Math.floor(data["winner_handicap"]);
p1_score.innerHTML = data["winner_score"];
if(data["loser_id"] != 0) {
p2.innerHTML = getName(data["loser_id"]) + " " + Math.floor(data["loser_handicap"]);
p2_score.innerHTML = data["loser_score"];
} else {
p2.innerHTML = "Bye";
p2_score.innerHTML = data["loser_score"];
}
p2.className = "player loser";
} else {
// Set winners and losers into next match.
switch(format) {
case "Single Elimination":
var feeder_match = getMatch(match.getAttribute("round") - 1, match.getAttribute("num") * 2 - 1, "true");
var feeder_data = getData(feeder_match.getAttribute("round"),
feeder_match.getAttribute("num"),
feeder_match.getAttribute("winner_side"));
var p1_id = feeder_data["winner_id"];
var p1_handicap = 0;
if(p1_id == data["winner_id"]) {
p1_handicap = Math.floor(data["winner_handicap"]);
p1_score.innerHTML = data["winner_score"];
} else {
p1_handicap = Math.floor(data["loser_handicap"]);
p1_score.innerHTML = data["loser_score"];
p1.className = "player loser";
}
p1.innerHTML = getName(p1_id) + " " + p1_handicap;
feeder_match = getMatch(match.getAttribute("round") - 1, match.getAttribute("num") * 2, "true");
feeder_data = getData(feeder_match.getAttribute("round"),
feeder_match.getAttribute("num"),
feeder_match.getAttribute("winner_side"));
var p2_id = feeder_data["winner_id"];
var p2_handicap = 0;
if(p2_id == data["winner_id"]) {
p2_handicap = Math.floor(data["winner_handicap"]);
p2_score.innerHTML = data["winner_score"];
} else {
p2_handicap = Math.floor(data["loser_handicap"]);
p2_score.innerHTML = data["loser_score"];
p2.className = "player loser";
}
p2.innerHTML = getName(p2_id) + " " + p2_handicap;
break;
case "Single Modified (Reverse Seeded)":
break;
case "Single Modified (Seeded)":
break;
case "Single Modified (Split Bracket)":
break;
case "Double Elimination":
break;
}
}
}
</script>
</head>
</html>
Upvotes: 1
Views: 93
Reputation: 1209
UPDATE
https://jsfiddle.net/ahmnurvx/
Is this what you are after?
I added overflow:auto
to the .match{
class.
You've run into the well known affect of a container losing its height when it contains floated elements.
My solution above should work for most basic cases but for more comprehensive use lookup 'clearfix' solutions: What methods of ‘clearfix’ can I use?
When you apply float
to an element, it removes it from normal document flow. This means it will behave differently, padding won't have ths same effect on elements. Try using margin
instead.
Although you've uploaded your code, the PHP scripts (with SQL statements) make it difficult for us to duplicate your situation. If you upload the final markup after the PHP has executed, I could maybe be more specific in my answer.
Upvotes: 3