inline edits UX pattern
by SebastianPataneMasuelli
HTML
<br /><br />
<span class="editable">Example Text</span>
<br />
CSS
body {font-family: Helvetica, Arial, sans-serif }
.editable { display: inline-block; position: relative; border-radius: 4px 0px 4px 4px;
-moz-transition: all .25s ease-in; border: 0px solid #fff; padding: auto;
}
.editable:hover, .editing, .edited, .saving {
border: 1px solid #5AA4D7;
padding: .2em .4em .2em .4em;
background-color: white;
box-shadow: 2px 2px 2px rgba(0, 0, 0, .25);
font-size: .92em;
color: #555;
}
.editable:hover:before, .editing:before, .edited:before, .saving:before { content: 'click to edit';
position: absolute; top:-1em; right: 0em;
font-size: .8em; color: #5AA4D7; background-color: white; padding: 0 .2em;
}
.editable:hover:after, .saving:after { content:"";
background:transparent url('http://jqueryui.com/themeroller/images/?new=5aa4d7&w=256&h=240&f=png&fltr[]=rcd|256&fltr[]=mask|icons/icons.png');
background-position: -64px -112px; width: 16px; height: 16px; display: inline-block; margin-left: .2em;
vertical-align: middle; position: relative; top: -1px;
}
.editing { border: 1px solid #c30; }
.editing:hover { }
.editing:before { content: 'not saved'; color: #c30}
.editing:hover:before { content: 'click or Enter to save'; }
.editing:after { content:"";
background:transparent url('http://jqueryui.com/themeroller/images/?new=cc3300&w=256&h=240&f=png&fltr[]=rcd|256&fltr[]=mask|icons/icons.png');
background-position: -64px -112px; width: 16px; height: 16px; display: inline-block; margin-left: .2em;
vertical-align: middle; position: relative; top: -1px;
}
.saving { }
.saving:before, .saving:hover:before { content: 'saving'; }
.saving:after, .saving:hover:after { content: ''; background: url(http://markets.on.nytimes.com/research/images/preloadSpinner.gif); opacity: .5;}
.edited { font-size: inherit; border: 1px solid #fff; padding: auto; box-shadow: none; padding: 0;}
.edited:hover { font-size: .8 em; }
.edited:before { content: 'saved'; }...
JavaScript
$('.editable').bind('click', function() {
$(this).addClass('editing');
//create input field on the fly
var textToEdit = $(this).html(),
thisWidth = $(this).width(),
textBoxA = '<input id="beingEdited" class="" type="text" value="' + textToEdit + '"/>';
$(this).html(textBoxA);
$('#beingEdited').css('width', thisWidth - 8 + 'px').focus();
// Options are passed like this:
$('#beingEdited').autoGrowInput({
comfortZone: 10,
minWidth: thisWidth,
maxWidth: 250
});
$('#beingEdited').click(function() {
return false;
})
$(this).unbind('click');
//listen for keyup
$('#beingEdited').keyup(function(event) {
//alert('Handler for .keyup() called.');
//var editedText = $('#beingEdited').val();
//$('.editing').text(editedText);
if (event.keyCode == '13') {
event.preventDefault();
$('.editing').removeClass('editing').addClass('saving').
html($('#beingEdited').val());
//ajax call to save
//$(this).addClass('edited');
window.setTimeout(function() {
$('.editable').removeClass('saving').addClass('edited');
}, 1500);
}
$('.editing').bind('click', function() {
$('.editing').removeClass('editing').addClass('saving');
//ajax call to save
//$(this).addClass('edited');
window.setTimeout(function() {
$('.editable').removeClass('saving').addClass('edited');
}, 1500);
});
});
});
//autostretch input
(function($) {
$.fn.autoGrowInput = function(o) {
o = $.extend({
maxWidth: 1000,
minWidth: 0,
comfortZone: 70
}, o);
this.filter('input:text').each(function() {
var minWidth = o.minWidth || $(this).width(),
val = '',
input = $(this),
...