onblur option ready, need test

This commit is contained in:
vitalets
2012-11-28 21:24:51 +04:00
parent ee13a2b1fb
commit 79847d1d92
5 changed files with 140 additions and 48 deletions

@ -27,7 +27,73 @@ Applied as jQuery method.
//bind 'destroyed' listener to destroy container when element is removed from dom //bind 'destroyed' listener to destroy container when element is removed from dom
this.$element.on('destroyed', $.proxy(function(){ this.$element.on('destroyed', $.proxy(function(){
this.destroy(); this.destroy();
}, this)); }, this));
//attach document handlers (once)
if(!$(document).data('editable-handlers-attached')) {
//close all on escape
$(document).on('keyup.editable', function (e) {
if (e.which === 27) {
$('.editable-open').editableContainer('hide');
//todo: return focus on element
}
});
//close containers when click outside
$(document).on('click.editable', function(e) {
var element = e.target,
$target = $(e.target),
$clickedContainer = $target.is('.editable-container') ? $target : $target.closest('.editable-container');
//if click inside some editableContainer --> find corresponding element
if($clickedContainer.length) {
$('.editable-open').each(function(i, el){
if($(el).data('editableContainer').tip()[0] === $clickedContainer[0]) {
element = el;
return false;
}
});
}
//close all open containers (except one)
EditableContainer.prototype.closeOthers(element);
/* $('.editable-open').each(function(){
//if click target is editable element --> do nothing with el
if(this === e.target) {
return;
}
var $el = $(this),
ec = $el.data('editableContainer');
//if click in some editableContainer and current el is it's owner --> do nothing with el
if($clickedContainer.length && ec.tip()[0] === $clickedContainer[0]) {
return;
}
//otherwise cancel or submit el's container
if(ec.options.onblur === 'cancel') {
$el.data('editableContainer').hide();
} else if(ec.options.onblur === 'submit') {
$el.data('editableContainer').tip().find('form').submit();
}
}); */
//if click inside container --> do nothing
// if($target.is('.editable-container') || $target.parents('.editable-container').length || $target.parents('.ui-datepicker-header').length) {
/*
if($target.is('.editable-container') || $target.parents('.editable-container').length || $target.parents('.ui-datepicker-header').length) {
return;
}
//close all other containers
$('.editable-container').find('.editable-cancel').click();
*/
});
$(document).data('editable-handlers-attached', true);
}
}, },
//split options on containerOptions and formOptions //split options on containerOptions and formOptions
@ -93,11 +159,22 @@ Applied as jQuery method.
/** /**
Shows container with form Shows container with form
@method show() @method show()
@param {boolean} multi if true - other editable containers will not be closed. Default false.
**/ **/
show: function () { show: function (multi) {
this.$element.addClass('editable-open');
if(!multi) {
//close all open containers (except one)
this.closeOthers(this.$element[0]);
}
this.innerShow();
},
/* internal show method. To be overwritten in child classes */
innerShow: function () {
this.call('show'); this.call('show');
this.tip().addClass('editable-container'); this.tip().addClass('editable-container');
this.initForm(); this.initForm();
this.tip().find(this.innerCss).empty().append(this.$form); this.tip().find(this.innerCss).empty().append(this.$form);
this.$form.editableform('render'); this.$form.editableform('render');
@ -108,10 +185,11 @@ Applied as jQuery method.
@method hide() @method hide()
**/ **/
hide: function() { hide: function() {
if(!this.tip() || !this.tip().is(':visible')) { if(!this.tip() || !this.tip().is(':visible') || !this.$element.hasClass('editable-open')) {
return; return;
} }
this.call('hide'); this.$element.removeClass('editable-open');
this.innerHide();
/** /**
Fired when container was hidden. It occurs on both save or cancel. Fired when container was hidden. It occurs on both save or cancel.
@ -121,6 +199,11 @@ Applied as jQuery method.
this.$element.triggerHandler('hidden'); this.$element.triggerHandler('hidden');
}, },
/* internal hide method. To be overwritten in child classes */
innerHide: function () {
this.call('hide');
},
/** /**
Toggles container visibility (show / hide) Toggles container visibility (show / hide)
@method toggle() @method toggle()
@ -210,6 +293,34 @@ Applied as jQuery method.
**/ **/
destroy: function() { destroy: function() {
this.call('destroy'); this.call('destroy');
},
/*
Closes other containers except one related to passed element.
Other containers can be cancelled or submitted (depends on onblur option)
*/
closeOthers: function(element) {
$('.editable-open').each(function(i, el){
//do nothing with passed element
if(el === element) {
return;
}
//otherwise cancel or submit all open containers
var $el = $(el),
ec = $el.data('editableContainer');
if(!ec) {
return;
}
if(ec.options.onblur === 'cancel') {
$el.data('editableContainer').hide();
} else if(ec.options.onblur === 'submit') {
$el.data('editableContainer').tip().find('form').submit();
}
});
} }
}; };
@ -248,7 +359,7 @@ Applied as jQuery method.
//store constructor //store constructor
$.fn.editableContainer.Constructor = EditableContainer; $.fn.editableContainer.Constructor = EditableContainer;
//defaults - must be redefined! //defaults
$.fn.editableContainer.defaults = { $.fn.editableContainer.defaults = {
/** /**
Initial value of form input Initial value of form input
@ -275,7 +386,15 @@ Applied as jQuery method.
@default true @default true
@private @private
**/ **/
autohide: true autohide: true,
/**
Action when click outside container. Can be <code>cancel|submit|ignore</code>
@property onblur
@type string
@default cancel
**/
onblur: 'cancel'
}; };
/* /*

@ -26,7 +26,7 @@
return this.$form; return this.$form;
}, },
show: function () { innerShow: function () {
this.$element.hide(); this.$element.hide();
if(this.$form) { if(this.$form) {
@ -40,19 +40,13 @@
this.$form.editableform('render'); this.$form.editableform('render');
}, },
hide: function () { innerHide: function () {
if(!this.tip() || !this.tip().is(':visible')) {
return;
}
this.$form.hide(this.options.anim, $.proxy(function() { this.$form.hide(this.options.anim, $.proxy(function() {
this.$element.show(); this.$element.show();
//return focus on element //return focus on element
if (this.options.enablefocus) { if (this.options.enablefocus) {
this.$element.focus(); this.$element.focus();
} }
//trigger event
this.$element.triggerHandler('hidden');
}, this)); }, this));
}, },

@ -28,11 +28,10 @@
this.call('update', $content); this.call('update', $content);
}, },
show: function () { innerShow: function () {
this.$form.editableform('render'); this.$form.editableform('render');
this.tip().addClass('editable-container');
this.call('show'); this.call('show');
this.tip().addClass('editable-container');
this.$form.data('editableform').input.activate(); this.$form.data('editableform').input.activate();
}, },

@ -50,7 +50,7 @@
return this.container()._find(this.container().element); return this.container()._find(this.container().element);
}, },
show: function() { innerShow: function() {
this.call('open'); this.call('open');
this.tip().addClass('editable-container'); this.tip().addClass('editable-container');
@ -62,12 +62,8 @@
this.$form.editableform('render'); this.$form.editableform('render');
}, },
hide: function() { innerHide: function() {
if(!this.tip() || !this.tip().is(':visible')) {
return;
}
this.call('close'); this.call('close');
this.$element.triggerHandler('hidden');
}, },
setPosition: function() { setPosition: function() {

@ -50,24 +50,6 @@ Makes editable any HTML element on the page. Applied as jQuery method.
this.value = this.input.str2value($.trim(this.options.value)); this.value = this.input.str2value($.trim(this.options.value));
} }
//attach handler to close any container on escape
$(document).off('keyup.editable').on('keyup.editable', function (e) {
if (e.which === 27) {
$('.editable-container').find('.editable-cancel').click();
}
});
//attach handler to close container when click outside
$(document).off('click.editable').on('click.editable', function(e) {
var $target = $(e.target);
//if click inside container --> do nothing
if($target.is('.editable-container') || $target.parents('.editable-container').length || $target.parents('.ui-datepicker-header').length) {
return;
}
//close all other containers
$('.editable-container').find('.editable-cancel').click();
});
//add 'editable' class //add 'editable' class
this.$element.addClass('editable'); this.$element.addClass('editable');
@ -199,15 +181,16 @@ Makes editable any HTML element on the page. Applied as jQuery method.
return; return;
} }
//stop propagation bacause document listen any click to hide all editableContainers //stop propagation bacause document listen any click to hide all editableContainers
e.stopPropagation(); //e.stopPropagation();
this.toggle(); this.toggle();
}, },
/** /**
Shows container with form Shows container with form
@method show() @method show()
@param {boolean} multi if true - other editable containers will not be closed. Default false.
**/ **/
show: function () { show: function (multi) {
if(this.options.disabled) { if(this.options.disabled) {
return; return;
} }
@ -216,7 +199,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(!this.container) { if(!this.container) {
var containerOptions = $.extend({}, this.options, { var containerOptions = $.extend({}, this.options, {
value: this.value, value: this.value,
autohide: false //element itsef will show/hide container autohide: false //element will take care to show/hide container
}); });
this.$element.editableContainer(containerOptions); this.$element.editableContainer(containerOptions);
this.$element.on({ this.$element.on({
@ -229,10 +212,11 @@ Makes editable any HTML element on the page. Applied as jQuery method.
} }
//hide all other editable containers. Required to work correctly with toggle = manual //hide all other editable containers. Required to work correctly with toggle = manual
$('.editable-container').find('.editable-cancel').click(); //temp
//$('.editable-container').find('.editable-cancel').click();
//show container //show container
this.container.show(); this.container.show(multi);
}, },
/** /**
@ -247,7 +231,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
//return focus on element //return focus on element
if (this.options.enablefocus && this.options.toggle === 'click') { if (this.options.enablefocus && this.options.toggle === 'click') {
this.$element.focus(); this.$element.focus();
} }
}, },
/** /**