/*@ Ox.Editable Editable element () -> Input Element (options) -> Input Element (options, self) -> Input Element options Options object editing If true, loads in editing state format Format function (value) -> Formatted value value Input value self Shared private variable @*/ Ox.Editable = function(options, self) { self = self || {}; var that = Ox.Element({ element: '
', tooltip: options.tooltip }, self) .defaults({ clickLink: function(e) { document.location.href = $(e.target).attr('href'); }, editable: true, editing: false, format: null, placeholder: '', tooltip: '', value: '', width: 256, type: 'input' }) .options(options || {}) .addClass('OxEditableElement') .bind({ click: function(e) { if ($(e.target).is('a')) { return false; } } }) .bindEvent({ doubleclick: edit, singleclick: function(e) { $(e.target).is('a') && self.options.clickLink(e); } }); self.options.value = self.options.value.toString(); self.$value = Ox.Element(self.options.type == 'input' ? '' : '
') .addClass('OxValue') .css(self.options.type == 'input' ? { //height: '14px', //padding: '1px 4px 1px 4px', //border: '1px solid transparent' } : { //padding: '0 4px 0 4px' width: self.options.width + 'px' }) .html(formatValue()) //[self.options.editing ? 'hide' : 'show']() .appendTo(that); self.$test = self.$value.$element.clone() .css({ display: 'inline-block', //position: 'absolute', //left: 200, //top: 200 }) .html(formatTestValue()) .hide() .appendTo(that.$element); self.$input = Ox.Input(Ox.extend({ changeOnKeypress: true, style: 'square', type: self.options.type, value: formatInputValue() }, self.options.type == 'textarea' ? { width: self.options.width } : {})) .css({display: 'none'}) .bindEvent({ blur: submit, cancel: cancel, change: change, //submit: submit }) //[self.options.editing ? 'show' : 'hide']() .hide() .appendTo(that.$element); if (self.options.editing) { self.options.editing = false; edit(); } function cancel() { self.$input.hide(); self.$value.show(); self.options.editing = false; } function change(event) { var height, width; self.options.value = event.value; self.$value.html(formatValue); self.$test.html(formatTestValue()); height = self.options.height || self.$test.height(); //height = Math.max(self.$test.height(), 14); width = Math.max(self.$test.width() + 2, 8); width = Ox.limit(self.$test.width() + 2, self.minWidth, self.maxWidth) Ox.print('wxh', width, height) if (self.options.type == 'input') { self.$input.options({ width: width }); self.$input.find('input').css({width: width + 'px'}); } else { self.$input.options({ height: height, width: width// + Ox.UI.SCROLLBAR_SIZE }); self.$input.find('textarea').css({ height: height + 'px', width: width /*+ Ox.UI.SCROLLBAR_SIZE*/ + 'px' }); } //self.$input.find('input').css({width: width + 2}) /* that.triggerEvent('change', { value: event.value }); */ } function edit() { var height, width; if (self.options.editable && !self.options.editing) { self.minWidth = 8 self.maxWidth = that.parent().width(); Ox.print('MAX WIDTH', self.maxWidth); height = self.options.height || self.$value.height(); width = self.$value.width(); self.$value.hide(); //self.$test.show(); Ox.print('HEIGHT', height) self.$input.options({ height: height, width: width }).show(); if (self.options.type == 'input') { self.$input.find('input').css({ height: height + 'px', width: width + 'px' }); } else { self.$input.find('textarea').css({ height: height + 'px', width: width + 'px' }); } // fixme: why can't this be chained? setTimeout(function() { self.$input.focusInput(false); }, 0); self.options.editing = true; } } function formatInputValue() { return self.options.type == 'input' ? self.options.value : self.options.value.replace(//g, '\n'); } function formatTestValue() { Ox.print('TEST VALUE =', self.options.type == 'input' ? self.options.value.replace(/ /g, ' ') : self.options.value.replace(/\n$/, '
 ') .replace(/\n/g, '
')); return self.options.type == 'input' ? self.options.value.replace(/ /g, ' ') : self.options.value.replace(/\n$/, '
 ') .replace(/\n/g, '
'); } function formatValue() { return self.options.format ? self.options.format(self.options.value) : self.options.value } function submit() { self.options.value = Ox.parseHTML(self.$input.value()); self.$input.value(formatInputValue()); self.$value.html(formatValue()); cancel(); that.triggerEvent('submit', { value: self.options.value }); } that.css = function(obj) { that.$element.css(obj); self.$value.css(obj); self.$test.css(obj).hide(); self.$input.css(obj).hide(); self.$input.find('input').css(obj); //self.$value.css.apply(this, arguments); //self.$input.css.apply(this, arguments); return that }; return that; };