Skip to content

Commit c8a6404

Browse files
authored
fix(forms): add (touch) event and [disabled] property for controls (#836)
fixes #804
1 parent ff99984 commit c8a6404

8 files changed

+124
-99
lines changed

Diff for: nativescript-angular/tslint.json

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"component-selector": [true, "element", "", "camelCase"],
88
"use-input-property-decorator": true,
99
"use-output-property-decorator": true,
10-
"use-host-property-decorator": true,
1110
"no-input-rename": true,
1211
"no-output-rename": true,
1312
"use-pipe-transform-interface": true,
+12-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { ControlValueAccessor } from "@angular/forms";
2+
import { View } from "tns-core-modules/ui/core/view";
23

3-
export class BaseValueAccessor<TView> implements ControlValueAccessor {
4-
constructor(public view: TView) { }
5-
6-
onChange = (_) => { };
4+
export class BaseValueAccessor<TView extends View> implements ControlValueAccessor {
75
private pendingChangeNotification: number = 0;
6+
onChange = (_) => { };
7+
onTouched = () => {};
8+
9+
constructor(public view: TView) { }
810

911
registerOnChange(fn: (_: any) => void): void {
1012
this.onChange = (arg) => {
@@ -18,11 +20,13 @@ export class BaseValueAccessor<TView> implements ControlValueAccessor {
1820
};
1921
}
2022

21-
writeValue(_: any) {
22-
//
23+
registerOnTouched(fn: () => void): void {
24+
this.onTouched = fn;
2325
}
2426

25-
registerOnTouched(_: () => void): void {
26-
//
27+
setDisabledState(isDisabled: boolean): void {
28+
this.view.isEnabled = !isDisabled;
2729
}
30+
31+
writeValue(_: any) { }
2832
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
1+
import { Directive, ElementRef, forwardRef } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
33
import { BaseValueAccessor } from "./base-value-accessor";
44
import { Switch } from "tns-core-modules/ui/switch";
55

6-
const CHECKED_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
7-
useExisting: forwardRef(() => CheckedValueAccessor), multi: true};
6+
const CHECKED_VALUE_ACCESSOR = {
7+
provide: NG_VALUE_ACCESSOR,
8+
useExisting: forwardRef(() => CheckedValueAccessor),
9+
multi: true,
10+
};
811

912
/**
1013
* The accessor for setting a checked property and listening to changes that is used by the
@@ -16,25 +19,21 @@ const CHECKED_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
1619
* ```
1720
*/
1821
@Directive({
19-
// tslint:disable-next-line:max-line-length directive-selector
20-
selector: "Switch[ngModel], Switch[formControlName], switch[ngModel], switch[formControlName], switch[ngModel], switch[formControlName]",
21-
providers: [CHECKED_VALUE_ACCESSOR]
22+
selector:
23+
"Switch[ngModel],Switch[formControlName]," +
24+
"switch[ngModel],switch[formControlName]",
25+
providers: [CHECKED_VALUE_ACCESSOR],
26+
host: {
27+
"(touch)": "onTouched()",
28+
"(checkedChange)": "onChange($event.value)",
29+
},
2230
})
2331
export class CheckedValueAccessor extends BaseValueAccessor<Switch> { // tslint:disable-line:directive-class-suffix
24-
@HostListener("checkedChange", ["$event"])
25-
checkedChangeListener(event: any) {
26-
this.onChange(event.value);
27-
}
28-
29-
onTouched = () => { };
30-
3132
constructor(elementRef: ElementRef) {
3233
super(elementRef.nativeElement);
3334
}
3435

3536
writeValue(value: any): void {
3637
this.view.checked = value;
3738
}
38-
39-
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
4039
}
+15-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
1+
import { Directive, ElementRef, forwardRef } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
33
import { BaseValueAccessor } from "./base-value-accessor";
44
import { DatePicker } from "tns-core-modules/ui/date-picker";
55

6-
const DATE_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
7-
useExisting: forwardRef(() => DateValueAccessor), multi: true};
6+
const DATE_VALUE_ACCESSOR = {
7+
provide: NG_VALUE_ACCESSOR,
8+
useExisting: forwardRef(() => DateValueAccessor),
9+
multi: true,
10+
};
811

912
/**
1013
* The accessor for setting a date and listening to changes that is used by the
@@ -16,25 +19,22 @@ const DATE_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
1619
* ```
1720
*/
1821
@Directive({
19-
// tslint:disable-next-line:max-line-length directive-selector
20-
selector: "DatePicker[ngModel], DatePicker[formControlName], datePicker[ngModel], datePicker[formControlName], date-picker[ngModel], date-picker[formControlName]",
21-
providers: [DATE_VALUE_ACCESSOR]
22+
selector: "DatePicker[ngModel],DatePicker[formControlName]," +
23+
"datepicker[ngModel],datepicker[formControlName]," +
24+
"datePicker[ngModel],datePicker[formControlName]," +
25+
"date-picker[ngModel],date-picker[formControlName]",
26+
providers: [DATE_VALUE_ACCESSOR],
27+
host: {
28+
"(touch)": "onTouched()",
29+
"(dateChange)": "onChange($event.value)",
30+
},
2231
})
2332
export class DateValueAccessor extends BaseValueAccessor<DatePicker> { // tslint:disable-line:directive-class-suffix
24-
@HostListener("dateChange", ["$event"])
25-
dateChangeListener(event: any) {
26-
this.onChange(event.value);
27-
}
28-
29-
onTouched = () => { };
30-
3133
constructor(elementRef: ElementRef) {
3234
super(elementRef.nativeElement);
3335
}
3436

3537
writeValue(value: any): void {
3638
this.view.date = value;
3739
}
38-
39-
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
4040
}
+14-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
1+
import { Directive, ElementRef, forwardRef } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
33
import { BaseValueAccessor } from "./base-value-accessor";
44
import { Slider } from "tns-core-modules/ui/slider";
55

6-
const NUMBER_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
7-
useExisting: forwardRef(() => NumberValueAccessor), multi: true};
6+
const NUMBER_VALUE_ACCESSOR = {
7+
provide: NG_VALUE_ACCESSOR,
8+
useExisting: forwardRef(() => NumberValueAccessor),
9+
multi: true,
10+
};
811

912
/**
1013
* The accessor for setting a value and listening to changes that is used by the
@@ -16,25 +19,21 @@ const NUMBER_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
1619
* ```
1720
*/
1821
@Directive({
19-
// tslint:disable-next-line:max-line-length directive-selector
20-
selector: "Slider[ngModel], Slider[formControlName], slider[ngModel], slider[formControlName], slider[ngModel], slider[formControlName]",
21-
providers: [NUMBER_VALUE_ACCESSOR]
22+
selector:
23+
"Slider[ngModel],Slider[formControlName]," +
24+
"slider[ngModel],slider[formControlName]",
25+
providers: [NUMBER_VALUE_ACCESSOR],
26+
host: {
27+
"(touch)": "onTouched()",
28+
"(valueChange)": "onChange($event.value)",
29+
},
2230
})
2331
export class NumberValueAccessor extends BaseValueAccessor<Slider> { // tslint:disable-line:directive-class-suffix
24-
@HostListener("valueChange", ["$event"])
25-
valueChangeListener(event: any) {
26-
this.onChange(event.value);
27-
}
28-
29-
onTouched = () => { };
30-
3132
constructor(elementRef: ElementRef) {
3233
super(elementRef.nativeElement);
3334
}
3435

3536
writeValue(value: any): void {
3637
this.view.value = value;
3738
}
38-
39-
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
4039
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { Directive, ElementRef, forwardRef, AfterViewInit, HostListener } from "@angular/core";
1+
import { Directive, ElementRef, forwardRef, AfterViewInit } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
33
import { BaseValueAccessor } from "./base-value-accessor";
44
import { View } from "tns-core-modules/ui/core/view";
55

6-
const SELECTED_INDEX_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
7-
useExisting: forwardRef(() => SelectedIndexValueAccessor), multi: true};
6+
const SELECTED_INDEX_VALUE_ACCESSOR = {
7+
provide: NG_VALUE_ACCESSOR,
8+
useExisting: forwardRef(() => SelectedIndexValueAccessor),
9+
multi: true,
10+
};
811

912
export type SelectableView = {selectedIndex: number} & View;
1013

@@ -18,18 +21,28 @@ export type SelectableView = {selectedIndex: number} & View;
1821
* ```
1922
*/
2023
@Directive({
21-
// tslint:disable-next-line:max-line-length directive-selector
22-
selector: "SegmentedBar[ngModel], SegmentedBar[formControlName], segmentedBar[ngModel], segmentedBar[formControlName], segmented-bar[ngModel], segmented-bar[formControlName], ListPicker[ngModel], ListPicker[formControlName], listPicker[ngModel], listPicker[formControlName], list-picker[ngModel], list-picker[formControlName], TabView[ngModel], TabView[formControlName], tabView[ngModel], tabView[formControlName], tab-view[ngModel], tab-view[formControlName]",
23-
providers: [SELECTED_INDEX_VALUE_ACCESSOR]
24-
})
25-
export class SelectedIndexValueAccessor extends BaseValueAccessor<SelectableView> implements AfterViewInit { // tslint:disable-line:max-line-length directive-class-suffix
26-
@HostListener("selectedIndexChange", ["$event"])
27-
selectedIndexChangeListener(event: any) {
28-
this.onChange(event.value);
29-
}
24+
selector:
25+
"SegmentedBar[ngModel],SegmentedBar[formControlName]," +
26+
"segmentedBar[ngModel],segmentedBar[formControlName]," +
27+
"segmentedbar[ngModel],segmentedbar[formControlName]," +
28+
"segmented-bar[ngModel],segmented-bar[formControlName]," +
3029

31-
onTouched = () => { };
30+
"ListPicker[ngModel],ListPicker[formControlName]," +
31+
"listPicker[ngModel],listPicker[formControlName]," +
32+
"listpicker[ngModel],listpicker[formControlName]," +
33+
"list-picker[ngModel],list-picker[formControlName]," +
3234

35+
"TabView[ngModel],TabView[formControlName]," +
36+
"tabView[ngModel],tabView[formControlName]," +
37+
"tabview[ngModel],tabview[formControlName]," +
38+
"tab-view[ngModel],tab-view[formControlName]",
39+
providers: [SELECTED_INDEX_VALUE_ACCESSOR],
40+
host: {
41+
"(touch)": "onTouched()",
42+
"(selectedIndexChange)": "onChange($event.value)",
43+
},
44+
})
45+
export class SelectedIndexValueAccessor extends BaseValueAccessor<SelectableView> implements AfterViewInit { // tslint:disable-line:max-line-length directive-class-suffix
3346
constructor(elementRef: ElementRef) {
3447
super(elementRef.nativeElement);
3548
}
@@ -39,6 +52,7 @@ export class SelectedIndexValueAccessor extends BaseValueAccessor<SelectableView
3952

4053
writeValue(value: any): void {
4154
this.value = value;
55+
4256
if (this.viewInitialized) {
4357
this.view.selectedIndex = this.value;
4458
}
@@ -48,6 +62,4 @@ export class SelectedIndexValueAccessor extends BaseValueAccessor<SelectableView
4862
this.viewInitialized = true;
4963
this.view.selectedIndex = this.value;
5064
}
51-
52-
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
5365
}
+26-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
1+
import { Directive, ElementRef, forwardRef } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
33
import { BaseValueAccessor } from "./base-value-accessor";
44
import { View } from "tns-core-modules/ui/core/view";
55

6-
const TEXT_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
7-
useExisting: forwardRef(() => TextValueAccessor), multi: true};
6+
const TEXT_VALUE_ACCESSOR = {
7+
provide: NG_VALUE_ACCESSOR,
8+
useExisting: forwardRef(() => TextValueAccessor),
9+
multi: true,
10+
};
811

912
export type TextView = {text: string} & View;
1013

@@ -18,25 +21,33 @@ export type TextView = {text: string} & View;
1821
* ```
1922
*/
2023
@Directive({
21-
// tslint:disable-next-line:max-line-length directive-selector
22-
selector: "TextField[ngModel], TextField[formControlName], textField[ngModel], textField[formControlName], text-field[ngModel], text-field[formControlName], TextView[ngModel], TextView[formControlName], textView[ngModel], textView[formControlName], text-view[ngModel], text-view[formControlName], SearchBar[ngModel], SearchBar[formControlName], searchBar[ngModel], searchBar[formControlName], search-bar[ngModel], search-bar[formControlName]",
23-
providers: [TEXT_VALUE_ACCESSOR]
24-
})
25-
export class TextValueAccessor extends BaseValueAccessor<TextView> { // tslint:disable-line:directive-class-suffix
26-
@HostListener("textChange", ["$event"])
27-
textChangeListener(event: any) {
28-
this.onChange(event.value);
29-
}
24+
selector:
25+
"TextField[ngModel],TextField[formControlName]," +
26+
"textField[ngModel],textField[formControlName]," +
27+
"textfield[ngModel],textfield[formControlName]," +
28+
"text-field[ngModel],text-field[formControlName]," +
3029

31-
onTouched = () => { };
30+
"TextView[ngModel],TextView[formControlName]," +
31+
"textView[ngModel],textView[formControlName]," +
32+
"textview[ngModel],textview[formControlName]," +
33+
"text-view[ngModel],text-view[formControlName]," +
3234

35+
"SearchBar[ngModel],SearchBar[formControlName]," +
36+
"searchBar[ngModel],searchBar[formControlName]," +
37+
"searchbar[ngModel],searchbar[formControlName]," +
38+
"search-bar[ngModel], search-bar[formControlName]",
39+
providers: [TEXT_VALUE_ACCESSOR],
40+
host: {
41+
"(touch)": "onTouched()",
42+
"(textChange)": "onChange($event.value)",
43+
},
44+
})
45+
export class TextValueAccessor extends BaseValueAccessor<TextView> { // tslint:disable-line:directive-class-suffix
3346
constructor(elementRef: ElementRef) {
3447
super(elementRef.nativeElement);
3548
}
3649

3750
writeValue(value: any): void {
3851
this.view.text = value;
3952
}
40-
41-
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
4253
}
+16-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { Directive, ElementRef, forwardRef, HostListener } from "@angular/core";
1+
import { Directive, ElementRef, forwardRef } from "@angular/core";
22
import { NG_VALUE_ACCESSOR } from "@angular/forms";
33
import { BaseValueAccessor } from "./base-value-accessor";
44
import { TimePicker } from "tns-core-modules/ui/time-picker";
55

6-
const TIME_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
7-
useExisting: forwardRef(() => TimeValueAccessor), multi: true};
6+
const TIME_VALUE_ACCESSOR = {
7+
provide: NG_VALUE_ACCESSOR,
8+
useExisting: forwardRef(() => TimeValueAccessor),
9+
multi: true,
10+
};
811

912
/**
1013
* The accessor for setting a time and listening to changes that is used by the
@@ -16,25 +19,23 @@ const TIME_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
1619
* ```
1720
*/
1821
@Directive({
19-
// tslint:disable-next-line:max-line-length directive-selector
20-
selector: "TimePicker[ngModel], TimePicker[formControlName], timePicker[ngModel], timePicker[formControlName], time-picker[ngModel], time-picker[formControlName]",
21-
providers: [TIME_VALUE_ACCESSOR]
22+
selector:
23+
"TimePicker[ngModel],TimePicker[formControlName]," +
24+
"timepicker[ngModel],timepicker[formControlName]," +
25+
"timePicker[ngModel],timePicker[formControlName]," +
26+
"time-picker[ngModel], time-picker[formControlName]",
27+
providers: [TIME_VALUE_ACCESSOR],
28+
host: {
29+
"(touch)": "onTouch()",
30+
"(timeChange)": "onChange($event.value)",
31+
},
2232
})
2333
export class TimeValueAccessor extends BaseValueAccessor<TimePicker> { // tslint:disable-line:directive-class-suffix
24-
@HostListener("timeChange", ["$event"])
25-
timeChangeListener(event: any) {
26-
this.onChange(event.value);
27-
}
28-
29-
onTouched = () => { };
30-
3134
constructor(elementRef: ElementRef) {
3235
super(elementRef.nativeElement);
3336
}
3437

3538
writeValue(value: any): void {
3639
this.view.time = value;
3740
}
38-
39-
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
4041
}

0 commit comments

Comments
 (0)