Angular: Problem with form validation in template driven form
I'm developing a web application using Angular 6. I have a question: I would like to create some custom components that are inspired by the components of HTML input. For example:
CustomComponent.ts (typescript)
@Component(
selector: 'custom-component',
templateUrl: './custom-component.html',
providers: [
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => InputTextComponent)
]
)
export class CustomComponent
@Input() name: string;
@Input() isRequired: boolean;
CustomComponent.html (template)
<input type="text"
[attr.name]="name"
[required] = "isRequired"
/>
I have this problem. Suppose we use my component in this template:
<form #myForm="ngForm" ngNativeValidate>
<custom-component
name="myName"
[isRequired] = true
ngModel
></custom-component>
<button type="submit" (click)="method()">Click</button>
The required
attribute it's initialized correctly in the <input type="text/>
(wrapped component of <custom-component>
). The problem is this (it's an Angular problem!): in this code of usage:
method()
console.log(this.myForm.valid);
The object myForm.valid
(where myForm
is associated with #myForm
in the previous template) return always the true
value, even if nothing is entered in the text field. This behavior is wrong: I would like this value to be false if I do not insert anything in the required field.
Anyone can help me?
html angular forms components
add a comment |
I'm developing a web application using Angular 6. I have a question: I would like to create some custom components that are inspired by the components of HTML input. For example:
CustomComponent.ts (typescript)
@Component(
selector: 'custom-component',
templateUrl: './custom-component.html',
providers: [
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => InputTextComponent)
]
)
export class CustomComponent
@Input() name: string;
@Input() isRequired: boolean;
CustomComponent.html (template)
<input type="text"
[attr.name]="name"
[required] = "isRequired"
/>
I have this problem. Suppose we use my component in this template:
<form #myForm="ngForm" ngNativeValidate>
<custom-component
name="myName"
[isRequired] = true
ngModel
></custom-component>
<button type="submit" (click)="method()">Click</button>
The required
attribute it's initialized correctly in the <input type="text/>
(wrapped component of <custom-component>
). The problem is this (it's an Angular problem!): in this code of usage:
method()
console.log(this.myForm.valid);
The object myForm.valid
(where myForm
is associated with #myForm
in the previous template) return always the true
value, even if nothing is entered in the text field. This behavior is wrong: I would like this value to be false if I do not insert anything in the required field.
Anyone can help me?
html angular forms components
add a comment |
I'm developing a web application using Angular 6. I have a question: I would like to create some custom components that are inspired by the components of HTML input. For example:
CustomComponent.ts (typescript)
@Component(
selector: 'custom-component',
templateUrl: './custom-component.html',
providers: [
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => InputTextComponent)
]
)
export class CustomComponent
@Input() name: string;
@Input() isRequired: boolean;
CustomComponent.html (template)
<input type="text"
[attr.name]="name"
[required] = "isRequired"
/>
I have this problem. Suppose we use my component in this template:
<form #myForm="ngForm" ngNativeValidate>
<custom-component
name="myName"
[isRequired] = true
ngModel
></custom-component>
<button type="submit" (click)="method()">Click</button>
The required
attribute it's initialized correctly in the <input type="text/>
(wrapped component of <custom-component>
). The problem is this (it's an Angular problem!): in this code of usage:
method()
console.log(this.myForm.valid);
The object myForm.valid
(where myForm
is associated with #myForm
in the previous template) return always the true
value, even if nothing is entered in the text field. This behavior is wrong: I would like this value to be false if I do not insert anything in the required field.
Anyone can help me?
html angular forms components
I'm developing a web application using Angular 6. I have a question: I would like to create some custom components that are inspired by the components of HTML input. For example:
CustomComponent.ts (typescript)
@Component(
selector: 'custom-component',
templateUrl: './custom-component.html',
providers: [
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => InputTextComponent)
]
)
export class CustomComponent
@Input() name: string;
@Input() isRequired: boolean;
CustomComponent.html (template)
<input type="text"
[attr.name]="name"
[required] = "isRequired"
/>
I have this problem. Suppose we use my component in this template:
<form #myForm="ngForm" ngNativeValidate>
<custom-component
name="myName"
[isRequired] = true
ngModel
></custom-component>
<button type="submit" (click)="method()">Click</button>
The required
attribute it's initialized correctly in the <input type="text/>
(wrapped component of <custom-component>
). The problem is this (it's an Angular problem!): in this code of usage:
method()
console.log(this.myForm.valid);
The object myForm.valid
(where myForm
is associated with #myForm
in the previous template) return always the true
value, even if nothing is entered in the text field. This behavior is wrong: I would like this value to be false if I do not insert anything in the required field.
Anyone can help me?
html angular forms components
html angular forms components
asked Nov 13 '18 at 15:48
claudiozclaudioz
145212
145212
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
To add validation to your custom input component you should add the following to your providers:
provide: NG_VALIDATORS,
useExisting: forwardRef(() => InputTextComponent),
multi: true
You will have have to implement the default method, within your InputTextComponent:
validate(control: AbstractControl): ValidationErrors | null
return null;
If you correctly update a property within your component called value using the writeValue() method you implemented with your NG_VALUE_ACCESSOR and then ensure to call (you can do this by implementing a change event on your default input):
this.propagateChange(this.value);
Finally change your isRequired input to the default required property.
@Input() required: boolean;
Your NgModel should now correctly update.
Edit: To avoid using required (however this is the correct way). Within the validation method place the following code:
validate(control: AbstractControl): ValidationErrors | null
return this.isRequired && this.value.length === 0 : required: true : null;
What is happening is when Angular runs its own validation it calls this method. When this method returns anything but null, the object is added to the errors property within the FormControl & NgModel.
This is a huge topic and there are some great articles properly explaining it all. However, as asked, this should solve it.
Thanks, I did everything, except the last step. Why I need to edit the input name (@Input() required: boolean;) and how is this reflected in the template of my custom component?
– claudioz
Nov 13 '18 at 16:21
Ok it works. But what if I wanted to keep the isRequired property?
– claudioz
Nov 13 '18 at 16:24
I would like to avoid using the "required" property from the caller... I preder use the custom property "isRequired" from the caller
– claudioz
Nov 13 '18 at 16:49
When using NgModel and ControlValueAccessor, you are informing Angular that you will be treating this component as a default HTML input. You can use isRequired, however, your input element is not the input within the component but your InputTextComponent itself. I will update my answer to include a workaround, however, I would advise against it. That is why using require as you would with a real input is advised.
– Jmsdb
Nov 13 '18 at 17:55
add a comment |
You should check is form dirty and is it valid. So both needs to be true. Otherwise it shows it hasn't been changed.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284663%2fangular-problem-with-form-validation-in-template-driven-form%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
To add validation to your custom input component you should add the following to your providers:
provide: NG_VALIDATORS,
useExisting: forwardRef(() => InputTextComponent),
multi: true
You will have have to implement the default method, within your InputTextComponent:
validate(control: AbstractControl): ValidationErrors | null
return null;
If you correctly update a property within your component called value using the writeValue() method you implemented with your NG_VALUE_ACCESSOR and then ensure to call (you can do this by implementing a change event on your default input):
this.propagateChange(this.value);
Finally change your isRequired input to the default required property.
@Input() required: boolean;
Your NgModel should now correctly update.
Edit: To avoid using required (however this is the correct way). Within the validation method place the following code:
validate(control: AbstractControl): ValidationErrors | null
return this.isRequired && this.value.length === 0 : required: true : null;
What is happening is when Angular runs its own validation it calls this method. When this method returns anything but null, the object is added to the errors property within the FormControl & NgModel.
This is a huge topic and there are some great articles properly explaining it all. However, as asked, this should solve it.
Thanks, I did everything, except the last step. Why I need to edit the input name (@Input() required: boolean;) and how is this reflected in the template of my custom component?
– claudioz
Nov 13 '18 at 16:21
Ok it works. But what if I wanted to keep the isRequired property?
– claudioz
Nov 13 '18 at 16:24
I would like to avoid using the "required" property from the caller... I preder use the custom property "isRequired" from the caller
– claudioz
Nov 13 '18 at 16:49
When using NgModel and ControlValueAccessor, you are informing Angular that you will be treating this component as a default HTML input. You can use isRequired, however, your input element is not the input within the component but your InputTextComponent itself. I will update my answer to include a workaround, however, I would advise against it. That is why using require as you would with a real input is advised.
– Jmsdb
Nov 13 '18 at 17:55
add a comment |
To add validation to your custom input component you should add the following to your providers:
provide: NG_VALIDATORS,
useExisting: forwardRef(() => InputTextComponent),
multi: true
You will have have to implement the default method, within your InputTextComponent:
validate(control: AbstractControl): ValidationErrors | null
return null;
If you correctly update a property within your component called value using the writeValue() method you implemented with your NG_VALUE_ACCESSOR and then ensure to call (you can do this by implementing a change event on your default input):
this.propagateChange(this.value);
Finally change your isRequired input to the default required property.
@Input() required: boolean;
Your NgModel should now correctly update.
Edit: To avoid using required (however this is the correct way). Within the validation method place the following code:
validate(control: AbstractControl): ValidationErrors | null
return this.isRequired && this.value.length === 0 : required: true : null;
What is happening is when Angular runs its own validation it calls this method. When this method returns anything but null, the object is added to the errors property within the FormControl & NgModel.
This is a huge topic and there are some great articles properly explaining it all. However, as asked, this should solve it.
Thanks, I did everything, except the last step. Why I need to edit the input name (@Input() required: boolean;) and how is this reflected in the template of my custom component?
– claudioz
Nov 13 '18 at 16:21
Ok it works. But what if I wanted to keep the isRequired property?
– claudioz
Nov 13 '18 at 16:24
I would like to avoid using the "required" property from the caller... I preder use the custom property "isRequired" from the caller
– claudioz
Nov 13 '18 at 16:49
When using NgModel and ControlValueAccessor, you are informing Angular that you will be treating this component as a default HTML input. You can use isRequired, however, your input element is not the input within the component but your InputTextComponent itself. I will update my answer to include a workaround, however, I would advise against it. That is why using require as you would with a real input is advised.
– Jmsdb
Nov 13 '18 at 17:55
add a comment |
To add validation to your custom input component you should add the following to your providers:
provide: NG_VALIDATORS,
useExisting: forwardRef(() => InputTextComponent),
multi: true
You will have have to implement the default method, within your InputTextComponent:
validate(control: AbstractControl): ValidationErrors | null
return null;
If you correctly update a property within your component called value using the writeValue() method you implemented with your NG_VALUE_ACCESSOR and then ensure to call (you can do this by implementing a change event on your default input):
this.propagateChange(this.value);
Finally change your isRequired input to the default required property.
@Input() required: boolean;
Your NgModel should now correctly update.
Edit: To avoid using required (however this is the correct way). Within the validation method place the following code:
validate(control: AbstractControl): ValidationErrors | null
return this.isRequired && this.value.length === 0 : required: true : null;
What is happening is when Angular runs its own validation it calls this method. When this method returns anything but null, the object is added to the errors property within the FormControl & NgModel.
This is a huge topic and there are some great articles properly explaining it all. However, as asked, this should solve it.
To add validation to your custom input component you should add the following to your providers:
provide: NG_VALIDATORS,
useExisting: forwardRef(() => InputTextComponent),
multi: true
You will have have to implement the default method, within your InputTextComponent:
validate(control: AbstractControl): ValidationErrors | null
return null;
If you correctly update a property within your component called value using the writeValue() method you implemented with your NG_VALUE_ACCESSOR and then ensure to call (you can do this by implementing a change event on your default input):
this.propagateChange(this.value);
Finally change your isRequired input to the default required property.
@Input() required: boolean;
Your NgModel should now correctly update.
Edit: To avoid using required (however this is the correct way). Within the validation method place the following code:
validate(control: AbstractControl): ValidationErrors | null
return this.isRequired && this.value.length === 0 : required: true : null;
What is happening is when Angular runs its own validation it calls this method. When this method returns anything but null, the object is added to the errors property within the FormControl & NgModel.
This is a huge topic and there are some great articles properly explaining it all. However, as asked, this should solve it.
edited Nov 13 '18 at 18:00
answered Nov 13 '18 at 16:01
JmsdbJmsdb
44417
44417
Thanks, I did everything, except the last step. Why I need to edit the input name (@Input() required: boolean;) and how is this reflected in the template of my custom component?
– claudioz
Nov 13 '18 at 16:21
Ok it works. But what if I wanted to keep the isRequired property?
– claudioz
Nov 13 '18 at 16:24
I would like to avoid using the "required" property from the caller... I preder use the custom property "isRequired" from the caller
– claudioz
Nov 13 '18 at 16:49
When using NgModel and ControlValueAccessor, you are informing Angular that you will be treating this component as a default HTML input. You can use isRequired, however, your input element is not the input within the component but your InputTextComponent itself. I will update my answer to include a workaround, however, I would advise against it. That is why using require as you would with a real input is advised.
– Jmsdb
Nov 13 '18 at 17:55
add a comment |
Thanks, I did everything, except the last step. Why I need to edit the input name (@Input() required: boolean;) and how is this reflected in the template of my custom component?
– claudioz
Nov 13 '18 at 16:21
Ok it works. But what if I wanted to keep the isRequired property?
– claudioz
Nov 13 '18 at 16:24
I would like to avoid using the "required" property from the caller... I preder use the custom property "isRequired" from the caller
– claudioz
Nov 13 '18 at 16:49
When using NgModel and ControlValueAccessor, you are informing Angular that you will be treating this component as a default HTML input. You can use isRequired, however, your input element is not the input within the component but your InputTextComponent itself. I will update my answer to include a workaround, however, I would advise against it. That is why using require as you would with a real input is advised.
– Jmsdb
Nov 13 '18 at 17:55
Thanks, I did everything, except the last step. Why I need to edit the input name (@Input() required: boolean;) and how is this reflected in the template of my custom component?
– claudioz
Nov 13 '18 at 16:21
Thanks, I did everything, except the last step. Why I need to edit the input name (@Input() required: boolean;) and how is this reflected in the template of my custom component?
– claudioz
Nov 13 '18 at 16:21
Ok it works. But what if I wanted to keep the isRequired property?
– claudioz
Nov 13 '18 at 16:24
Ok it works. But what if I wanted to keep the isRequired property?
– claudioz
Nov 13 '18 at 16:24
I would like to avoid using the "required" property from the caller... I preder use the custom property "isRequired" from the caller
– claudioz
Nov 13 '18 at 16:49
I would like to avoid using the "required" property from the caller... I preder use the custom property "isRequired" from the caller
– claudioz
Nov 13 '18 at 16:49
When using NgModel and ControlValueAccessor, you are informing Angular that you will be treating this component as a default HTML input. You can use isRequired, however, your input element is not the input within the component but your InputTextComponent itself. I will update my answer to include a workaround, however, I would advise against it. That is why using require as you would with a real input is advised.
– Jmsdb
Nov 13 '18 at 17:55
When using NgModel and ControlValueAccessor, you are informing Angular that you will be treating this component as a default HTML input. You can use isRequired, however, your input element is not the input within the component but your InputTextComponent itself. I will update my answer to include a workaround, however, I would advise against it. That is why using require as you would with a real input is advised.
– Jmsdb
Nov 13 '18 at 17:55
add a comment |
You should check is form dirty and is it valid. So both needs to be true. Otherwise it shows it hasn't been changed.
add a comment |
You should check is form dirty and is it valid. So both needs to be true. Otherwise it shows it hasn't been changed.
add a comment |
You should check is form dirty and is it valid. So both needs to be true. Otherwise it shows it hasn't been changed.
You should check is form dirty and is it valid. So both needs to be true. Otherwise it shows it hasn't been changed.
answered Nov 13 '18 at 15:58
Slobodan GajićSlobodan Gajić
104110
104110
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284663%2fangular-problem-with-form-validation-in-template-driven-form%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown