JSFiddle - React, Tailwind, and code Playground

HTML

<div align="center">
    <p class="text-success text-center" id="success"></p>
    <table class="table table-bordered table-condensed table-nonfluid">
        <tbody id="planner"></tbody>
    </table>
    <div id="buttons">
        <button class="btn btn-primary" id="save">Save</button>
        <button class="btn btn-danger" id="discard">Discard Changes</button>
    </div>
    <p class="text-center text-warning" id="warning"></p>
</div>
<div id="status"></div>

CSS

@import url("http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css");
 .assigned {
    background-color: #FDFD96;
}
.item {
    width: 100%;
    text-align: center;
    background-color: #FDFD96
}
/* Doesn't seem to do anything */
 .timeslot {
    text-align: center;
    width: 100px;
}
/* Highlighting for elements that are being dragged over but are unavailable */
 .over-red {
    background-color: red;
}
/* Highlighting for elements that are being dragged over and are available */
 .over-green {
    background-color: green;
}
/* Flash for warnings: Something went wrong! */
 #warning {
    color: red;
    font-style: italic;
}
/* Flash for successful save to database */
 #success {
    margin-top: 10px;
    margin-bottom: 10px;
    color: green;
    font-style: italic;
}
#buttons {
    margin-top: 10px;
    margin-bottom: 10px;
}
.table-nonfluid {
    width: auto;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
}
td {
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
}

JavaScript

/**
 * @author SL
 */

/**
 * These variables should later be dynamically added by the PHP Code. This allows the
 * JavaScript to create HTML locally instead of the server. Since the table will be rebuilt
 * often, this should reduce some code duplication between server and client.
 */
var slotNames = ["Monday AM", "Monday PM", "Tuesday AM", "Tuesday PM", "Wednesday AM"];
var roomNames = ["A123", "B123", "C123", "D123", "E123"];
var timetable = [{
    room: "A123",
    events: [{
        time: "Monday AM",
        name: "A1.1"
    }, {
        time: "Monday PM",
        name: "A1.1"
    }, {
        time: "Tuesday AM",
        name: "A1.1"
    }]
}, {
    room: "C123",
    events: [{
        time: "Tuesday AM",
        name: "C3.6"
    }, {
        time: "Tuesday PM",
        name: "C3.6"
    }]
}];

/*
 * This is needed as a clone of the timetable, in order to
 * manage discarding and saving locally without reloading
 * the entire page.
 */
var discard = JSON.parse(JSON.stringify(timetable));

/*
 * Function used to retrieve a certain event given its
 * room and timeslot. Returns 0 when no result is found.
 */
function eventBySlot(room, time) {
    var event;
    for (var i = 0; i < timetable.length; i++) {
        if (typeof timetable[i] !== "undefined" && timetable[i].room === room) {
            var events = timetable[i].events;
            for (var j = 0; j < events.length; j++) {
                if (events[j] !== null && events[j].time === time) {
                    return events[j];
                }
            }
        }
    }
    return 0;
}

function roomIndex(room) {
    for (var i = 0; i < timetable.length; i++) {
        if (timetable[i].room === room) {
            return i;
        }
    }
    return -1;
}

/*
 * Convenience method to create a <div> element for a certain event
 */
function makeEventDiv(event) {
    return "<div class=\"item\">" + event.name + "</div>";
}

/*
 *Build the HTML table from the JSON data provided by the PHP side
...