Skip to content

Commit

Permalink
feature(switch): add disabled input and test
Browse files Browse the repository at this point in the history
  • Loading branch information
devversion committed Jan 10, 2016
1 parent 08f0ca4 commit 73f1361
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 26 deletions.
31 changes: 22 additions & 9 deletions src/components/switch/switch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ import {MdSwitch} from './switch';
import {AsyncTestFn} from "angular2/testing";
import {FORM_DIRECTIVES} from "angular2/common";
import {Input} from "angular2/core";

import {By} from 'angular2/platform/browser';

describe('MdSwitch', () => {
let builder: TestComponentBuilder;

beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { builder = tcb; }));

describe('md-switch', () => {
it('should change the model value', (done: () => void) => {
it('should change the model value', (done:() => void) => {
return builder.createAsync(TestApp).then((fixture) => {
let testComponent = fixture.debugElement.componentInstance;
let switchElement = getChildDebugElement(fixture.debugElement, 'md-switch');
let switchElement = fixture.debugElement.query(By.css('md-switch'));

expect(switchElement.nativeElement.classList.contains('md-checked')).toBe(false);

Expand All @@ -39,21 +39,34 @@ describe('MdSwitch', () => {
done();
});
});

it('should not change the model if disabled', (done:() => void) => {
return builder.createAsync(TestApp).then((fixture) => {
let testComponent = fixture.debugElement.componentInstance;
let switchElement = fixture.debugElement.query(By.css('md-switch'));

expect(switchElement.nativeElement.classList.contains('md-checked')).toBe(false);

testComponent.isDisabled = true;
fixture.detectChanges();

switchElement.nativeElement.click();

expect(switchElement.nativeElement.classList.contains('md-checked')).toBe(false);
done();
});
});
});
});

/** Gets a child DebugElement by tag name. */
function getChildDebugElement(parent: DebugElement, tagName: string): DebugElement {
return parent.query(debugEl => debugEl.nativeElement.tagName.toLowerCase() == tagName);
}

/** Test component that contains an MdSwitch. */
@Component({
selector: 'test-app',
directives: [MdSwitch, FORM_DIRECTIVES],
template:
'<md-switch [(ngModel)]="testSwitch">Test Switch</md-switch>',
'<md-switch [(ngModel)]="testSwitch" [disabled]="isDisabled">Test Switch</md-switch>',
})
class TestApp {
testSwitch = false;
isDisabled = false;
}
65 changes: 49 additions & 16 deletions src/components/switch/switch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import {MdDrag} from '../../core/services/drag/drag';
import {ControlValueAccessor} from "angular2/common";
import {NgControl} from "angular2/common";
import {Optional} from "angular2/core";
import {Renderer} from "angular2/core";

@Component({
selector: 'md-switch',
inputs: ['disabled'],
host: {
'[attr.aria-disabled]': 'disabled',
'(click)': 'onClick()'
},
templateUrl: './components/switch/switch.html',
Expand All @@ -27,10 +30,12 @@ export class MdSwitch implements ControlValueAccessor {
onChange = (_:any) => {};
onTouched = () => {};

// Model Values
value: boolean;
// storage values
checked_: any;
disabled_: boolean;

constructor(private _elementRef: ElementRef, @Optional() ngControl: NgControl) {
constructor(private _elementRef: ElementRef, private _renderer: Renderer, @Optional() ngControl: NgControl) {
this.componentElement = _elementRef.nativeElement;
this.elementRef = _elementRef;

if (ngControl) {
Expand All @@ -39,7 +44,6 @@ export class MdSwitch implements ControlValueAccessor {
}

ngOnInit() {
this.componentElement = this.elementRef.nativeElement;
this.switchContainer = <HTMLElement> this.componentElement.querySelector('.md-container');
this.thumbContainer = <HTMLElement> this.componentElement.querySelector('.md-thumb-container');

Expand All @@ -48,10 +52,13 @@ export class MdSwitch implements ControlValueAccessor {
this.switchContainer.addEventListener('$md.dragstart', (ev: CustomEvent) => this.onDragStart(ev));
this.switchContainer.addEventListener('$md.drag', (ev: CustomEvent) => this.onDrag(ev));
this.switchContainer.addEventListener('$md.dragend', (ev: CustomEvent) => this.onDragEnd(ev));

}


onDragStart(event: CustomEvent) {
if (this.disabled) return;

this.componentElement.classList.add('md-dragging');

this.dragData = {
Expand All @@ -62,23 +69,27 @@ export class MdSwitch implements ControlValueAccessor {
}

onDrag(event: CustomEvent) {
if (this.disabled) return;

let percent = event.detail.pointer.distanceX / this.dragData.width;

let translate = this.value ? 1 + percent : percent;
let translate = this.checked ? 1 + percent : percent;
translate = Math.max(0, Math.min(1, translate));

this.thumbContainer.style.transform = 'translate3d(' + (100 * translate) + '%,0,0)';
this.dragData.translate = translate;
}

onDragEnd(event: CustomEvent) {
if (this.disabled) return;

this.componentElement.classList.remove('md-dragging');
this.thumbContainer.style.transform = null;


var isChanged = this.value ? this.dragData.translate < 0.5 : this.dragData.translate > 0.5;
var isChanged = this.checked ? this.dragData.translate < 0.5 : this.dragData.translate > 0.5;
if (isChanged || !this.dragData.translate) {
this.changeValue(!this.value);
this.checked = !this.checked;
}

this.dragData = null;
Expand All @@ -89,19 +100,14 @@ export class MdSwitch implements ControlValueAccessor {
}

onClick() {
if (!this.dragClick) this.changeValue(!this.value);
if (!this.dragClick && !this.disabled) {
this.checked = !this.checked;
}
}

changeValue(newValue: boolean) {
this.onChange(newValue);
this.writeValue(newValue);
}

writeValue(value: any): void {
this.value = !!value;

// Apply Checked Class
this.componentElement.classList.toggle('md-checked', this.value);
this.checked = value;
}

registerOnChange(fn: any): void {
Expand All @@ -111,4 +117,31 @@ export class MdSwitch implements ControlValueAccessor {
registerOnTouched(fn: any): void {
this.onTouched = fn;
}

get disabled(): string|boolean {
return this.disabled_;
}

set disabled(value: string|boolean) {
if (typeof value == 'string') {
this.disabled_ = (value === 'true' || value === '');
} else {
this.disabled_ = <boolean> value;
}

this._renderer.setElementAttribute(this._elementRef, 'disabled', this.disabled_ ? 'true' : undefined);
}

get checked() {
return !!this.checked_;
}

set checked(value) {
this.checked_ = !!value;
this.onChange(this.checked_);

this._renderer.setElementAttribute(this._elementRef, 'aria-checked', this.checked_);
this.componentElement.classList.toggle('md-checked', this.checked);
}

}
2 changes: 1 addition & 1 deletion src/demo-app/demo-app.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
<button md-raised-button class="md-primary">HELLO</button>
<button md-fab class="md-accent">HI</button>

<md-switch [(ngModel)]="switchValue"> Toggle Angular Version</md-switch>
<md-switch [(ngModel)]="switchValue" [disabled]="switchValue"> Toggle Angular Version</md-switch>
Value: {{ switchValue }}
</p>

0 comments on commit 73f1361

Please sign in to comment.