/*@ 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 || {}; that = Ox.Element('
', self) .defaults({ editing: false, format: null, value: '', type: 'input' }) .options(options || {}) .addClass('OxEditable') .bindEvent({ doubleclick: edit }); 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' }) .html( self.options.format ? self.options.format(self.options.value) : self.options.value ) //[self.options.editing ? 'hide' : 'show']() .appendTo(that); self.$input = Ox.Input({ changeOnKeypress: true, style: 'square', type: self.options.type, value: self.options.value }) .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; if (self.options.type == 'input') { self.options.value = self.options.value.replace(/ /g, ' '); } else if (Ox.endsWith(self.options.value, '\n')) { self.options.value += ' '; } self.$value.html( self.options.format ? self.options.format(self.options.value) : self.options.value ); height = self.$value.height(); width = self.$value.width(); if (self.options.type == 'input') { self.$input.options({ height: height, width: width + 2 }); self.$input.find('input').css({width: width + 2 + '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.editing) { height = self.$value.height(); width = self.$value.width(); self.$value.hide(); self.$input.options({ height: height, width: width }).show(); if (self.options.type == 'input') { self.$input.find('input').css({width: width + 'px'}); } else { self.$input.find('textarea').css({ height: height + 'px', width: width + Ox.UI.SCROLLBAR_SIZE + 'px' }); } // fixme: why can't this be chained? setTimeout(function() { self.$input.focusInput(false); }, 0); self.options.editing = true; } } function submit() { self.options.value = self.$input.value(); self.$value.html( self.options.format ? self.options.format(self.options.value) : self.options.value ); cancel(); } that.css = function(obj) { that.$element.css(obj); self.$value.css(obj); self.$input.css(obj); self.$input.find('input').css(obj); //self.$value.css.apply(this, arguments); //self.$input.css.apply(this, arguments); return that }; return that; };