diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 3996703..fdef278 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,6 +5,7 @@ X-editable changelog Version 1.4.2 wip ---------------------------- +[enh] source defined as function now has scope of element and can return string used as url (vitalets) [bug #99] select2 with Hierarchical Data (kev360) [bug #81] wysihtml5: fix inserting image (vitalets) [bug] remove $.browser from wysihtml5 input to support jQuery 1.9 (vitalets) diff --git a/src/element/editable-element.js b/src/element/editable-element.js index 10a4366..9836455 100644 --- a/src/element/editable-element.js +++ b/src/element/editable-element.js @@ -26,7 +26,9 @@ Makes editable any HTML element on the page. Applied as jQuery method. //name this.options.name = this.options.name || this.$element.attr('id'); - //create input of specified type. Input need already here to convert value for initial display (e.g. show text by id for select) + //create input of specified type. Input needed already here to convert value for initial display (e.g. show text by id for select) + //also we set scope option to have access to element inside input specific callbacks (e. g. source as function) + this.options.scope = this.$element[0]; this.input = $.fn.editableutils.createInput(this.options); if(!this.input) { return; diff --git a/src/inputs/abstract.js b/src/inputs/abstract.js index e32c844..c1ad480 100644 --- a/src/inputs/abstract.js +++ b/src/inputs/abstract.js @@ -186,7 +186,10 @@ To create your own input you can inherit from this class. @type string @default input-medium **/ - inputclass: 'input-medium' + inputclass: 'input-medium', + //scope for external methods (e.g. source defined as function) + //for internal use only + scope: null }; $.extend($.fn.editabletypes, {abstractinput: AbstractInput}); diff --git a/src/inputs/list.js b/src/inputs/list.js index e5fcb00..d01de0b 100644 --- a/src/inputs/list.js +++ b/src/inputs/list.js @@ -70,12 +70,19 @@ List - abstract class for inputs that have source option loaded from js array or error.call(this); return; } + + var source = this.options.source; + + //run source if it function + if ($.isFunction(source)) { + source = source.call(this.options.scope); + } //loading from url - if (typeof this.options.source === 'string') { + if (typeof source === 'string') { //try to get from cache if(this.options.sourceCache) { - var cacheID = this.options.source, + var cacheID = source, cache; if (!$(document).data(cacheID)) { @@ -108,7 +115,7 @@ List - abstract class for inputs that have source option loaded from js array or //loading sourceData from server $.ajax({ - url: this.options.source, + url: source, type: 'get', cache: false, dataType: 'json', @@ -143,12 +150,8 @@ List - abstract class for inputs that have source option loaded from js array or } }, this) }); - } else { //options as json/array/function - if ($.isFunction(this.options.source)) { - this.sourceData = this.makeArray(this.options.source()); - } else { - this.sourceData = this.makeArray(this.options.source); - } + } else { //options as json/array + this.sourceData = this.makeArray(source); if($.isArray(this.sourceData)) { this.doPrepend(); @@ -165,16 +168,20 @@ List - abstract class for inputs that have source option loaded from js array or } if(!$.isArray(this.prependData)) { + //run prepend if it is function (once) + if ($.isFunction(this.options.prepend)) { + this.options.prepend = this.options.prepend.call(this.options.scope); + } + //try parse json in single quotes this.options.prepend = $.fn.editableutils.tryParseJson(this.options.prepend, true); + + //convert prepend from string to object if (typeof this.options.prepend === 'string') { this.options.prepend = {'': this.options.prepend}; - } - if (typeof this.options.prepend === 'function') { - this.prependData = this.makeArray(this.options.prepend()); - } else { - this.prependData = this.makeArray(this.options.prepend); } + + this.prependData = this.makeArray(this.options.prepend); } if($.isArray(this.prependData) && $.isArray(this.sourceData)) { diff --git a/test/unit/select.js b/test/unit/select.js index 93a0321..e4a34e3 100644 --- a/test/unit/select.js +++ b/test/unit/select.js @@ -105,11 +105,15 @@ $(function () { ok(!p.is(':visible'), 'popover was removed'); }); - test("load options from function", function () { + test("load options from function returning array", function () { var e = $('<a href="#" data-type="select" data-value="2" data-url="post.php">customer</a>').appendTo('#qunit-fixture').editable({ pk: 1, - prepend: 'prepend', + prepend: function() { + equal(this, e[0], 'prepend scope is element'); + return 'prepend'; + }, source: function() { + equal(this, e[0], 'source scope is element'); return groups; } }); @@ -124,6 +128,40 @@ $(function () { ok(!p.is(':visible'), 'popover was removed'); }); + asyncTest("load options from function returning URL", function () { + var e = $('<a href="#" data-type="select" data-value="2" data-url="post.php">customer</a>').appendTo('#qunit-fixture').editable({ + pk: 1, + //need to disable cache to force request + sourceCache: false, + source: function() { + equal(this, e[0], 'source scope is element'); + return 'groups.php'; + } + }); + + e.click(); + var p = tip(e); + + setTimeout(function() { + ok(p.is(':visible'), 'popover visible'); + 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') ; + p.find('.editable-cancel').click(); + 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(); + start(); + }, timeout); + }); + test("load options from html (single quotes)", function () { var e = $('<a href="#" data-type="select" data-value="M" data-source=\'{"L":"Low", "": "None", "M": "Medium", "H": "High"}\'>customer</a>').appendTo('#qunit-fixture').editable({ pk: 1