Angular 2 - Move form validation to directive -
i move form validation directive , keep ngform validation across fields in form. in following example move input text field of following validation (1. works), directive. when move directive, model updated correct, form.valid operation not effected directive. form not valid, because input text has no value. when given value butten activated , form valid.
1. works:
<form (ngsubmit)="onsubmit()" #aliasform="ngform"> <div class="form-group"> <label for="firstname">fornavn</label> <input type="text" class="form-control" id="firstname" required [(ngmodel)]="model.primaryalias.firstname" name="firstname" #name="ngmodel"> <div [hidden]="name.valid || name.pristine" class="alert alert-danger"> fornavn er påkrævet </div> </div> <div class="form-group col-sm-6"> <p-dropdown [style]="{'width':'150px'}" [options]="genders" [(ngmodel)]="model.primaryalias.gender" name="genders" [required]="true"></p-dropdown> </div>
opret
2. not working directive (p-input):
<form (ngsubmit)="onsubmit()" #aliasform="ngform"> <p-input [(value)]="model.primaryalias.firstname" directivelabel="fornavn"></p-input> <div class="form-group"> <p-dropdown [style]="{'width':'150px'}" [options]="genders" [(ngmodel)]="model.primaryalias.gender" name="genders" [required]="true"></p-dropdown> </div> <button type="submit" class="btn btn-success pull-right" [disabled]="!aliasform.form.valid">opret</button></form>
p-input.html:
<div class="form-group"> <label for="firstname">fornavn</label> <input type="text" class="form-control" id="firstname" required [(ngmodel)]="value" (ngmodelchange)="onchange($event)" ngcontrol="value" name="firstname" #name="ngmodel"> <div [hidden]="name.valid || name.pristine" class="alert alert-danger"> fornavn er påkrævet </div>
how move validation directive , keep form handling, entire form intact ?
i either implement controlvalueaccessor
custom directive like:
p-input.ts
export const input_value_accessor: = { provide: ng_value_accessor, useexisting: forwardref(() => inputtestcomponent), multi: true }; @component({ selector: 'p-input', template: ` <div class="form-group"> <label for="firstname">{{directivelabel}}</label> <input type="text" class="form-control" id="firstname" required [(ngmodel)]="value" (ngmodelchange)="onmodelchange($event)" #name="ngmodel"> <div [hidden]="name.valid || name.pristine" class="alert alert-danger"> fornavn er påkrævet </div> </div> `, providers: [input_value_accessor] }) export class inputtestcomponent implements controlvalueaccessor { onchange = (_: any) => {}; ontouched = () => {}; value: string; @input() directivelabel: string; @viewchild('name') inputref: elementref; constructor(private renderer: renderer2) {} registeronchange(fn: (_: any) => void): void { this.onchange = fn; } registerontouched(fn: () => void): void { this.ontouched = fn; } onmodelchange(newvalue: string) { this.value = newvalue; this.onchange(this.value); } writevalue(val: any): void { this.value = val; } setdisabledstate(isdisabled: boolean): void { this.renderer.setproperty(this.inputref.nativeelement, 'disabled', isdisabled); } }
parent.html
<p-input required name="firstname" [(ngmodel)]="model.primaryalias.firstname" directivelabel="fornavn"> </p-input>
or add inner input control form manually:
p-input.ts
@component({ selector: 'p-input', template: ` <div class="form-group"> <label for="firstname">{{directivelabel}}</label> <input type="text" class="form-control" id="firstname" required [(ngmodel)]="value" (ngmodelchange)="onchange($event)" name="firstname" #name="ngmodel"> <div [hidden]="name.valid || name.pristine" class="alert alert-danger"> fornavn er påkrævet </div> </div> ` }) export class inputtestcomponent { @input() value: string; @input() directivelabel: string; @output() valuechange: eventemitter<string> = new eventemitter(); @viewchild(ngcontrol) inputcontrol: ngcontrol; constructor(@optional() private controlcontainer: controlcontainer) {} ngoninit() { if(this.controlcontainer) { this.controlcontainer.formdirective.addcontrol(this.inputcontrol); } } onchange(newvalue: string) { this.value = newvalue; this.valuechange.emit(this.value); } }
parent.html
<p-input [(value)]="model.primaryalias.firstname" directivelabel="fornavn"></p-input>
Comments
Post a Comment