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 6223574
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 26 deletions.
2 changes: 1 addition & 1 deletion ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var broccoliAutoprefixer = require('broccoli-autoprefixer');
var autoprefixerOptions = require('./build/autoprefixer-options');

module.exports = function(defaults) {
var demoAppCssTree = new BroccoliSass(['src/demo-app'], './demo-app.scss', 'demo-app.css');
var demoAppCssTree = new BroccoliSass(['src/demo-app'], './demo-app.scss', 'demo-app/demo-app.css');
var componentCssTree = getComponentsCssTree();
var angularAppTree = new Angular2App(defaults);

Expand Down
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);
}

}
1 change: 1 addition & 0 deletions src/demo-app/demo-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {FORM_DIRECTIVES} from "angular2/common";
selector: 'demo-app',
providers: [],
templateUrl: 'demo-app/demo-app.html',
styleUrls: ['demo-app/demo-app.css'],
directives: [MdButton, MdSwitch, FORM_DIRECTIVES],
pipes: []
})
Expand Down
6 changes: 6 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
<base href=".">
<script src="vendor/angular2/bundles/angular2-polyfills.js"></script>
{{content-for 'head'}}
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">
<style>
html {
font-family: 'Roboto', Arial, sans-serif;
}
</style>
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
Expand Down

0 comments on commit 6223574

Please sign in to comment.