JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<div>
    <input type="button" id="create-empty-book" value="Create Empty" />
    <input type="button" id="create-predefined-book" value="Create Predefined" />
    <input type="button" id="show-json" value="Show JSON" />
</div>
<div class="book-view">
    Book: <span class="title"></span> by <span class="author"></span>
</div>

<fieldset class="book-edit">
    <legend>Edit Book</legend>
    <div>
        <label for="id-edit">Id</label>
        <span id="id-edit"></span>
    </div>
    <div>
        <label for="cid-edit">CId</label>
        <span id="cid-edit"></span>
    </div>
    <div>
        <label for="title-edit">Title</label>
        <input type="text" id="title-edit" />
    </div>
    <div>
        <label for="author-edit">Author</label>
        <input type="text" id="author-edit" />
    </div>
    <div>
        <label for="has-changed">Has Changed?</label>
        <span id="has-changed"></span>
    </div>
    <input type="submit" id="book-submit" value="Change" />
</fieldset>

<div>
    <input type="button" id="save-book" value="Save Book to server" />
</div>

CSS

html {
    font-family: Arial;font-size:12px;
    line-height:30px;
}

.book-view {
    background-color : #bfbfbf;
    border: 1px solid #aaa;
    padding: 10px;
    width:335px;
font-weight:bold;
}
.book-edit {
    color:green;
    width:350px;
}
.book-edit input{
    color:#b0b0b0;
/*margin-left:20px;*/
}
.book-edit label{
    margin-right:20px;
}

JavaScript

//-------------------------------------------------------------
// Backbone setup

// Sync override to prevent requests to the server
Backbone.sync = function(method, model) {
  alert(method + ": " + JSON.stringify(model));
  model.id = 1;
};

// create model
var Book = Backbone.Model.extend({
    // initialize is called automatically on object creation
    initialize: function() {
    },
    defaults: {
        // setting defaults
        title: "New Book",
        author: "Author"
    }
});

var book1 = null;

//-------------------------------------------------------------
// Model relataed
var attachOnchangeHandlertoBook = function(book) {
    if(validateModel(book)) {
        book.bind("change", function() {
            $hasChangedSpan.text(new Date().toLocaleString());
        });
    }
};

var destroyBook = function(book) {
    if(validateModel(book)) {
        book.unbind();
    }
    delete book;
};

var createEmptyBook = function() {
    destroyBook(book1);
    book1 = new Book;
    attachOnchangeHandlertoBook(book1);
};
var createPredefinedBook = function() {
    destroyBook(book1);
    book1 = new Book({
        title: "One Thousand and One Nights",
        author: "Scheherazade"
    });
    attachOnchangeHandlertoBook(book1);
};
var updateBookModel = function(book) {
    if(validateModel(book)) {
        book.set({ 
            title: $title.val(),
            author: $author.val()
        });
    }
};
var validateModel = function(book) {
    var isValid = (book && (book instanceof Book));
    return isValid;
};
//-------------------------------------------------------------
// Display relataed

var $bookView = $(".book-view");
var $createEmptyBookButton = $("#create-empty-book");
var $createPredefinedBookButton = $("#create-predefined-book");
var $changeBookButton = $("#book-submit");
var $saveBookButton= $("#save-book");
var $showJsonButton = $("#show-json");
var $hasChangedSpan = $("#has-changed");
var $id = $("#id-edit");
var $cid =...