Skip to content

Commit

Permalink
fix(md-select): fire blur after dropdown hides
Browse files Browse the repository at this point in the history
  • Loading branch information
Ullfis committed Sep 8, 2016
1 parent 1e1079d commit 6fae969
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 53 deletions.
6 changes: 3 additions & 3 deletions sample/src/samples/select/basic-use.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</md-card>

<md-card md-title="Disabled Functionality">
<select md-select="disabled.bind: disabled" value.two-way="selectedValue">
<select md-select="disabled.bind: disabled" value.two-way="selectedValue2">
<option value="" disabled selected>select an item</option>
<option value="item1">item 1</option>
<option value="item2">item 2</option>
Expand All @@ -24,8 +24,8 @@
</select>

<div>
<a md-button="flat: true;" md-waves click.trigger="setSelectedValue()" class="accent-text">set to item 3</a>
You selected: ${selectedValue}
<a md-button="flat: true;" md-waves click.trigger="setSelectedValue2()" class="accent-text">set to item 3</a>
You selected: ${selectedValue2}
</div>
<div>
<a md-button="flat: true;" md-waves click.trigger="toggle()" class="accent-text">${ disabled ? 'enable' :
Expand Down
5 changes: 5 additions & 0 deletions sample/src/samples/select/basic-use.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
export class BasicUse {
disabled = true;
selectedValue = '';
selectedValue2 = '';

setSelectedValue() {
this.selectedValue = 'item3';
}

setSelectedValue2() {
this.selectedValue2 = 'item3';
}

toggle() {
this.disabled = !this.disabled;
}
Expand Down
2 changes: 1 addition & 1 deletion sample/src/samples/select/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"samples": {
"basic-use": {
"route": ["", "basic-use"],
"files": ["html"]
"files": ["html", "js"]
},
"multiple": {
"route": "multiple",
Expand Down
102 changes: 53 additions & 49 deletions src/select/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {inject} from 'aurelia-dependency-injection';
import {TaskQueue} from 'aurelia-task-queue';
import * as LogManager from 'aurelia-logging';
import {fireEvent} from '../common/events';
import {DOM} from 'aurelia-pal';

@inject(Element, LogManager, BindingEngine, TaskQueue)
@customAttribute('md-select')
Expand All @@ -13,6 +14,7 @@ export class MdSelect {
_suspendUpdate = false;
subscriptions = [];
input = null;
dropdownMutationObserver = null;
constructor(element, logManager, bindingEngine, taskQueue) {
this.element = element;
Expand Down Expand Up @@ -48,7 +50,8 @@ export class MdSelect {
detached() {
$(this.element).off('change', this.handleChangeFromNativeSelect);
this.attachBlur(false);
this.observeVisibleDropdownContent(false);
this.dropdownMutationObserver = null;
$(this.element).material_select('destroy');
this.subscriptions.forEach(sub => sub.dispose());
}
Expand All @@ -59,34 +62,6 @@ export class MdSelect {
});
}
handleBlur() {
this.log.debug('handleBlur called');
// problem: if this comes from an actual "blur" event, the event is fired too early
// if this comes from a "change" event, the timing is correct
// take 1
// setTimeout(() => {
// fireEvent(this.element, 'blur');
// }, 200);
// TaskQueue doesn't change anything because the "change" event is fired after
// the queue has been processed

// take 2
// if (!this._blurHandled) {
// this.taskQueue.queueTask(() => {
// fireEvent(this.element, 'blur');
// this.log.debug('blur event fired');
// this._blurHandled = false;
// });
// this._blurHandled = true;
// }

// take 3
fireEvent(this.element, 'blur');
}

disabledChanged(newValue) {
this.toggleControl(newValue);
}
Expand Down Expand Up @@ -127,32 +102,61 @@ export class MdSelect {
}
}
attachBlur(attach) {
createMaterialSelect(destroy) {
this.observeVisibleDropdownContent(false);
if (destroy) {
$(this.element).material_select('destroy');
}
$(this.element).material_select();
this.toggleControl(this.disabled);
this.observeVisibleDropdownContent(true);
}
observeVisibleDropdownContent(attach) {
if (attach) {
let $wrapper = $(this.element).parent('.select-wrapper');
if ($wrapper.length > 0) {
this.input = $('input.select-dropdown:first', $wrapper);
if (this.input) {
this.input.on('blur', this.handleBlur);
}
if (!this.dropdownMutationObserver) {
this.dropdownMutationObserver = DOM.createMutationObserver(mutations => {
let isHidden = false;
for (let mutation of mutations) {
if (window.getComputedStyle(mutation.target).getPropertyValue('display') === 'none') {
isHidden = true;
}
}
if (isHidden) {
this.dropdownMutationObserver.takeRecords();
this.handleBlur();
}
});
}
// this.element.addEventListener('change', this.handleBlur);
this.dropdownMutationObserver.observe(this.element.parentElement.querySelector('.dropdown-content'), {
attributes: true,
attributeFilter: ['style']
});
} else {
if (this.input) {
this.input.off('blur', this.handleBlur);
this.input = null;
if (this.dropdownMutationObserver) {
this.dropdownMutationObserver.disconnect();
this.dropdownMutationObserver.takeRecords();
}
// this.element.removeEventListener('change', this.handleBlur);
}
}
createMaterialSelect(destroy) {
this.attachBlur(false);
if (destroy) {
$(this.element).material_select('destroy');
}
$(this.element).material_select();
this.toggleControl(this.disabled);
this.attachBlur(true);
//
// Firefox sometimes fire blur several times in a row
// observable at http://localhost:3000/#/samples/select/
// when enable 'Disable Functionality', open that list and
// then open 'Basic use' list.
// Chrome - ok
// IE ?
//
_taskqueueRunning = false;
handleBlur() {
if (this._taskqueueRunning) return;
this._taskqueueRunning = true;
this.taskQueue.queueTask(() => {
this.log.debug('fire blur event');
fireEvent(this.element, 'blur');
this._taskqueueRunning = false;
});
}
}

0 comments on commit 6fae969

Please sign in to comment.