only use one element in EditableContent and toggle contenteditable: adds firefox support, allows using doubleclick handler, less code

This commit is contained in:
j 2013-02-25 20:29:08 +00:00
parent 559fbd9995
commit 0957500476

View file

@ -16,15 +16,30 @@ Ox.EditableContent = function(options, self) {
.options(options || {}) .options(options || {})
.update({ .update({
highlight: function() { highlight: function() {
self.$value.html(formatValue()); !self.editing && self.$value.html(formatValue());
}, },
value: function() { value: function() {
self.$value.html(formatValue()); !self.editing && self.$value.html(formatValue());
} }
}) })
.addClass('OxEditableContent') .addClass('OxEditableContent')
.on({ .on({
click: edit click: function(e) {
var $target = $(e.target);
if (!e.shiftKey && ($target.is('a') || ($target = $target.parents('a')).length)) {
e.preventDefault();
if (self.options.clickLink) {
e.target = $target[0];
self.options.clickLink(e);
} else {
document.location.href = $target.attr('href');
}
}
return false;
}
})
.bindEvent({
doubleclick: edit
}); });
self.options.value = self.options.value.toString(); self.options.value = self.options.value.toString();
@ -33,51 +48,44 @@ Ox.EditableContent = function(options, self) {
self.$value = Ox.Element(self.options.type == 'span' ? '<span>' : '<div>') self.$value = Ox.Element(self.options.type == 'span' ? '<span>' : '<div>')
.html(formatValue(self.options.value)) .html(formatValue(self.options.value))
.appendTo(that);
self.$input = Ox.Element(self.options.type == 'span' ? '<span>' : '<div>')
.addClass('OxEditableContentInput')
.attr({contenteditable: true})
.text(formatInputValue(self.options.value))
.hide()
.on({ .on({
blur: submit, blur: submit,
keydown: function(e) { keydown: function(e) {
if (self.options.type == 'span' && e.keyCode == 13) { if (self.editing) {
submit(); if (self.options.type == 'span' && e.keyCode == 13) {
return false; submit();
return false;
} else if (e.keyCode == 27) {
cancel();
return false;
}
} }
} }
}) })
.appendTo(that); .appendTo(that);
function edit(e) { function cancel() {
var $target = $(e.target); if (self.editing) {
e.preventDefault(); that.loseFocus();
if (!e.shiftKey && ($target.is('a') || ($target = $target.parents('a')).length)) { self.editing = false;
if (self.options.clickLink) { self.$value
e.target = $target[0]; .attr({contenteditable: false})
self.options.clickLink(e); .removeClass('OxEditableContentInput')
} else { .html(formatValue());
document.location.href = $target.attr('href'); that.triggerEvent('cancel', {value: self.options.value});
} }
} else if (self.options.editable && !self.editing) { }
that.gainFocus();
self.$value.hide(); function edit() {
self.$input.show().on({ if (self.options.editable && !self.editing) {
focus: function() { self.$value
self.editing = true; .text(formatInputValue() || '&nbsp;')
updateSelection(); .addClass('OxEditableContentInput')
} .attr({contenteditable: true});
}); self.editing = true;
setTimeout(function() { that.gainFocus();
if (!self.editing) { setTimeout(updateSelection, 50);
self.$input.hide();
self.$value.show();
}
}, 250);
} }
return false;
} }
function formatInputValue() { function formatInputValue() {
@ -105,7 +113,7 @@ Ox.EditableContent = function(options, self) {
function parseValue() { function parseValue() {
var value = Ox.clean( var value = Ox.clean(
self.$input.text().replace(/\n\n+/g, '\0') self.$value.text().replace(/\n\n+/g, '\0')
).replace(/\0/g, '\n\n').trim(); ).replace(/\0/g, '\n\n').trim();
return ( return (
self.options.type == 'span' self.options.type == 'span'
@ -119,19 +127,27 @@ Ox.EditableContent = function(options, self) {
} }
function submit() { function submit() {
that.loseFocus(); if (self.editing) {
self.editing = false; that.loseFocus();
self.options.value = self.$input.text(); self.editing = false;
self.$input.text(formatInputValue()).hide(); self.options.value = self.$value.text();
self.$value.html(formatValue()).show(); if (self.options.value.charCodeAt(0) == 160) {
that.triggerEvent('submit', {value: self.options.value}); self.options.value = '';
}
self.$value
.attr({contenteditable: false})
.removeClass('OxEditableContentInput')
.html(formatValue());
that.triggerEvent('submit', {value: self.options.value});
}
} }
function updateSelection() { function updateSelection() {
var range, selection; var range, selection;
self.$value[0].focus();
selection = window.getSelection(); selection = window.getSelection();
selection.removeAllRanges(); selection.removeAllRanges();
range = document.createRange(); range = document.createRange();
range.selectNodeContents(self.$input[0]); range.selectNodeContents(self.$value[0]);
selection.addRange(range); selection.addRange(range);
if (self.options.type != 'span') { if (self.options.type != 'span') {
setTimeout(function() { setTimeout(function() {
@ -143,7 +159,6 @@ Ox.EditableContent = function(options, self) {
that.css = function(css) { that.css = function(css) {
that.$element.css(css); that.$element.css(css);
self.$value.css(css); self.$value.css(css);
self.$input.css(css);
return that; return that;
} }