diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 03fd4c7..1d8bb37 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,9 @@ X-editable changelog Version 1.2.0 wip ---------------------------- +[enh] editableContainer removed from docs as not widely used (vitalets) +[enh] editableContainer: removed 'autohide' option and 'cancel' event. Use 'hidden' event instead (vitalets) +[enh] 'hidden' event: added param 'reason' that points to reason caused hiding (vitalets) [enh] 'select' submit by enter (vitalets) [bug #37] fix incorrectly shown datepicker in jquery 1.7.1 + webkit (vitalets) [enh] added url param 'jquery' to run tests in different versions of jquery, e.g. '&jquery=1.7.2' (vitalets) diff --git a/src/containers/editable-container.js b/src/containers/editable-container.js index 55fab88..5b2a9d9 100644 --- a/src/containers/editable-container.js +++ b/src/containers/editable-container.js @@ -80,8 +80,10 @@ Applied as jQuery method. .editableform(this.formOptions) .on({ save: $.proxy(this.save, this), - cancel: $.proxy(this.cancel, this), - show: $.proxy(this.setPosition, this), //re-position container every time form is shown (after loading state) + cancel: $.proxy(function(){ + this.hide('cancel'); + }, this), + 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 rendered: $.proxy(function(){ /** @@ -144,8 +146,9 @@ Applied as jQuery method. /** Hides container with form @method hide() + @param {string} reason Reason caused hiding. Can be <code>save|cancel|onblur|undefined (=manual)</code> **/ - hide: function() { + hide: function(reason) { if(!this.tip() || !this.tip().is(':visible') || !this.$element.hasClass('editable-open')) { return; } @@ -155,9 +158,17 @@ Applied as jQuery method. Fired when container was hidden. It occurs on both save or cancel. @event hidden - @param {Object} event event object + @param {object} event event object + @param {string} reason Reason caused hiding. Can be <code>save|cancel|onblur|undefined (=manual)</code> + @example + $('#username').on('hidden', function(e, reason) { + if(reason === 'save' || reason === 'cancel') { + //auto-open next editable + $(this).closest('tr').next().find('.editable').editable('show'); + } + }); **/ - this.$element.triggerHandler('hidden'); + this.$element.triggerHandler('hidden', reason); }, /* internal hide method. To be overwritten in child classes */ @@ -186,23 +197,8 @@ Applied as jQuery method. //tbd in child class }, - cancel: function() { - if(this.options.autohide) { - this.hide(); - } - /** - Fired when form was cancelled by user - - @event cancel - @param {Object} event event object - **/ - this.$element.triggerHandler('cancel'); - }, - save: function(e, params) { - if(this.options.autohide) { - this.hide(); - } + this.hide('save'); /** Fired when new value was submitted. You can use <code>$(this).data('editableContainer')</code> inside handler to access to editableContainer instance @@ -263,7 +259,7 @@ Applied as jQuery method. */ closeOthers: function(element) { $('.editable-open').each(function(i, el){ - //do nothing with passed element + //do nothing with passed element and it's children if(el === element || $(el).find(element).length) { return; } @@ -277,7 +273,7 @@ Applied as jQuery method. } if(ec.options.onblur === 'cancel') { - $el.data('editableContainer').hide(); + $el.data('editableContainer').hide('onblur'); } else if(ec.options.onblur === 'submit') { $el.data('editableContainer').tip().find('form').submit(); } diff --git a/src/element/editable-element.js b/src/element/editable-element.js index 6047336..e7ccf3a 100644 --- a/src/element/editable-element.js +++ b/src/element/editable-element.js @@ -246,15 +246,11 @@ Makes editable any HTML element on the page. Applied as jQuery method. //init editableContainer: popover, tooltip, inline, etc.. if(!this.container) { var containerOptions = $.extend({}, this.options, { - value: this.value, - autohide: false //element will take care to show/hide container. Otherwise hide() will be called twice + value: this.value }); this.$element.editableContainer(containerOptions); this.$element.on({ - save: $.proxy(this.save, this), - cancel: $.proxy(function(){ - this.hide(); - }, this) + save: $.proxy(this.save, this) }); this.container = this.$element.data('editableContainer'); } else if(this.container.tip().is(':visible')) { @@ -293,13 +289,13 @@ Makes editable any HTML element on the page. Applied as jQuery method. */ save: function(e, params) { //if url is not user's function and value was not sent to server and value changed --> mark element with unsaved css. - if(typeof this.options.url !== 'function' && params.response === undefined && this.input.value2str(this.value) !== this.input.value2str(params.newValue)) { + if(typeof this.options.url !== 'function' && this.options.display !== false && params.response === undefined && this.input.value2str(this.value) !== this.input.value2str(params.newValue)) { this.$element.addClass('editable-unsaved'); } else { this.$element.removeClass('editable-unsaved'); } - this.hide(); + // this.hide(); this.setValue(params.newValue); /** diff --git a/test/unit/api.js b/test/unit/api.js index e097fb5..93f0cfb 100644 --- a/test/unit/api.js +++ b/test/unit/api.js @@ -79,9 +79,9 @@ $(function () { e.editable(); }); - asyncTest("events: shown / cancel / hidden", function () { - expect(3); - var val = '1', + asyncTest("events: shown / hidden (reason: cancel, onblur, manual)", function () { + expect(11); + var val = '1', test_reason, e = $('<a href="#" data-pk="1" data-type="select" data-url="post.php" data-name="text" data-value="'+val+'"></a>').appendTo(fx); e.on('shown', function(event) { @@ -89,14 +89,8 @@ $(function () { equal(editable.value, val, 'shown triggered, value correct'); }); - e.on('cancel', function(event) { - var editable = $(this).data('editable'); - ok(true, 'cancel triggered'); - }); - - e.on('hidden', function(event) { - var editable = $(this).data('editable'); - ok(true, 'hidden triggered'); + e.on('hidden', function(event, reason) { + ok((reason === test_reason) || (test_reason === 'manual' && reason === undefined), 'hidden triggered, reason ok'); }); e.editable({ @@ -107,28 +101,42 @@ $(function () { setTimeout(function() { var p = tip(e); - p.find('button[type=button]').click(); - setTimeout(function() { - e.remove(); - start(); - }, timeout); + + test_reason = 'cancel' + p.find('button[type=button]').click(); //cancel + ok(!p.is(':visible'), 'popover closed'); + + test_reason = 'onblur' + e.click(); + p = tip(e); + ok(p.is(':visible'), 'popover shown'); + e.parent().click(); + ok(!p.is(':visible'), 'popover closed'); + + test_reason = 'manual' + e.click(); + p = tip(e); + ok(p.is(':visible'), 'popover shown'); + e.editable('hide'); + ok(!p.is(':visible'), 'popover closed'); + + e.remove(); + start(); }, timeout); }); - asyncTest("event: save / hidden", function () { + asyncTest("event: save / hidden (reason: save)", function () { expect(2); var val = '1', e = $('<a href="#" data-pk="1" data-type="select" data-url="post.php" data-name="text" data-value="'+val+'"></a>').appendTo(fx); e.on('save', function(event, params) { - var editable = $(this).data('editable'); equal(params.newValue, 2, 'save triggered, value correct'); }); - e.on('hidden', function(event) { - var editable = $(this).data('editable'); - ok(true, 'hidden triggered'); + e.on('hidden', function(event, reason) { + equal(reason, 'save', 'hidden triggered, reason ok'); }); e.editable({