Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty controls are invalid when a [required]="false" property is defined #5976

Closed
frickt opened this issue Dec 17, 2015 · 18 comments
Closed

Empty controls are invalid when a [required]="false" property is defined #5976

frickt opened this issue Dec 17, 2015 · 18 comments

Comments

@frickt
Copy link

@frickt frickt commented Dec 17, 2015

small example:

import {Component} from 'angular2/core'
import {FORM_DIRECTIVES, Control} from "angular2/common";

@Component({
     selector: "login-comp",
     directives: [FORM_DIRECTIVES],
     template: '<input type="text" [(ngModel)]="login" [ngFormControl]="loginControl" [required]="isRequired()">'
})
export class App {
 loginControl: Control = new Control('');
 login:string = "";

 isRequired(){
   return false;
 }
}

plnkr for alpha.54

http://plnkr.co/edit/nPlfg2uNAMYTkc5gBWTh?p=preview

@ericmartinezr
Copy link
Contributor

@ericmartinezr ericmartinezr commented Dec 17, 2015

@frickt required is an attribute, you must add attr to it.

... [attr.required]="isRequired()">
@pkozlowski-opensource
Copy link
Member

@pkozlowski-opensource pkozlowski-opensource commented Dec 17, 2015

@ericmartinezr this should work with binding to properties. And there is a required property: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#Properties

Generally speaking we do prefer binding to properties. Currently the main use case for binding to attributes are: aria support and attributes one would like to add for styling

@thelgevold
Copy link
Contributor

@thelgevold thelgevold commented Dec 17, 2015

Different implementation, I know, but I have been using the built in form validators for this. I like this approach since it enables me to manage all validators from a central location.

constructor(fb: FormBuilder) {
    this.form = fb.group({
        "firstName": ['', Validators.required],
        "zip": ['', Validators.compose([zipValidator])],
    });
}

Working example here: http://www.syntaxsuccess.com/viewarticle/forms-and-validation-in-angular-2.0

@slintes
Copy link

@slintes slintes commented Feb 16, 2016

Hi, I have the same problem, I'm setting required and readonly based on a checkbox value, see this example:

http://plnkr.co/edit/XM8QTwkr3B4nzc40gEpx?p=preview

@zoechi
Copy link
Contributor

@zoechi zoechi commented Feb 17, 2016

If you want the requiredattribute to be remove the value needs to be null not false

 isRequired(){
   return null;
 }
@slintes
Copy link

@slintes slintes commented Feb 17, 2016

mh, at least in Chrome I see that required is removed with the false value from the checkbox, same for readonly the other way around, with [required]="checked" [readonly]="!checked", see my plunker.
For now I switched to using FormBuilder and a custom validator for checkbox + input on the model side...

@awerlang
Copy link
Contributor

@awerlang awerlang commented Mar 1, 2016

[required] is used to initialize a validator for the control. After that, it would always validate even if the required attribute is removed. This behavior diverges from ng1 ng-required.

For a conditional required, you need a custom validator and call updateValueAndValidity() to revalidate. If you want to preserve the required attribute, you'll need to use the attr.required syntax, only for screen readers perhaps.

See comment: #6824 (comment)

@slintes
Copy link

@slintes slintes commented Mar 2, 2016

I use a 1 custom validator for both checkbox and text input now. Code snippets (exposeToFrontend is the checkbox, exposeUrl the text input):

this.formControls = this._fb.group({
            expose: this._fb.group({
                exposeToFrontend: [],
                exposeUrl: []
            },{
                validator: MyValidators.checkboxInputValidator("exposeToFrontend", "exposeUrl", "exposeUrlRequired")
            })
        });
    public static checkboxInputValidator(checkboxName: string, inputName: string, errorCode: string) {
        return (controlGroup: ControlGroup): {[key: string]: any} => {
            let checkbox = controlGroup.controls[checkboxName].value;
            let input = controlGroup.controls[inputName].value;
            if (checkbox && !input) {
                this.addError(inputName, controlGroup.controls[inputName], errorCode);
            }
            else {
                this.removeError(inputName, controlGroup.controls[inputName], errorCode);
            }
            return null;
        }
    }
@udos86
Copy link

@udos86 udos86 commented May 30, 2016

Stumbled over this a couple of days ago.

In my opinion this behavior perhaps should be reconsidered because it doesn't feel one hundred percent naturally. When applying Validators.required programmatically no required attribute is added in the DOM. Shouldn't it be there for a semantic reason? I can see the advantage of not having to deal with browser default validation messages on submit, though.

Otherwise as soon as you add [required] in markup, Validators.required is implicitly set, no matter if you bind [required]="true"or [required]="false". Falling back to [attr.required] seems not intuitive when there is a [required] property at the same time.

@westor21
Copy link

@westor21 westor21 commented May 31, 2016

Coming from large angular1 projects, it's unacceptable, not to have a bindable [required] with working validation as pendant to ng-required.

@Zefling
Copy link

@Zefling Zefling commented Jun 3, 2016

Same problem whit Material2 input on RC1. If required is at false and control says is not required, the field is still required.

@zoechi
Copy link
Contributor

@zoechi zoechi commented Jun 3, 2016

As far as I know currently attributes for validators required, minlength, pattern, ... need to be static HTML and can't be set by bindings.

Looks like a dup of #7393

@westor21
Copy link

@westor21 westor21 commented Jun 3, 2016

I think, that is a showstopper for many of us migrating angular1 to angular2 - we can currently not implement all of our app logic.

@zoechi
Copy link
Contributor

@zoechi zoechi commented Jun 3, 2016

You can use model driven forms and add validators there with full control.

@kara
Copy link
Contributor

@kara kara commented Aug 29, 2016

Should have been fixed by #11116.

@kara kara closed this Aug 29, 2016
@DeepzSandra
Copy link

@DeepzSandra DeepzSandra commented Mar 14, 2018

Angular 2 Form Validation Using Validators WIth An Element That Is Dynamically Built Using *ngIf
see this example
constructor(
private QRService:QRService,
fb: FormBuilder
){
this.title = 'My Form';
this.showDeliveryTypes = false;
this.complexForm = fb.group({
'number' : [null, Validators.required],
'dateofbirth' : [null, Validators.required],
'delivery' : [null, Validators.required],
'location' : [null, Validators.required], //validates even if these aren't included using *ngIf
'options' : [null, Validators.required] //validates even if these aren't included using *ngIf
})

};
thanks

@angular-automatic-lock-bot
Copy link

@angular-automatic-lock-bot angular-automatic-lock-bot bot commented Sep 13, 2019

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.