Revert "fix(slide-toggle): invalid model change event (#4140)" (#4218)

This reverts commit 317952a18d.
This commit is contained in:
Kara
2017-04-22 14:22:22 -07:00
committed by GitHub
parent 66e65c48f1
commit bfdef8e9bb
2 changed files with 35 additions and 34 deletions
+11 -14
View File
@@ -295,23 +295,18 @@ describe('MdSlideToggle', () => {
expect(slideToggleControl.pristine).toBe(true);
expect(slideToggleControl.touched).toBe(false);
// After changing the value from the view, the control should
// become dirty (not pristine), but remain untouched if focus is still there.
// After changing the value programmatically, the control should
// become dirty (not pristine), but remain untouched.
slideToggle.checked = true;
// Dispatch a change event on the input element to fake a user interaction that triggered
// the state change.
dispatchFakeEvent(inputElement, 'change');
fixture.detectChanges();
expect(slideToggleControl.valid).toBe(true);
expect(slideToggleControl.pristine).toBe(false);
expect(slideToggleControl.touched).toBe(false);
// Once the input element looses focus, the control should remain dirty but should
// also turn touched.
dispatchFakeEvent(inputElement, 'blur');
// After a user interaction occurs (such as a click), the control should remain dirty and
// now also be touched.
labelElement.click();
fixture.detectChanges();
expect(slideToggleControl.valid).toBe(true);
@@ -329,13 +324,13 @@ describe('MdSlideToggle', () => {
expect(slideToggleControl.touched).toBe(false);
expect(slideToggleElement.classList).toContain('mat-checked');
// Once the input element looses focus, the control should remain dirty but should
// also turn touched.
dispatchFakeEvent(inputElement, 'blur');
// After a user interaction occurs (such as a click), the control should remain dirty and
// now also be touched.
inputElement.click();
fixture.detectChanges();
expect(slideToggleControl.touched).toBe(true);
expect(slideToggleElement.classList).toContain('mat-checked');
expect(slideToggleElement.classList).not.toContain('mat-checked');
});
// TODO(kara): update when core/testing adds fix
@@ -439,6 +434,7 @@ describe('MdSlideToggle', () => {
}));
it('should prevent the form from submit when being required', () => {
if ('reportValidity' in inputElement === false) {
// If the browser does not report the validity then the tests will break.
// e.g Safari 8 on Mobile.
@@ -446,6 +442,7 @@ describe('MdSlideToggle', () => {
}
testComponent.isRequired = true;
fixture.detectChanges();
buttonElement.click();
+24 -20
View File
@@ -64,6 +64,7 @@ export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueA
// A unique id for the slide-toggle. By default the id is auto-generated.
private _uniqueId = `md-slide-toggle-${++nextId}`;
private _checked: boolean = false;
private _color: string;
private _slideRenderer: SlideToggleRenderer = null;
private _disabled: boolean = false;
@@ -85,9 +86,6 @@ export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueA
/** Whether the label should appear after or before the slide-toggle. Defaults to 'after' */
@Input() labelPosition: 'before' | 'after' = 'after';
/** Whether the slide-toggle element is checked or not */
@Input() checked: boolean = false;
/** Used to set the aria-label attribute on the underlying input element. */
@Input('aria-label') ariaLabel: string = null;
@@ -138,7 +136,9 @@ export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueA
}
/**
* This function will called if the underlying input changed its value through user interaction.
* The onChangeEvent method will be also called on click.
* This is because everything for the slide-toggle is wrapped inside of a label,
* which triggers a onChange event on click.
*/
_onChangeEvent(event: Event) {
// We always have to stop propagation on the change event.
@@ -146,22 +146,19 @@ export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueA
// emit its event object to the component's `change` output.
event.stopPropagation();
// Sync the value from the underlying input element with the slide-toggle component.
this.checked = this._inputElement.nativeElement.checked;
// Once a drag is currently in progress, we do not want to toggle the slide-toggle on a click.
if (!this.disabled && !this._slideRenderer.dragging) {
this.toggle();
// Emit our custom change event if the native input emitted one.
// It is important to only emit it, if the native input triggered one, because we don't want
// to trigger a change event, when the `checked` variable changes programmatically.
this._emitChangeEvent();
// Emit our custom change event if the native input emitted one.
// It is important to only emit it, if the native input triggered one, because
// we don't want to trigger a change event, when the `checked` variable changes for example.
this._emitChangeEvent();
}
}
_onInputClick(event: Event) {
// In some situations the user will release the mouse on the label element. The label element
// redirects the click to the underlying input element and will result in a value change.
// Prevent the default behavior if dragging, because the value will be set after drag.
if (this._slideRenderer.dragging) {
event.preventDefault();
}
this.onTouched();
// We have to stop propagation for click events on the visual hidden input element.
// By default, when a user clicks on a label element, a generated click event will be
@@ -198,6 +195,16 @@ export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueA
this._focusOriginMonitor.focusVia(this._inputElement.nativeElement, this._renderer, 'keyboard');
}
/** Whether the slide-toggle is checked. */
@Input()
get checked() { return !!this._checked; }
set checked(value) {
if (this.checked !== !!value) {
this._checked = value;
this.onChange(this._checked);
}
}
/** The color of the slide-toggle. Can be primary, accent, or warn. */
@Input()
get color(): string { return this._color; }
@@ -238,15 +245,12 @@ export class MdSlideToggle implements OnDestroy, AfterContentInit, ControlValueA
}
}
/**
* Emits a change event on the `change` output. Also notifies the FormControl about the change.
*/
/** Emits the change event to the `change` output EventEmitter */
private _emitChangeEvent() {
let event = new MdSlideToggleChange();
event.source = this;
event.checked = this.checked;
this.change.emit(event);
this.onChange(this.checked);
}