Skip to content

Commit 6223574

Browse files
committed
feature(switch): add disabled input and test
1 parent 08f0ca4 commit 6223574

File tree

5 files changed

+79
-26
lines changed

5 files changed

+79
-26
lines changed

ember-cli-build.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ var broccoliAutoprefixer = require('broccoli-autoprefixer');
99
var autoprefixerOptions = require('./build/autoprefixer-options');
1010

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

src/components/switch/switch.spec.ts

+22-9
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ import {MdSwitch} from './switch';
1616
import {AsyncTestFn} from "angular2/testing";
1717
import {FORM_DIRECTIVES} from "angular2/common";
1818
import {Input} from "angular2/core";
19-
19+
import {By} from 'angular2/platform/browser';
2020

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

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

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

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

@@ -39,21 +39,34 @@ describe('MdSwitch', () => {
3939
done();
4040
});
4141
});
42+
43+
it('should not change the model if disabled', (done:() => void) => {
44+
return builder.createAsync(TestApp).then((fixture) => {
45+
let testComponent = fixture.debugElement.componentInstance;
46+
let switchElement = fixture.debugElement.query(By.css('md-switch'));
47+
48+
expect(switchElement.nativeElement.classList.contains('md-checked')).toBe(false);
49+
50+
testComponent.isDisabled = true;
51+
fixture.detectChanges();
52+
53+
switchElement.nativeElement.click();
54+
55+
expect(switchElement.nativeElement.classList.contains('md-checked')).toBe(false);
56+
done();
57+
});
58+
});
4259
});
4360
});
4461

45-
/** Gets a child DebugElement by tag name. */
46-
function getChildDebugElement(parent: DebugElement, tagName: string): DebugElement {
47-
return parent.query(debugEl => debugEl.nativeElement.tagName.toLowerCase() == tagName);
48-
}
49-
5062
/** Test component that contains an MdSwitch. */
5163
@Component({
5264
selector: 'test-app',
5365
directives: [MdSwitch, FORM_DIRECTIVES],
5466
template:
55-
'<md-switch [(ngModel)]="testSwitch">Test Switch</md-switch>',
67+
'<md-switch [(ngModel)]="testSwitch" [disabled]="isDisabled">Test Switch</md-switch>',
5668
})
5769
class TestApp {
5870
testSwitch = false;
71+
isDisabled = false;
5972
}

src/components/switch/switch.ts

+49-16
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ import {MdDrag} from '../../core/services/drag/drag';
33
import {ControlValueAccessor} from "angular2/common";
44
import {NgControl} from "angular2/common";
55
import {Optional} from "angular2/core";
6+
import {Renderer} from "angular2/core";
67

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

30-
// Model Values
31-
value: boolean;
33+
// storage values
34+
checked_: any;
35+
disabled_: boolean;
3236

33-
constructor(private _elementRef: ElementRef, @Optional() ngControl: NgControl) {
37+
constructor(private _elementRef: ElementRef, private _renderer: Renderer, @Optional() ngControl: NgControl) {
38+
this.componentElement = _elementRef.nativeElement;
3439
this.elementRef = _elementRef;
3540

3641
if (ngControl) {
@@ -39,7 +44,6 @@ export class MdSwitch implements ControlValueAccessor {
3944
}
4045

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

@@ -48,10 +52,13 @@ export class MdSwitch implements ControlValueAccessor {
4852
this.switchContainer.addEventListener('$md.dragstart', (ev: CustomEvent) => this.onDragStart(ev));
4953
this.switchContainer.addEventListener('$md.drag', (ev: CustomEvent) => this.onDrag(ev));
5054
this.switchContainer.addEventListener('$md.dragend', (ev: CustomEvent) => this.onDragEnd(ev));
55+
5156
}
5257

5358

5459
onDragStart(event: CustomEvent) {
60+
if (this.disabled) return;
61+
5562
this.componentElement.classList.add('md-dragging');
5663

5764
this.dragData = {
@@ -62,23 +69,27 @@ export class MdSwitch implements ControlValueAccessor {
6269
}
6370

6471
onDrag(event: CustomEvent) {
72+
if (this.disabled) return;
73+
6574
let percent = event.detail.pointer.distanceX / this.dragData.width;
6675

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

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

7483
onDragEnd(event: CustomEvent) {
84+
if (this.disabled) return;
85+
7586
this.componentElement.classList.remove('md-dragging');
7687
this.thumbContainer.style.transform = null;
7788

7889

79-
var isChanged = this.value ? this.dragData.translate < 0.5 : this.dragData.translate > 0.5;
90+
var isChanged = this.checked ? this.dragData.translate < 0.5 : this.dragData.translate > 0.5;
8091
if (isChanged || !this.dragData.translate) {
81-
this.changeValue(!this.value);
92+
this.checked = !this.checked;
8293
}
8394

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

91102
onClick() {
92-
if (!this.dragClick) this.changeValue(!this.value);
103+
if (!this.dragClick && !this.disabled) {
104+
this.checked = !this.checked;
105+
}
93106
}
94107

95-
changeValue(newValue: boolean) {
96-
this.onChange(newValue);
97-
this.writeValue(newValue);
98-
}
99108

100109
writeValue(value: any): void {
101-
this.value = !!value;
102-
103-
// Apply Checked Class
104-
this.componentElement.classList.toggle('md-checked', this.value);
110+
this.checked = value;
105111
}
106112

107113
registerOnChange(fn: any): void {
@@ -111,4 +117,31 @@ export class MdSwitch implements ControlValueAccessor {
111117
registerOnTouched(fn: any): void {
112118
this.onTouched = fn;
113119
}
120+
121+
get disabled(): string|boolean {
122+
return this.disabled_;
123+
}
124+
125+
set disabled(value: string|boolean) {
126+
if (typeof value == 'string') {
127+
this.disabled_ = (value === 'true' || value === '');
128+
} else {
129+
this.disabled_ = <boolean> value;
130+
}
131+
132+
this._renderer.setElementAttribute(this._elementRef, 'disabled', this.disabled_ ? 'true' : undefined);
133+
}
134+
135+
get checked() {
136+
return !!this.checked_;
137+
}
138+
139+
set checked(value) {
140+
this.checked_ = !!value;
141+
this.onChange(this.checked_);
142+
143+
this._renderer.setElementAttribute(this._elementRef, 'aria-checked', this.checked_);
144+
this.componentElement.classList.toggle('md-checked', this.checked);
145+
}
146+
114147
}

src/demo-app/demo-app.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {FORM_DIRECTIVES} from "angular2/common";
88
selector: 'demo-app',
99
providers: [],
1010
templateUrl: 'demo-app/demo-app.html',
11+
styleUrls: ['demo-app/demo-app.css'],
1112
directives: [MdButton, MdSwitch, FORM_DIRECTIVES],
1213
pipes: []
1314
})

src/index.html

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
<base href=".">
77
<script src="vendor/angular2/bundles/angular2-polyfills.js"></script>
88
{{content-for 'head'}}
9+
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">
10+
<style>
11+
html {
12+
font-family: 'Roboto', Arial, sans-serif;
13+
}
14+
</style>
915
<link rel="icon" type="image/x-icon" href="favicon.ico">
1016
</head>
1117
<body>

0 commit comments

Comments
 (0)