bug: source loaded twice if sourceCache = true

This commit is contained in:
vitalets
2013-01-08 13:33:09 +04:00
parent 2fd6340b03
commit f06b5c4d01
8 changed files with 68 additions and 43 deletions

@ -4,6 +4,7 @@ X-editable changelog
Version 1.4.0 wip Version 1.4.0 wip
---------------------------- ----------------------------
[bug] select: source loaded twice if sourceCache = false (vitalets)
[enh] added `destroy` method, see #61 (vitalets) [enh] added `destroy` method, see #61 (vitalets)
[enh] textarea: added `rows` property (vitalets) [enh] textarea: added `rows` property (vitalets)
[enh #60] added wysihtml5 input (vitalets) [enh #60] added wysihtml5 input (vitalets)

@ -33,7 +33,7 @@ Applied as jQuery method.
this.destroy(); this.destroy();
}, this)); }, this));
//attach document handlers (once) //attach document handler to close containers on click / escape
if(!$(document).data('editable-handlers-attached')) { if(!$(document).data('editable-handlers-attached')) {
//close all on escape //close all on escape
$(document).on('keyup.editable', function (e) { $(document).on('keyup.editable', function (e) {
@ -59,7 +59,7 @@ Applied as jQuery method.
} }
} }
//close all open containers (except one) //close all open containers (except one - target)
Popup.prototype.closeOthers(e.target); Popup.prototype.closeOthers(e.target);
}); });
@ -72,6 +72,7 @@ Applied as jQuery method.
this.containerOptions = {}; this.containerOptions = {};
this.formOptions = {}; this.formOptions = {};
var cDef = $.fn[this.containerName].defaults; var cDef = $.fn[this.containerName].defaults;
//keys defined in container defaults go to container, others go to form
for(var k in this.options) { for(var k in this.options) {
if(k in cDef) { if(k in cDef) {
this.containerOptions[k] = this.options[k]; this.containerOptions[k] = this.options[k];
@ -90,9 +91,9 @@ Applied as jQuery method.
this.$form = $('<div>') this.$form = $('<div>')
.editableform(this.formOptions) .editableform(this.formOptions)
.on({ .on({
save: $.proxy(this.save, this), save: $.proxy(this.save, this), //click on submit button (value changed)
cancel: $.proxy(function(){ this.hide('cancel'); }, this), nochange: $.proxy(function(){ this.hide('nochange'); }, this), //click on submit button (value NOT changed)
nochange: $.proxy(function(){ this.hide('nochange'); }, this), cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on calcel button
show: $.proxy(this.setPosition, this), //re-position container every time form is shown (occurs each time after loading state) show: $.proxy(this.setPosition, this), //re-position container every time form is shown (occurs each time after loading state)
rendering: $.proxy(this.setPosition, this), //this allows to place container correctly when loading shown rendering: $.proxy(this.setPosition, this), //this allows to place container correctly when loading shown
rendered: $.proxy(function(){ rendered: $.proxy(function(){

@ -21,8 +21,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
EditableForm.prototype = { EditableForm.prototype = {
constructor: EditableForm, constructor: EditableForm,
initInput: function() { //called once initInput: function() { //called once
//create input of specified type //take input from options or create new input instance
this.input = $.fn.editableutils.createInput(this.options); this.input = this.options.input || $.fn.editableutils.createInput(this.options);
if(!this.input) { if(!this.input) {
return; return;
} }

@ -241,7 +241,8 @@ Makes editable any HTML element on the page. Applied as jQuery method.
//init editableContainer: popover, tooltip, inline, etc.. //init editableContainer: popover, tooltip, inline, etc..
if(!this.container) { if(!this.container) {
var containerOptions = $.extend({}, this.options, { var containerOptions = $.extend({}, this.options, {
value: this.value value: this.value,
input: this.input //pass input to form (as it is already created)
}); });
this.$element.editableContainer(containerOptions); this.$element.editableContainer(containerOptions);
this.$element.on("save.internal", $.proxy(this.save, this)); this.$element.on("save.internal", $.proxy(this.save, this));
@ -355,6 +356,9 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(this.container) { if(this.container) {
this.container.destroy(); this.container.destroy();
} }
this.$element.off("save.internal");
this.$element.removeClass('editable'); this.$element.removeClass('editable');
this.$element.removeClass('editable-open'); this.$element.removeClass('editable-open');
this.$element.removeData('editable'); this.$element.removeData('editable');

@ -32,6 +32,9 @@ $(function(){
$.extend(Checklist.prototype, { $.extend(Checklist.prototype, {
renderList: function() { renderList: function() {
var $label, $div; var $label, $div;
this.$tpl.empty();
if(!$.isArray(this.sourceData)) { if(!$.isArray(this.sourceData)) {
return; return;
} }

@ -17,8 +17,6 @@ List - abstract class for inputs that have source option loaded from js array or
var deferred = $.Deferred(); var deferred = $.Deferred();
this.error = null; this.error = null;
this.sourceData = null;
this.prependData = null;
this.onSourceReady(function () { this.onSourceReady(function () {
this.renderList(); this.renderList();
deferred.resolve(); deferred.resolve();

@ -30,12 +30,14 @@ $(function(){
$.extend(Select.prototype, { $.extend(Select.prototype, {
renderList: function() { renderList: function() {
this.$input.empty();
if(!$.isArray(this.sourceData)) { if(!$.isArray(this.sourceData)) {
return; return;
} }
for(var i=0; i<this.sourceData.length; i++) { for(var i=0; i<this.sourceData.length; i++) {
this.$tpl.append($('<option>', {value: this.sourceData[i].value}).text(this.sourceData[i].text)); this.$input.append($('<option>', {value: this.sourceData[i].value}).text(this.sourceData[i].text));
} }
this.setClass(); this.setClass();

@ -37,7 +37,15 @@ $(function () {
equal(p.find('select').find('option').length, size, 'options loaded'); equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ; equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
p.find('.editable-cancel').click(); p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed'); ok(!p.is(':visible'), 'popover was removed');
//open second time: items should not dublicate
e.click();
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
e.remove(); e.remove();
start(); start();
}, timeout); }, timeout);
@ -384,50 +392,58 @@ $(function () {
asyncTest("sourceCache: false", function () { asyncTest("sourceCache: false", function () {
var e = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="2" data-url="post.php" data-source="groups-cache-false.php">customer</a>').appendTo(fx).editable({
sourceCache: false $.mockjax({
}),
e1 = $('<a href="#" data-type="select" data-pk="1" id="name1" data-value="2" data-url="post.php" data-source="groups-cache-false.php">customer</a>').appendTo(fx).editable({
sourceCache: false
}),
req = 0;
$.mockjax({
url: 'groups-cache-false.php', url: 'groups-cache-false.php',
response: function() { response: function() {
req++; req++;
this.responseText = groups; this.responseText = groups;
} }
}); });
//click first var req = 0,
e.click(); e = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="2" data-url="post.php" data-source="groups-cache-false.php"></a>').appendTo(fx).editable({
var p = tip(e); sourceCache: false
}),
e1 = $('<a href="#" data-type="select" data-pk="1" id="name1" data-value="2" data-url="post.php" data-source="groups-cache-false.php">customer</a>').appendTo(fx).editable({
sourceCache: false
});
setTimeout(function() { setTimeout(function() {
ok(p.is(':visible'), 'popover visible'); equal(req, 1, 'autotext request performed');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 1, 'one request performed'); //click first
e.click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
//click second
e1.click();
p = tip(e1);
setTimeout(function() { setTimeout(function() {
ok(p.is(':visible'), 'popover2 visible');
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
equal(p.find('select').find('option').length, size, 'options loaded'); equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 2, 'second request performed'); equal(req, 1, 'no additional request performed, loaded on autotext');
p.find('.editable-cancel').click(); p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed'); ok(!p.is(':visible'), 'popover was removed');
e.remove(); //click second
e1.remove(); e1.click();
start(); p = tip(e1);
}, timeout);
setTimeout(function() {
ok(p.is(':visible'), 'popover2 visible');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 2, 'second request performed');
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
e1.remove();
start();
}, timeout);
}, timeout);
}, timeout); }, timeout);
}); });