diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index 89bd2e2dbfc..0f1d8f39550 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -415,6 +415,10 @@ _onSelectRecipient: function(e, s) { e.preventDefault(); + // Ensure that the keydown handler for the input field is not + // called; otherwise it would try to add the recipient again, which + // would fail. + e.stopImmediatePropagation(); $(e.target).attr('disabled', true) .val(s.item.label); var $loading = this.$el.find('.shareWithLoading'); @@ -451,6 +455,15 @@ $shareWithField.prop('disabled', true); + // Disabling the autocompletion does not clear its search timeout; + // removing the focus from the input field does, but only if the + // autocompletion is not disabled when the field loses the focus. + // Thus, the field has to be disabled before disabling the + // autocompletion to prevent an old pending search result from + // appearing once the field is enabled again. + $shareWithField.autocomplete('close'); + $shareWithField.autocomplete('disable'); + var perPage = 200; var onlyExactMatches = true; this._getSuggestions( @@ -467,6 +480,8 @@ $shareWithField.prop('disabled', false); $shareWithField.focus(); + $shareWithField.autocomplete('enable'); + // There is no need to show an error message here; it will // be automatically shown when the autocomplete is activated // again (due to the focus on the field) and it finds no @@ -483,6 +498,8 @@ $shareWithField.prop('disabled', false); $shareWithField.focus(); + $shareWithField.autocomplete('enable'); + return; } @@ -494,6 +511,8 @@ $shareWithField.val(''); $shareWithField.prop('disabled', false); $shareWithField.focus(); + + $shareWithField.autocomplete('enable'); }; var actionError = function(obj, msg) { @@ -504,6 +523,8 @@ $shareWithField.prop('disabled', false); $shareWithField.focus(); + $shareWithField.autocomplete('enable'); + OC.Notification.showTemporary(msg); }; @@ -519,6 +540,8 @@ $shareWithField.prop('disabled', false); $shareWithField.focus(); + $shareWithField.autocomplete('enable'); + // There is no need to show an error message here; it will be // automatically shown when the autocomplete is activated again // (due to the focus on the field) and getting the suggestions @@ -554,6 +577,7 @@ }, render: function() { + var self = this; var baseTemplate = this._getTemplate('base', TEMPLATE_BASE); this.$el.html(baseTemplate({ @@ -565,6 +589,16 @@ var $shareField = this.$el.find('.shareWithField'); if ($shareField.length) { + var shareFieldKeydownHandler = function(event) { + if (event.keyCode !== 13) { + return true; + } + + self._confirmShare(); + + return false; + }; + $shareField.autocomplete({ minLength: 1, delay: 750, @@ -574,6 +608,8 @@ source: this.autocompleteHandler, select: this._onSelectRecipient }).data('ui-autocomplete')._renderItem = this.autocompleteRenderItem; + + $shareField.on('keydown', null, shareFieldKeydownHandler); } this.resharerInfoView.$el = this.$el.find('.resharerInfoView'); diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js index 76a214f6705..7ef38c022dd 100644 --- a/core/js/tests/specs/sharedialogviewSpec.js +++ b/core/js/tests/specs/sharedialogviewSpec.js @@ -1872,6 +1872,8 @@ describe('OC.Share.ShareDialogView', function() { expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); + expect(autocompleteStub.lastCall.args[0]).toEqual('disable'); + expect(autocompleteStub.calledWith('close')).toEqual(true); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); }); @@ -1918,6 +1920,7 @@ describe('OC.Share.ShareDialogView', function() { // Ensure that the UI is not restored before adding the share expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); + expect(autocompleteStub.lastCall.args[0]).toEqual('disable'); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); @@ -1933,6 +1936,7 @@ describe('OC.Share.ShareDialogView', function() { expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); expect(dialog.$el.find('.shareWithField').val()).toEqual(''); }); @@ -1981,6 +1985,7 @@ describe('OC.Share.ShareDialogView', function() { // Ensure that the UI is not restored before adding the share expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); + expect(autocompleteStub.lastCall.args[0]).toEqual('disable'); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); @@ -1996,6 +2001,7 @@ describe('OC.Share.ShareDialogView', function() { expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); @@ -2037,6 +2043,7 @@ describe('OC.Share.ShareDialogView', function() { expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); @@ -2088,6 +2095,7 @@ describe('OC.Share.ShareDialogView', function() { expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); expect(dialog.$el.find('.shareWithField').val()).toEqual('bo'); }); @@ -2143,6 +2151,7 @@ describe('OC.Share.ShareDialogView', function() { expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); }); @@ -2171,6 +2180,7 @@ describe('OC.Share.ShareDialogView', function() { expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); @@ -2188,6 +2198,7 @@ describe('OC.Share.ShareDialogView', function() { expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); + expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); expect(dialog.$el.find('.shareWithField').val()).toEqual('bob');