refactor containers: same render logic, fix tests

This commit is contained in:
vitalets
2013-01-11 17:07:00 +04:00
parent 775deede07
commit 0ced7f87f5
9 changed files with 230 additions and 137 deletions

@ -26,6 +26,10 @@ Applied as jQuery method.
//todo: what is in priority: data or js?
this.options = $.extend({}, $.fn.editableContainer.defaults, $.fn.editableutils.getConfigData(this.$element), options);
this.splitOptions();
//set scope of form callbacks to element
this.formOptions.scope = this.$element[0];
this.initContainer();
//bind 'destroyed' listener to destroy container when element is removed from dom
@ -82,13 +86,29 @@ Applied as jQuery method.
}
},
/*
Returns jquery object of container
@method tip()
*/
tip: function() {
return this.container() ? this.container().$tip : null;
},
/* returns container object */
container: function() {
return this.$element.data(this.containerName);
},
call: function() {
this.$element[this.containerName].apply(this.$element, arguments);
},
initContainer: function(){
this.call(this.containerOptions);
},
initForm: function() {
this.formOptions.scope = this.$element[0]; //set scope of form callbacks to element
this.$form = $('<div>')
renderForm: function() {
this.$form
.editableform(this.formOptions)
.on({
save: $.proxy(this.save, this), //click on submit button (value changed)
@ -110,31 +130,16 @@ Applied as jQuery method.
**/
this.$element.triggerHandler('shown');
}, this)
});
return this.$form;
})
.editableform('render');
},
/*
Returns jquery object of container
@method tip()
*/
tip: function() {
return this.container().$tip;
},
container: function() {
return this.$element.data(this.containerName);
},
call: function() {
this.$element[this.containerName].apply(this.$element, arguments);
},
/**
Shows container with form
@method show()
@param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true.
**/
**/
/* Note: poshytip owerwrites this method totally! */
show: function (closeAll) {
this.$element.addClass('editable-open');
if(closeAll !== false) {
@ -142,16 +147,37 @@ Applied as jQuery method.
this.closeOthers(this.$element[0]);
}
//show container itself
this.innerShow();
},
/* internal show method. To be overwritten in child classes */
innerShow: function () {
this.call('show');
this.tip().addClass('editable-container');
this.initForm();
this.tip().find(this.innerCss).empty().append(this.$form);
this.$form.editableform('render');
/*
Currently, form is re-rendered on every show.
The main reason is that we dont know, what container will do with content when closed:
remove(), detach() or just hide().
Detaching form itself before hide and re-insert before show is good solution,
but visually it looks ugly, as container changes size before hide.
*/
//if form already exist - delete previous data
if(this.$form) {
//todo: destroy prev data!
//this.$form.destroy();
}
this.$form = $('<div>');
//insert form into container body
if(this.tip().is(this.innerCss)) {
//for inline container
this.tip().append(this.$form);
} else {
this.tip().find(this.innerCss).append(this.$form);
}
//render form
this.renderForm();
},
/**
@ -163,8 +189,10 @@ Applied as jQuery method.
if(!this.tip() || !this.tip().is(':visible') || !this.$element.hasClass('editable-open')) {
return;
}
this.$element.removeClass('editable-open');
this.innerHide();
/**
Fired when container was hidden. It occurs on both save or cancel.
@ -182,9 +210,14 @@ Applied as jQuery method.
this.$element.triggerHandler('hidden', reason);
},
/* internal show method. To be overwritten in child classes */
innerShow: function () {
},
/* internal hide method. To be overwritten in child classes */
innerHide: function () {
this.call('hide');
},
/**
@ -193,7 +226,7 @@ Applied as jQuery method.
@param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true.
**/
toggle: function(closeAll) {
if(this.tip && this.tip().is(':visible')) {
if(this.container() && this.tip() && this.tip().is(':visible')) {
this.hide();
} else {
this.show(closeAll);
@ -261,11 +294,17 @@ Applied as jQuery method.
@method destroy()
**/
destroy: function() {
this.call('destroy');
this.hide();
this.innerDestroy();
this.$element.off('destroyed');
this.$element.removeData('editableContainer');
},
/* to be overwritten in child classes */
innerDestroy: function() {
},
/*
Closes other containers except one related to passed element.
Other containers can be cancelled or submitted (depends on onblur option)

@ -8,49 +8,42 @@
//extend methods
$.extend($.fn.editableContainer.Inline.prototype, $.fn.editableContainer.Popup.prototype, {
containerName: 'editableform',
innerCss: null,
innerCss: '.editable-inline',
initContainer: function(){
//no init for container
//only convert anim to miliseconds (int)
//container is <span> element
this.$tip = $('<span></span>').addClass('editable-inline');
//convert anim to miliseconds (int)
if(!this.options.anim) {
this.options.anim = 0;
}
},
splitOptions: function() {
//all options are passed to form
this.containerOptions = {};
this.formOptions = this.options;
},
tip: function() {
return this.$form;
return this.$tip;
},
innerShow: function () {
this.$element.hide();
if(this.$form) {
this.$form.remove();
}
this.initForm();
this.tip().addClass('editable-container').addClass('editable-inline');
this.$form.insertAfter(this.$element);
this.$form.show(this.options.anim);
this.$form.editableform('render');
this.tip().insertAfter(this.$element).show();
},
innerHide: function () {
this.$form.hide(this.options.anim, $.proxy(function() {
this.$tip.hide(this.options.anim, $.proxy(function() {
this.$element.show();
this.tip().empty().remove();
}, this));
},
destroy: function() {
innerDestroy: function() {
this.tip().remove();
this.$element.off('destroyed');
this.$element.removeData('editableContainer');
}
});

@ -29,9 +29,25 @@
this.call(this.containerOptions);
if(t) {
//restore data('template')
this.$element.data('template', t);
}
},
},
/* show */
innerShow: function () {
this.call('show');
},
/* hide */
innerHide: function () {
this.call('hide');
},
/* destroy */
innerDestroy: function() {
this.call('destroy');
},
setContainerOption: function(key, value) {
this.container().options[key] = value;

@ -20,20 +20,41 @@
});
this.call(this.containerOptions);
var $content = $('<div>')
.append($('<label>').text(this.options.title || this.$element.data( "title") || this.$element.data( "originalTitle")))
.append(this.initForm());
this.call('update', $content);
},
innerShow: function () {
this.$form.editableform('render');
/*
Overwrite totally show() method as poshytip requires content is set before show
*/
show: function (closeAll) {
this.$element.addClass('editable-open');
if(closeAll !== false) {
//close all open containers (except this)
this.closeOthers(this.$element[0]);
}
//render form
this.$form = $('<div>');
this.renderForm();
var $label = $('<label>').text(this.options.title || this.$element.data( "title") || this.$element.data( "originalTitle")),
$content = $('<div>').append($label).append(this.$form);
this.call('update', $content);
this.call('show');
this.tip().addClass('editable-container');
this.$form.data('editableform').input.activate();
},
},
/* hide */
innerHide: function () {
this.call('hide');
},
/* destroy */
innerDestroy: function() {
this.call('destroy');
},
setPosition: function() {
this.container().refresh(false);

@ -47,25 +47,23 @@
},
tip: function() {
return this.container()._find(this.container().element);
return this.container() ? this.container()._find(this.container().element) : null;
},
innerShow: function() {
this.call('open');
this.tip().addClass('editable-container');
this.initForm();
this.tip().find(this.innerCss)
.empty()
.append($('<label>').text(this.options.title || this.$element.data( "ui-tooltip-title") || this.$element.data( "originalTitle")))
.append(this.$form);
this.$form.editableform('render');
var label = this.options.title || this.$element.data( "ui-tooltip-title") || this.$element.data( "originalTitle");
this.tip().find(this.innerCss).empty().append($('<label>').text(label));
},
innerHide: function() {
this.call('close');
},
innerDestroy: function() {
/* tooltip destroys itself on hide */
},
setPosition: function() {
this.tip().position( $.extend({
of: this.$element
@ -102,11 +100,8 @@
}
this.containerOptions.position = pos;
},
destroy: function() {
//jqueryui tooltip destroys itself
}
}
});
}(window.jQuery));