diff --git a/src/app/components/components/directives/directives.component.html b/src/app/components/components/directives/directives.component.html index a8ef6105a5..9c8c0a00cc 100644 --- a/src/app/components/components/directives/directives.component.html +++ b/src/app/components/components/directives/directives.component.html @@ -41,7 +41,11 @@

Click on this to open a div:

- Reveal or hide with a toggle click! + + Toggle Card + Reveal or hide with a toggle click! + +

HTML:

@@ -61,4 +65,64 @@ {{ '}' }} - \ No newline at end of file + + + + Fade directive + + +

Use [tdFade]="variable" on an element to fade it in and out.

+

Click on this to open a div:

+ +
+ + Fade Card + Fade in or out with a click! + + +
+

HTML:

+ + Toggle +
+ This one fades in and out! +
+ ]]> +
+

TypeScript:

+ + fadeDiv: boolean = true; + + fade(): any {{ '{' }} + this.fadeDiv = !this.fadeDiv; + {{ '}' }} + +
+
+ + + Min/Max/Number Validators + + +

We've added min/max/number-required validations since ng2 doesnt support them at the moment.

+

Supported:

+ +

Example enter lower than 5 or higher than 10:

+
+ +
+

Errors:

+ {{el?.errors | json}} +

HTML:

+ + + ]]> + +
+
diff --git a/src/app/components/components/directives/directives.component.ts b/src/app/components/components/directives/directives.component.ts index a4dc911bc1..ebf9a44233 100644 --- a/src/app/components/components/directives/directives.component.ts +++ b/src/app/components/components/directives/directives.component.ts @@ -8,8 +8,12 @@ import { Component } from '@angular/core'; export class DirectivesComponent { toggleDiv: boolean = true; + fadeDiv: boolean = true; toggle(): void { this.toggleDiv = !this.toggleDiv; } + fade(): void { + this.fadeDiv = !this.fadeDiv; + } } diff --git a/src/platform/core/index.ts b/src/platform/core/index.ts index 75c3e96e44..3c1e874686 100644 --- a/src/platform/core/index.ts +++ b/src/platform/core/index.ts @@ -129,6 +129,23 @@ export { TdToggleDirective } from './directives/toggle/toggle.directive'; export { TdFadeDirective } from './directives/fade/fade.directive'; export { TdAutoTrimDirective } from './directives/auto-trim/auto-trim.directive'; +/** + * VALIDATORS + */ +import { TdMinValidator } from './validators/min.validator'; +import { TdMaxValidator } from './validators/max.validator'; +import { TdNumberRequiredValidator } from './validators/number-required.validator'; + +export const TD_VALIDATORS: Type[] = [ + TdMinValidator, + TdMaxValidator, + TdNumberRequiredValidator, +]; + +export { TdMinValidator } from './validators/min.validator'; +export { TdMaxValidator } from './validators/max.validator'; +export { TdNumberRequiredValidator } from './validators/number-required.validator'; + /** * PIPES */ @@ -182,6 +199,7 @@ export { TdMediaToggleDirective } from './media/directives/media-toggle.directiv TD_EXPANSION_DIRECTIVES, TD_DIALOG_DIRECTIVES, TD_PLATFORM_DIRECTIVES, + TD_VALIDATORS, ], exports: [ HttpModule, @@ -199,6 +217,7 @@ export { TdMediaToggleDirective } from './media/directives/media-toggle.directiv TD_EXPANSION_DIRECTIVES, TD_DIALOG_DIRECTIVES, TD_PLATFORM_DIRECTIVES, + TD_VALIDATORS, ], entryComponents: [ TD_DIALOG_ENTRY_COMPONENTS ], }) diff --git a/src/platform/core/validators/max.validator.ts b/src/platform/core/validators/max.validator.ts new file mode 100644 index 0000000000..8cb29cb4fd --- /dev/null +++ b/src/platform/core/validators/max.validator.ts @@ -0,0 +1,40 @@ +import { Directive, Input, forwardRef } from '@angular/core'; +import { NG_VALIDATORS, Validator, Validators, AbstractControl, ValidatorFn } from '@angular/forms'; + +import { TdNumberRequiredValidator } from './number-required.validator'; + +export const MAX_VALIDATOR: any = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => TdMaxValidator), + multi: true, +}; + +@Directive({ + selector: '[max][formControlName],[max][formControl],[max][ngModel]', + providers: [ MAX_VALIDATOR ], +}) +export class TdMaxValidator implements Validator { + + private _validator: ValidatorFn; + + @Input('max') + set max(max: number) { + this._validator = TdMaxValidator.validate(max); + } + + static validate(maxValue: any): ValidatorFn { + return (c: AbstractControl): {[key: string]: any} => { + if (!!Validators.required(c) || !!TdNumberRequiredValidator.validate(c) || (!maxValue && maxValue !== 0)) { + return undefined; + } + let v: number = c.value; + return v > maxValue ? + { max: {maxValue: maxValue, actualValue: v} } : + undefined; + }; + }; + + validate(c: AbstractControl): {[key: string]: any} { + return this._validator(c); + }; +} diff --git a/src/platform/core/validators/min.validator.ts b/src/platform/core/validators/min.validator.ts new file mode 100644 index 0000000000..c4875f036d --- /dev/null +++ b/src/platform/core/validators/min.validator.ts @@ -0,0 +1,40 @@ +import { Directive, Input, forwardRef } from '@angular/core'; +import { NG_VALIDATORS, Validator, Validators, AbstractControl, ValidatorFn } from '@angular/forms'; + +import { TdNumberRequiredValidator } from './number-required.validator'; + +export const MIN_VALIDATOR: any = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => TdMinValidator), + multi: true, +}; + +@Directive({ + selector: '[min][formControlName],[min][formControl],[min][ngModel]', + providers: [ MIN_VALIDATOR ], +}) +export class TdMinValidator implements Validator { + + private _validator: ValidatorFn; + + @Input('min') + set min(min: number) { + this._validator = TdMinValidator.validate(min); + } + + static validate(minValue: any): ValidatorFn { + return (c: AbstractControl): {[key: string]: any} => { + if (!!Validators.required(c) || !!TdNumberRequiredValidator.validate(c) || (!minValue && minValue !== 0)) { + return undefined; + } + let v: number = c.value; + return v < minValue ? + { min: {minValue: minValue, actualValue: v} } : + undefined; + }; + }; + + validate(c: AbstractControl): {[key: string]: any} { + return this._validator(c); + }; +} diff --git a/src/platform/core/validators/number-required.validator.ts b/src/platform/core/validators/number-required.validator.ts new file mode 100644 index 0000000000..aaef85aeaf --- /dev/null +++ b/src/platform/core/validators/number-required.validator.ts @@ -0,0 +1,27 @@ +import { Directive, forwardRef } from '@angular/core'; +import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms'; + +export const NUMBER_INPUT_REQUIRED_VALIDATOR: any = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => TdNumberRequiredValidator), + multi: true, +}; + +@Directive({ + selector: `[type=number][required][formControlName], + [type=number][required][formControl], + [type=number][required][ngModel]`, + providers: [ NUMBER_INPUT_REQUIRED_VALIDATOR ], +}) +export class TdNumberRequiredValidator implements Validator { + + static validate(c: AbstractControl): {[key: string]: any} { + return (Number.isNaN(c.value)) ? + { required: true } : + undefined; + } + + validate(c: AbstractControl): {[key: string]: any} { + return TdNumberRequiredValidator.validate(c); + } +} diff --git a/tslint.json b/tslint.json index 054bc73fd7..0771e4128f 100644 --- a/tslint.json +++ b/tslint.json @@ -202,7 +202,7 @@ "element" ], "directive-selector-prefix": [ - true, + false, "td" ], "component-selector-prefix": [ // This will be checked in PR's since we only want `td-` prefix for platform components, not docs not product components.