Bracket drag and drop

by lukerichison

HTML

<div data-region="1">
    <ul data-round="1">
        <li data-game="1">
            <div data-team="M1" draggable="true">1</div>
            <div data-team="M16" draggable="true">16</div>
        </li>
        <li data-game="8">
            <div data-team="M8" draggable="true">8</div>
            <div data-team="M9" draggable="true">9</div>
        </li>
        <li data-game="5">
            <div data-team="M5" draggable="true">5</div>
            <div data-team="M12" draggable="true">12</div>
        </li>
        <li data-game="4">
            <div data-team="M4" draggable="true">4</div>
            <div data-team="M13" draggable="true">13</div>
        </li>
        <li data-game="6">
            <div data-team="M6" draggable="true">6</div>
            <div data-team="M11" draggable="true">11</div>
        </li>
        <li data-game="3">
            <div data-team="M3" draggable="true">3</div>
            <div data-team="M14" draggable="true">14</div>
        </li>
        <li data-game="7">
            <div data-team="M7" draggable="true">7</div>
            <div data-team="M10" draggable="true">10</div>
        </li>
        <li data-game="2">
            <div data-team="M2" draggable="true">2</div>
            <div data-team="M15" draggable="true">15</div>
        </li>
    </ul>
    <ul data-round="2">
        <li data-game="1">
            <div data-team=""></div>
            <div data-team=""></div>
        </li>
        <li data-game="4">
            <div data-team=""></div>
            <div data-team=""></div>
        </li>
        <li data-game="3">
            <div data-team=""></div>
            <div data-team=""></div>
        </li>
        <li data-game="2">
            <div data-team=""></div>
            <div data-team=""></div>
        </li>
    </ul>
    <ul data-round="3">
        <li data-game="1">
            <div data-team=""></div>
            <div data-team=""></div>
        </li>
        <li data-game="2">
            <div...

CSS

body,html{height:100%;width:100%;}
ul[data-round] {float:left;margin-right: 1em;}
div[data-team] {height: 1em; width: 2em; border: 0.0625em solid #AAA; position: relative;background-color:white;}
div[data-team]:last-child {border-top: none;}
div[data-team][draggable] {cursor: pointer;}
ul[data-round='1'] li[data-game]:not(:last-child) {margin-bottom: 1em;}
ul[data-round='2'] {margin-top: 1.625em;}
ul[data-round='2'] li[data-game]:not(:last-child) {margin-bottom: 4.1875em;}
ul[data-round='3'] {margin-top: 4.6875em;}
ul[data-round='3'] li[data-game]:not(:last-child) {margin-bottom: 10.5625em;}
ul[data-round='4'] {margin-top: 11.0625em;}

div[data-team="M1"]  {background-color: #E01B1B;}
div[data-team="M2"]  {background-color: #16409C;}
div[data-team="M3"]  {background-color: #636080;}
div[data-team="M4"]  {background-color: #0E6918;}
div[data-team="M5"]  {background-color: #D46A00;}
div[data-team="M6"]  {background-color: #62D1F0;}
div[data-team="M7"]  {background-color: #778C54;}
div[data-team="M8"]  {background-color: #20211F;}
div[data-team="M9"]  {background-color: #081673;}
div[data-team="M10"] {background-color: #730841;}
div[data-team="M11"] {background-color: #9E1200;}
div[data-team="M12"] {background-color: #2E6E2E;}
div[data-team="M13"] {background-color: #FAFA19;}
div[data-team="M14"] {background-color: #2D5200;}
div[data-team="M15"] {background-color: #9CAAF7;}
div[data-team="M16"] {background-color: #808080;}

div[data-team]:not([data-team=""]):after {
    content: "";position: absolute;display: block;
    top:0;left:0;width:100%;height:100%;
    background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 1%, rgba(255,255,255,0.2) 50%, rgba(255,255,255,0.1) 51%, rgba(255,255,255,0.4) 100%);
    background: -webkit-linear-gradient(top,  rgba(255,255,255,0) 0%,rgba(255,255,255,0) 1%,rgba(255,255,255,0.2) 50%,rgba(255,255,255,0.1) 51%,rgba(255,255,255,0.4) 100%);
    background: linear-gradient(to bottom,  rgba(255,255,255,0)...

JavaScript

$("[data-team][draggable='true']").on("dragstart", function(event){
    var dragged = $(this);
    var team = dragged.attr("data-team");
    var teami = team.replace(/\D/g,'');
    var game = dragged.closest("[data-game]").attr("data-game");
    var round = dragged.closest("[data-round]").attr("data-round");
    var region = dragged.closest("[data-region]").attr("data-region");
    var gameo = $("[data-region='1']").find("[data-team='"+team+"']").closest("[data-game]").index();
    $("div[data-region] ul[data-round]").each(function(){
        var roundi = $(this).attr("data-round");
        var games = $("li[data-game]", this).length;
        if (roundi > round){
            var dropAccept = $("li[data-game='"+(Math.abs((teami-1)%(16/Math.pow(2,roundi))+(Math.pow(-1, Math.ceil(teami/(16/Math.pow(2,roundi)))+1)-1)/2*(16/Math.pow(2,roundi)-1))+1)+"'] div[data-team]:nth-child("+((Math.pow(-1, Math.ceil((gameo*2+$("[data-round='1']").find("[data-team='"+team+"']").index()+1)/Math.pow(2,roundi-1)))+1)/2+1)+")", this);
            dropAccept.css("background-color", "#BBB").on("dragover", function(event){
                $(this).css("background-color", dragged.css("background-color"));
                return false;
            }).on("dragleave", function(event) {
                $(this).css("background-color", "BBB");
                return false;
            }).on("drop", function(event) {
                var dropped = $(this);
                $(this).attr("data-team", team);
                return false;
            });
        }
    });
    dragged.on("dragend", function(event){
        $("div[data-team='']").css("background-color", "");
        return false;
    });
});