ContentEditable Example

HTML

<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<div id="updated" class="alert alert-error">
    Highlighted element value is not int!
</div>
<div id="not-updated" class="alert alert-error">
    Highlighted element value is not int!
</div>
<h1>Statistics</h1>
<div id="statistics">
<table class="table">
    <thead>
        <tr>
            <th>Stat</th>
            <th>Home</th>
            <th>Away</th>
        </tr>
    </thead>
    <tbody>
        <tr><td>First</td> <td id="home1">0</td><td id="away1">0</td></tr>
        <tr><td>Second</td><td id="home2">0</td><td id="away2">0</td></tr>
        <tr><td>Third</td> <td id="home3">0</td><td id="away2">0</td></tr>
        <tr><td>Fourth</td><td id="home4">0</td><td id="away3">0</td></tr>
    </tbody>
    </table>
</div>
<div class="form-actions">
    <button class="btn btn-danger" id="cancel">Cancel</button>
    <button class="btn btn-primary" id="edit">Edit</button>
    <button class="btn btn-success" id="save">Save</button>
</div>

CSS

body{
    text-align: center;
}

div {
    border: 1px solid #000;
}

td[contenteditable="true"] {
    background-color: #eeeeee;
}

td[contenteditable="true"]:focus {
    background-color: #dddddd;
}
#save, #cancel{
    display: none;
}

#updated, #not-updated{
    display: none;
}

td[contenteditable="true"].error{
    background-color: #CD2626;
    color: #fff;
}

JavaScript

var editable = false;
var editables = $('td[id*=home], td[id*=away]');
var edit = $('#edit');
var cancel = $('#cancel');
var save = $('#save');
var updated = $('#updated');
var notUpdated = $('#not-updated');

var values = {};

function salert(state) {
    $('.alert').hide();
    if (state == 'updated') {
        updated.show('fast');
    } else {
        notUpdated.show('fast');
    }
    setTimeout('$(".alert").hide("fast");', 10000);
}

function toggleButtons(action) {
    if (action == 'show') {
        edit.hide('fast');
        cancel.show('fast');
        save.show('fast');
    } else {
        edit.show('fast');
        cancel.hide('fast');
        save.hide('fast');
    }
}

function toggleEditable() {
    editable = !editable;
    editables.attr('contentEditable', editable);
}

function selectElementContents(el) {
    var range = document.createRange();
    range.selectNodeContents(el);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
}

function error(show, el) {
    if (show) {
        el.addClass('error');
    } else {
        el.removeClass('error');
    }
}

edit.on('click', function() {
    toggleEditable();
    if (editable) {
        editables.each(function() {
            var el = $(this);
            values[el.attr('home1')] = String(el.html());
        });
        toggleButtons('show');
    } else {
        toggleButtons('hide');
    }
});

cancel.on('click', function() {
    editables.each(function() {
        var el = $(this);
        el.html(values[el.attr('id')]);
    });
    toggleEditable();
    toggleButtons('hide');
});

save.on('click', function() {
    var invalid = false;
    editables.each(function() {
        var el = $(this);
        if (isNaN(el.html())) {
            error(true, el);
            invalid = true;
        }
    });
    if (invalid) {
        salert('not updated');
        return false;
    }

    editables.each(function() {
        var el = $(this);
       ...