Skip to content

Instantly share code, notes, and snippets.

@anutron
Created June 2, 2009 16:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anutron/122362 to your computer and use it in GitHub Desktop.
Save anutron/122362 to your computer and use it in GitHub Desktop.
//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