Skip to content

Commit

Permalink
feat: add autoOpenDisabled property (#853)
Browse files Browse the repository at this point in the history
Co-authored-by: web-padawan <iamkulykov@gmail.com>
  • Loading branch information
Nii Yeboah and web-padawan committed Mar 30, 2020
1 parent a35cd90 commit 7d0931d
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 12 deletions.
45 changes: 33 additions & 12 deletions src/vaadin-combo-box-mixin.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
observer: '_openedChanged'
},

/**
* Set true to prevent the overlay from opening automatically.
*/
autoOpenDisabled: Boolean,

/**
* Set to true to disable this element.
*/
Expand Down Expand Up @@ -273,7 +278,7 @@
});
}
};

this.addEventListener('mousedown', bringToFrontListener);
this.addEventListener('touchstart', bringToFrontListener);
}
Expand Down Expand Up @@ -366,7 +371,7 @@
} else if (path.indexOf(this.inputElement) !== -1) {
if (path.indexOf(this._toggleElement) > -1 && this.opened) {
this.close();
} else {
} else if (path.indexOf(this._toggleElement) > -1 || !this.autoOpenDisabled) {
this.open();
}
}
Expand Down Expand Up @@ -487,11 +492,19 @@
}
}

_closeOrCommit() {
if (this.autoOpenDisabled && !this.opened) {
this._commitValue();
} else {
this.close();
}
}

_onEnter(e) {
// should close on enter when custom values are allowed, input field is cleared, or when an existing
// item is focused with keyboard.
if (this.opened && (this.allowCustomValue || this._inputElementValue === '' || this._focusedIndex > -1)) {
this.close();
// item is focused with keyboard. If auto open is disabled, under the same conditions, commit value.
if ((this.opened || this.autoOpenDisabled) && (this.allowCustomValue || this._inputElementValue === '' || this._focusedIndex > -1)) {
this._closeOrCommit();

// Do not submit the surrounding form.
e.preventDefault();
Expand All @@ -502,7 +515,10 @@
}

_onEscape(e) {
if (this.opened) {
if (this.autoOpenDisabled) {
this._focusedIndex = -1;
this.cancel();
} else if (this.opened) {
this._stopPropagation(e);

if (this._focusedIndex > -1) {
Expand Down Expand Up @@ -547,7 +563,7 @@
this._revertInputValueToValue();
// In the next _detectAndDispatchChange() call, the change detection should not pass
this._lastCommittedValue = this.value;
this.close();
this._closeOrCommit();
}

_onOpened() {
Expand Down Expand Up @@ -577,12 +593,15 @@
}

_onClosed() {

// Happens when the overlay is closed by clicking outside
if (this.opened) {
this.close();
}

this._commitValue();
}

_commitValue() {
if (this.$.overlay._items && this._focusedIndex > -1) {
const focusedItem = this.$.overlay._items[this._focusedIndex];
if (this.selectedItem !== focusedItem) {
Expand Down Expand Up @@ -638,7 +657,7 @@
}

_filterFromInput(e) {
if (!this.opened && !e.__fromClearButton) {
if (!this.opened && !e.__fromClearButton && !this.autoOpenDisabled) {
this.open();
}

Expand Down Expand Up @@ -805,7 +824,7 @@
if (e.path === 'filteredItems' || e.path === 'filteredItems.splices') {
this._setOverlayItems(this.filteredItems);

this._focusedIndex = this.opened ?
this._focusedIndex = this.opened || this.autoOpenDisabled ?
this.$.overlay.indexOfLabel(this.filter) :
this._indexOfValue(this.value, this.filteredItems);

Expand All @@ -820,11 +839,13 @@
return arr;
}

return arr.filter(item => {
const filteredItems = arr.filter(item => {
filter = filter ? filter.toString().toLowerCase() : '';
// Check if item contains input value.
return this._getItemLabel(item).toString().toLowerCase().indexOf(filter) > -1;
});

return !filteredItems.length && this.autoOpenDisabled ? arr : filteredItems;
}

_selectItemForValue(value) {
Expand Down Expand Up @@ -922,7 +943,7 @@
return;
}
if (!this._closeOnBlurIsPrevented) {
this.close();
this._closeOrCommit();
}
}

Expand Down
20 changes: 20 additions & 0 deletions test/filtering.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@
expect(comboBox.opened).to.equal(true);
});

it('should not open the popup if closed and autoOpenDisabled is true', () => {
comboBox.autoOpenDisabled = true;
comboBox.close();

setInputValue('foo');

expect(comboBox.opened).to.equal(false);
});

it('should open the popup when the value of the input field is set to none', () => {
comboBox.value = 'foo';
comboBox.close();
Expand All @@ -67,6 +76,17 @@
expect(comboBox.opened).to.equal(true);
});

it('should not open the popup when the value of the input field is set to none and autoOpenDisabled is true', () => {
comboBox.autoOpenDisabled = true;
comboBox.value = 'foo';
comboBox.close();
expect(comboBox.opened).to.equal(false);

setInputValue('');

expect(comboBox.opened).to.equal(false);
});

it('should not change the value of the combobox', () => {
comboBox.value = 'foo';
setInputValue('bar');
Expand Down
73 changes: 73 additions & 0 deletions test/keyboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@
}
}

function inputChar(char) {
const target = comboBox.inputElement;
target.value += char;
MockInteractions.keyDownOn(target, char.charCodeAt(0));
target.dispatchEvent(new CustomEvent('input', {bubbles: true, composed: true}));
}

function inputText(text) {
for (var i = 0; i < text.length; i++) {
inputChar(text[i]);
}
}

function arrowDown(cb) {
pushKey(40, cb);
}
Expand Down Expand Up @@ -544,6 +557,66 @@
});
});
});

describe('auto open disabled', () => {

beforeEach(() => {
comboBox.autoOpenDisabled = true;
});

it('should open the overlay with arrow down', () => {
arrowDown();
expect(comboBox.opened).to.equal(true);
});

it('should open the overlay with arrow up', () => {
arrowUp();
expect(comboBox.opened).to.equal(true);
});

it('should apply input value on focusout if input valid', () => {
inputText('FOO');
comboBox.dispatchEvent(new Event('focusout'));
expect(comboBox._inputElementValue).to.equal('foo');
expect(comboBox.value).to.equal('foo');
});

it('should apply input value on enter if input valid', () => {
inputText('FOO');
enter();
expect(comboBox._inputElementValue).to.equal('foo');
expect(comboBox.value).to.equal('foo');
});

it('should not apply input value on enter if input invalid', () => {
inputText('quux');
enter();
expect(comboBox._inputElementValue).to.equal('quux');
expect(comboBox.value).to.equal('');
});

it('should revert input value on focusout if input invalid', () => {
inputText('quux');
comboBox.dispatchEvent(new Event('focusout'));
expect(comboBox._inputElementValue).to.equal('');
expect(comboBox.value).to.equal('');
});

it('should revert input value on esc if input valid', () => {
inputText('foo');
esc();
expect(comboBox._inputElementValue).to.equal('');
expect(comboBox.value).to.equal('');
});

it('should revert input value on esc if input invalid', () => {
inputText('quux');
esc();
expect(comboBox._inputElementValue).to.equal('');
expect(comboBox.value).to.equal('');
});

});
});
</script>

