Created
June 2, 2009 16:58
-
-
Save anutron/122362 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//positions an input over an object to edit it inline | |
var EditInline = new Class({ | |
Implements: [Options, Class.Occlude, Events], | |
Binds: ['edit', 'mouseenter', 'mouseleave', 'esc'], | |
options: { | |
//onEnter: $empty, | |
tag: 'input', | |
hoverClass: 'edit_highlight', | |
activeClass: 'edit_activated', | |
props: { | |
styles: {} | |
}, | |
onEdit: $empty, | |
positionOptions: {}, | |
preventDefault: false, | |
editEvent: 'click', | |
applySize: true, | |
applyPosition: true, | |
value: false //value or function, if true, uses innerHTML of element | |
}, | |
property: 'EditInline', | |
initialize: function(element, options){ | |
this.element = $(element); | |
if (this.occlude()) return this.occluded; | |
this.setOptions(options); | |
this.attach(); | |
}, | |
attach: function(attach) { | |
var method = $pick(attach, true) ? 'addEvents' : 'removeEvents'; | |
//mouseover/out behavior to allow for highlight invitation | |
var events = { | |
mouseenter: this.mouseenter, | |
mouseleave: this.mouseleave | |
}; | |
//if we're attaching an edit event (like "click") attach it | |
if (this.options.editEvent) events[this.options.editEvent] = this.edit; | |
this.element[method](events); | |
//add document listener for out-clicks and esc key | |
document[method]({ | |
keyup: this.esc, | |
click: this.esc | |
}); | |
}, | |
detach: function(){ | |
this.attach(false); | |
}, | |
//if user hits "esc" or clicks out, close | |
esc: function(e) { | |
if (e.key == "esc" || (!this.activating && this.active && e.type == "click" && e.target != this.input)) this.close(); | |
}, | |
mouseenter: function(){ | |
this.element.addClass(this.options.hoverClass); | |
}, | |
mouseleave: function(){ | |
this.element.removeClass(this.options.hoverClass); | |
}, | |
//shows input with the given value defaulted and selected | |
edit: function(value){ | |
if (this.activating || this.active) return; | |
this.activating = true; | |
//if this was used as an event listener, reset the value | |
if ($type(value) == "event") value = null; | |
if (!this.input) { | |
//make the input; if the user hits enter, fire the enter event | |
this.input = new Element(this.options.tag, this.options.props); | |
this.input.addEvent('keydown', function(e) { | |
if (this.active && !this.activating && e.key == "enter") this.fireEvent('enter', this.input.get('value')); | |
}.bind(this)); | |
} | |
//inject it after the element we're editing | |
this.input.hide().inject(this.element, 'after'); | |
value = value || this.options.value; | |
if (value) this.input.set('value', $type(value) == "boolean" ? this.element.get('html') : $lambda(value)()); | |
//position it | |
var dim = this.element.getComputedSize(); | |
if (this.options.applySize) { | |
this.input.setStyles({ | |
width: this.options.props.styles.width||(this.element.getScrollSize().x), | |
height: this.options.props.styles.height||(this.element.getScrollSize().y) | |
}); | |
} | |
if (this.options.applyPosition) { | |
this.input.position( | |
$merge(this.options.positionOptions, { | |
relativeTo: this.element, | |
position: 'upperLeft' | |
}) | |
); | |
} | |
this.active = true; | |
this.fireEvent('edit', this.input); | |
this.input.show().select(); | |
(function(){ | |
this.activating = false; | |
}).delay(30, this); | |
}, | |
close: function(){ | |
if (!this.active) return; | |
this.input.hide(); | |
this.active = false; | |
this.fireEvent('hide'); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment