Reputation: 93
Given a particular formGroup and it's corresponding HTML form
this.fieldForm = new FormGroup({
fieldId: new FormControl(null),
fieldName: new FormControl("", Validators.required),
sourceCreateBy: new FormControl(null),
sourceUpdateBy: new FormControl(null),
}, {validators: FieldFormValidators.invalidFormInput}) // some other logic
Consider the scenario that fieldName
= "WORKFORCE". In the HTML Form, I edit the input field to make the value first "WORKFORCE_1" and then back to "WORKFORCE". The formGroup attributes have changed from pristine=true, dirty=false, touched=false
to pristine=false, dirty=true, touched=true
.
Hence the form is valid. But actually no data change has taken place. Are there any inbuilt FormControl or FormGroup attributes or any combination thereof that can help me disable the "UPDATE" button or can I do such validation only after the fact(UPDATE button click)?
Can I create a custom validator to address this validation logic?
Upvotes: 0
Views: 1247
Reputation: 58099
You can create a custom validator "isDifferent", but first reemplace the way to create the form using a function
getForm(data:any=null){
data=data|| {fieldID:null,fieldName:"",sourceCreateBy:null,sourceUpdateBy:null}
return FormGroup({
fieldId: new FormControl(null),
fieldName: new FormControl("", Validators.required),
sourceCreateBy: new FormControl(null),
sourceUpdateBy: new FormControl(null),
}, {validators: [FieldFormValidators.invalidFormInput,isDifferent(data)]})
getForm(data:any=null){
data=data|| {fieldID:null,fieldName:"",sourceCreateBy:null,sourceUpdateBy:null}
return FormGroup({
fieldId: new FormControl(data.fieldID),
fieldName: new FormControl(data.fieldName, Validators.required),
sourceCreateBy: new FormControl(data.sourceCreatedBy),
sourceUpdateBy: new FormControl(data.sourceUpdateBy),
}, {validators: [FieldFormValidators.invalidFormInput,isDifferent(data)]}) // some other logic
isDiferent(data:any){
return (control:AbtractControl)=>{
bool equal=true;
Object.keys(data).forEach(key=>{
equal=equal && data[key]==control.value[key]
})
return equal?{error:"must be different"}:null
}
}
You use as
this.fieldForm=this.getForm(..your object...)
Update:Aclaration. Well the code above goes from I imagine a typical REST. So if we has a component to Edit/Create a register we has a router like
{ path: 'hero/:id',component: HeroDetailComponent },
Where, possible id values are a number or "new", so we can has
url=hero/new //edit-component to create a new "hero"
url=hero/1 //edit-compoent to edit the hero with "id=1"
Our component, that has an form and use reactiveForm take account this, so
constructor(private activatedRoute: ActivatedRoute,private service: HeroService) {}
form:FormGroup
status:string //here we store if "new" or "edit" to use for e.g.
//the button "submit" show a message "create" or "update"
ngOnInit() {
this.activatedRoute.paramMap.pipe(
switchMap(params => {
const id=params.get('id')
if (id=="new"){
this.form=this.getForm(); //create a empty form
this.status="new"
}
else{
//use "+id" to convert to number the "id"
this.service.getHeroe(+id).subscribe(res=>{
//here we has the "data of the "hero"
this.form=this.getForm(res) //create a form with the data of hero
this.status="edit"
})
}
);
}
Our .html needn't a complex handlers in inputs, e.g. our button "submit" can be
<!--see that the button is disabled if the form is invalid
if it's not invalid you need equal "disabled" to null,
**not** to false
--->
<button disabled="form.invalid?true:null">
{{status=="new"?"Create":"Update"}}
</button>
Upvotes: 1