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