ContentEditable Example
by jlujan
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('id')] = Number(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);
...