我正在尝试使用ngx-color-picker
和Angular Materials FormField
为颜色选择器制作包装器组件。我将其配置为required
,但无效时它的轮廓不会像其他表单字段一样变成红色...如何在自定义表单字段上实现此行为?
color-picker.component.ts
import { Component, Input, forwardRef } from '@angular/core'
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
// inspiration:
// https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
export const requiredValidator = (c: FormControl): ValidationErrors | null => {
return
c.value === '' ||
c.value === null ||
c.value === undefined ||
c.value.length === 0
? {
required: {
valid: false,
},
}
: null
}
@Component({
selector: 'nda-color-picker',
templateUrl: './color-picker.component.html',
styleUrls: ['./color-picker.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ColorPickerComponent),
multi: true,
},
],
})
export class ColorPickerComponent implements ControlValueAccessor, Validator {
@Input() label: string
_color: string
get color() {
return this._color
}
set color(value: string) {
this._color = value
this.propagateChange(this._color)
}
constructor() {}
writeValue(value: any) {
if (value !== undefined) {
this.color = value
}
}
propagateChange = (_: any) => {}
registerOnChange(fn) {
this.propagateChange = fn
}
registerOnTouched() {}
validate(control: AbstractControl): ValidationErrors | null {
return requiredValidator(control as FormControl)
}
}
color-picker.component.html
<mat-form-field appearance="outline" [floatLabel]="'always'">
<mat-label>{{ label }}</mat-label>
<input
matTooltip="{{ color }}"
cpOKButton="true"
cpCancelButton="true"
[required]="required"
matInput
[ngStyle]="{ color: color, background: color }"
[colorPicker]="color"
(colorPickerChange)="color = $event"
/>
</mat-form-field>
form-component.html
<form
[formGroup]="transportForm"
autocomplete="off"
(ngSubmit)="handleSubmit()"
>A
<div mat-dialog-content>
<div fxLayout="row wrap" fxLayoutGap="1rem">
<mat-form-field appearance="outline">
<mat-label>Icon</mat-label>
<input
matInput
placeholder="Icon"
formControlName="icon"
required
/>
</mat-form-field>
<nda-color-picker
label="Badge Color Code"
formControlName="badgeColorCode"
required
></nda-color-picker>
<nda-color-picker
label="Text Color Code"
formControlName="textColorCode"
required
></nda-color-picker>
<mat-form-field appearance="outline">
<mat-label>Badge Type</mat-label>
<input
matInput
placeholder="Badge Type"
formControlName="badgeType"
/>
</mat-form-field>
</div>
</div>
<!-- dialog actions -->
<div mat-dialog-actions fxLayout="row" fxLayoutAlign="space-between center">
<div>
<button
type="button"
*ngIf="data && data.code"
color="warn"
mat-flat-button
(click)="handleDelete()"
>
DELETE
</button>
</div>
<div class="btn-container">
<button type="reset" mat-stroked-button (click)="handleCancel()">
CANCEL
</button>
<button
mat-flat-button
color="accent"
[disabled]="transportForm.pristine"
>
SAVE
</button>
</div>
<div
*ngIf="!transportForm.valid"
class="mat-small dialog-error-message"
>
* Fill out all required fields
</div>
</div>
</form>
------更新------
我使用验证器函数和实现了Validator接口的类更新了color-picker.component
。验证器函数实际上已被调用并按预期工作。但是,表单字段不会被标记为无效,因为响应表单字段通常是(css类.ng-invalid
)。
答案 0 :(得分:0)
您可以使用ReactiveFormsModule
自定义类来设置不同状态的样式:
.ng-invalid {
border: 1px solid red;
}
您可以在angular.io...css-classes中找到有关ReactiveFormsModule
css类的更多文档。
答案 1 :(得分:0)
ibenjelloun,您的代码中存在错误。替换您的函数get value(),如果ratrat等于0,则返回null;否则,如果选择一个开始并取消选择,则不会返回错误
get value(): number {
let ratting= this.stars.reduce((total, starred) => {
return total + (starred ? 1 : 0);
}, 0);
return ratting?ratting:null;
}
如果您希望控件是由谁提供错误添加提供程序并创建功能验证的控件,请参见the ibenjelloun forked stackblitz