Skip to content

Commit

Permalink
Add change event
Browse files Browse the repository at this point in the history
  • Loading branch information
samiheikki committed Mar 23, 2019
1 parent 66a3a85 commit 5c35dbd
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 1 deletion.
40 changes: 39 additions & 1 deletion src/vaadin-select.html
Expand Up @@ -318,7 +318,22 @@

_oldTemplate: Object,

_oldRenderer: Object
_oldRenderer: Object,

/**
* Used to detect user value changes and fire `change` events.
*/
_lastCommittedValue: String,

/**
* Used to detect opened value changes and fire `change` events.
*/
_wasOpened: Boolean,

/**
* Used to detect searched value changes and fire `change` events.
*/
_searchWithoutOpening: Boolean
};
}

Expand All @@ -345,6 +360,7 @@
ready() {
super.ready();

this._lastCommittedValue = this.value;
this._overlayElement = this.shadowRoot.querySelector('vaadin-select-overlay');
this._valueElement = this.shadowRoot.querySelector('[part="value"]');
this._toggleElement = this.shadowRoot.querySelector('[part="toggle-button"]');
Expand Down Expand Up @@ -474,6 +490,19 @@
return;
}
this.validate();

// In the next _detectAndDispatchChange() call, the change detection should pass
this._lastCommittedValue = undefined;
this._detectAndDispatchChange();
}

_detectAndDispatchChange() {
if ((this._wasOpened || this._searchWithoutOpening) && this.value !== this._lastCommittedValue) {
this.dispatchEvent(new CustomEvent('change', {bubbles: true}));
this._lastCommittedValue = this.value;
this._wasOpened = false;
this._searchWithoutOpening = false;
}
}

_onKeyDown(e) {
Expand All @@ -487,6 +516,7 @@
const currentIdx = selected !== undefined ? selected : -1;
const newIdx = this._menuElement._searchKey(currentIdx, e.key);
if (newIdx >= 0) {
this._searchWithoutOpening = true;
this._updateSelectedItem(this._items[newIdx].value, this._items);
}
}
Expand Down Expand Up @@ -517,6 +547,7 @@
this._menuElement.focus();
this._setPosition();
window.addEventListener('scroll', this._boundSetPosition, true);
this._lastCommittedValue = this.value;
} else if (wasOpened) {
if (this._phone) {
this._setFocused(false);
Expand All @@ -528,6 +559,7 @@
}
this.validate();
window.removeEventListener('scroll', this._boundSetPosition, true);
this._wasOpened = true;
}
}

Expand Down Expand Up @@ -644,6 +676,12 @@
validate() {
return !(this.invalid = !(this.disabled || !this.required || this.value));
}

/**
* Fired when value changes.
* To comply with https://developer.mozilla.org/en-US/docs/Web/Events/change
* @event change
*/
}

customElements.define(SelectElement.is, SelectElement);
Expand Down
73 changes: 73 additions & 0 deletions test/select-test.html
Expand Up @@ -817,6 +817,79 @@
expect(spy).not.to.have.been.called;
});
});

describe('`change` event', () => {
let menu, changeSpy, valueChangedSpy;
beforeEach(done => {
menu = select._menuElement;
Polymer.RenderStatus.afterNextRender(menu, done);

valueChangedSpy = sinon.spy();
select.addEventListener('value-changed', valueChangedSpy);

changeSpy = sinon.spy();
select.addEventListener('change', changeSpy);
});

it('should fire exactly one `change` event', () => {
select.opened = true;
menu.selected = 1;
select.opened = false;

expect(changeSpy.callCount).to.equal(1);
});

it('should not fire when closed', () => {
select.value = 'v2';
select.opened = true;
select.opened = false;

expect(changeSpy.callCount).to.equal(0);
});

it('should stop input `change` event from bubbling', () => {
select._inputElement.dispatchEvent(new CustomEvent('change'));

expect(changeSpy.callCount).to.equal(0);
});

it('should not set composed flag to true on `change` event', done => {
select.addEventListener('change', e => {
expect(e.composed).to.be.false;
done();
});

select.opened = true;
menu.selected = 1;
});

it('should not fire until close', () => {
select.opened = true;
menu.value = 'hello';
expect(changeSpy.callCount).to.equal(0);
});

it('should not fire `change` event when not commiting a value by closing', () => {
menu.selected = 1;

expect(changeSpy.callCount).to.equal(0);
});

it('should not fire for changes when closed', () => {
menu.selected = 1;
select.opened = true;
select.opened = false;
expect(changeSpy.callCount).to.equal(0);
});

it('should fire `change` events when value changes when alphanumeric keys are pressed', () => {
select.opened = false;
keyDownChar(input, 'o');
keyDownChar(input, 'p');
keyDownChar(input, 't');
expect(changeSpy.callCount).to.equal(1);
});
});
});

describe('vaadin-select theme attribute', () => {
Expand Down

0 comments on commit 5c35dbd

Please sign in to comment.