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

Comments

@frickt
Copy link

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

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

... [attr.required]="isRequired()">

@pkozlowski-opensource
Copy link
Member

@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

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 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 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 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 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 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 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 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 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 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 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 commented Jun 3, 2016

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

@kara
Copy link
Contributor

kara commented Aug 29, 2016

Should have been fixed by #11116.

@kara kara closed this as completed Aug 29, 2016
@amdani786
Copy link

@DeepzSandra
Copy link

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

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.
Labels
None yet
Projects
None yet
Development

No branches or pull requests