Expand Down
24 changes: 24 additions & 0 deletions test/toggling-dropdown.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@
expect(combobox.opened).to.be.true;
});

it('should not open synchronously by clicking label when autoOpenDisabled is true', () => {
combobox.autoOpenDisabled = true;
expect(combobox.opened).to.be.false;
fireMousedownMouseupClick(combobox.inputElement.root.querySelector('label'));
expect(combobox.opened).to.be.false;
});

it('should restore attribute focus-ring if it was initially set before opening and combo-box is focused', () => {
combobox.setAttribute('focus-ring', '');
combobox.opened = true;
Expand All @@ -80,12 +87,29 @@
expect(combobox.opened).to.be.true;
});

it('should not open synchronously by clicking input when autoOpenDisabled is true', () => {
combobox.autoOpenDisabled = true;
expect(combobox.opened).to.be.false;
fireMousedownMouseupClick(combobox.inputElement);
expect(combobox.opened).to.be.false;
});

it('should open by clicking icon', () => {
clickToggleIcon();

expect(combobox.opened).to.be.true;
});

it('should open by clicking icon when autoOpenDisabled is true and input is invalid', () => {
combobox.autoOpenDisabled = true;
combobox.inputElement.value = 3;
combobox.inputElement.dispatchEvent(new CustomEvent('input'));

clickToggleIcon();

expect(combobox.opened).to.be.true;
});

it('should open on function call', () => {
combobox.open();

Expand Down

0 comments on commit 7d0931d

Please sign in to comment.