I am new in angular 2 and I want to implement a custom validator for form control that takes a boolean ( requiredAttribute) as parameter.
if this parameter is true so the form control is required else it is not required.
I have implemented this but seems don't works. All inputs (Form contol) becoms required. I have implemented this function that represent the custom validator.
function inputRequired( requiredAttribute: boolean) {
return (control: FormControl): { [s: string]: boolean } => {
if (requiredAttribute === false) {
return {'input is not required': true};
}else {
return null;
}
};
}
And I have placed it in the initForm method. Then for the input form text for my reactive form:
text: new FormControl('', [Validators.compose([inputRequired(this.selectedOperation.inputs[i].required)])]),
The final code
private initForm() {
function inputRequired( requiredAttribute: boolean) {
return (control: FormControl): { [s: string]: boolean } => {
if (requiredAttribute === false) {
return {'input is not required': true};
}else {
return null;
}
};
}
let operationName: any;
const operationInputs: FormArray = new FormArray([]);
if (this.selectedOperation.inputs != null) {
for (let i = 0; i < this.selectedOperation.inputs.length; i++ ) {
operationInputs.push(
new FormGroup({
name: new FormControl(this.selectedOperation.inputs[i].name),
text: new FormControl('', [Validators.compose([inputRequired(this.selectedOperation.inputs[i].required)])]),
defaultText: new FormControl(this.selectedOperation.inputs[i].defaultText),
complexType: new FormControl(this.selectedOperation.inputs[i].complexType),
type: new FormControl(this.selectedOperation.inputs[i].type),
isMultivalued: new FormControl(this.selectedOperation.inputs[i].isMultiValued),
values: new FormControl(this.selectedOperation.inputs[i].values),
indicator: new FormControl(this.selectedOperation.inputs[i].indicator),
required: new FormControl(this.selectedOperation.inputs[i].required),
isSelected: new FormControl(this.selectedOperation.inputs[i].isSelected),
simpleTypeVarietyOrComplexTypeContent: new FormControl(this.selectedOperation.inputs[i].simpleTypeVarietyOrComplexTypeContent),
choiceContent: new FormControl(this.selectedOperation.inputs[i].choiceContent),
inputQname: new FormControl(this.selectedOperation.inputs[i].inputQname),
attributes: new FormControl(this.selectedOperation.inputs[i].attributes),
children: operationInputsChildren,
})
);
}
}
operationName = this.selectedOperation.name;
this.operationRequestForm = this.formBuilder.group({
wsdlPath: [this.wsdlPath],
name: [operationName],
inputs: operationInputs,
operationDateInvoke: ['', Validators.required],
operationTimeInvoke: ['', Validators.required]
});
}
and the input is an object of CustomInput class that has required as attribute.
export class CustomInput {
constructor(public name: string, public text: string, public
defaultText: string,
public complexType: boolean, public type: string, public children:
CustomInput[] = [],
public isMultiValued: boolean,
public values: string[] = [], public indicator: string, public
required: boolean,
public isSelected: boolean, public
simpleTypeVarietyOrComplexTypeContent: number,
public choiceContent: boolean, public inputQname: string,
public attributes: Map<string, string> = new Map<string, string>()
) {}
}
An operation has many inputs elements. I want to create a reactive form for the operation. If the input element is required( its attribute required eqaul to true) then the HTML input associated to the operation input element is required.
So how I implement a custom validator that takes a boolean parameter and if this parameter is true then the form control is required else is not.
Thanks
UPDATE
Now when looking closer at post, I realize you don't need a custom validator at all. When building the form, you can just call a function that checks the value of this.selectedOperation.inputs[i].required
and if it's true
set the validator required, if not, do nothing.
So call the function after the build of the nested formgroup, but before the end of the iteration:
}); // end of formgroup build
this.checkValidator(this.selectedOperation.inputs[i].required, i)
) // end of iteration
And the function:
checkValidator(bool: boolean, index: number) {
const control = this.operationRequestForm.controls.operationInputs.controls[index].controls.text
if(bool) {
control.setValidators(Validators.required)
control.updateValueAndValidity();
}
}
A very simplified Plunker that showcases that it works fine with setValidators()
and updateValueAndValidity()
ORIGINAL POST:
Without testing your code (meaning that if there would be other problems), you are actually made it reverse in your custom validator. You want to...
if
requiredAttribute
istrue
the form control is required, else it is not required
Now you are doing the opposite in your custom validator.
The funny thing is with validating forms, is that null
is considered valid, and whatever else you return is considered not valid. So your custom validator should actually look like this:
if (requiredAttribute === true) {
return {'inputRequired': true}; // field is required
}else {
return null; // field is not required when 'requiredAttribute' is 'false'
}