I'm making a litte todo app with angular.
in my component.html i want a validation. If you enter nothing in the textbox then i text is show with "title is required". And when you have less then 5 characters in the textbox then also a text is showing.
But that doesn't work ..
When i start my app i see only my textbox without my todo's. When i enter 1 letter in the textbox then i see my todos. Also when i have only 4 characters i see no notification that says i must have 5 characters ..
This is my code :
<h3>Add todo</h3>
<form >
<input class="form-control" type="text" id="text" required minlength="5" [(ngModel)]="text" name="text" >
<div *ngIf="text.errors && (text.dirty || text.touched)" class="alert alert-danger">
<div [hidden]="!text.errors.required">
Title is required
</div>
<div [hidden]="!text.errors.minlength">
titel moet minstens 5 karakters zijn
</div>
</div>
</form>
<button class="btn btn-danger" (click)="addTodo()">test</button>
You need to use the template reference with ngModel to bind the error messages. Like so: #text="ngModel".
The two-way-binding won't work with the same name, so they have to be different. Here I have actually changed the name of the two-way-binding variable to theText:
<input type="text" id="text" required minlength="5" [(ngModel)]="theText"
name="text" #text="ngModel">
Here's the complete template, notice we are giving the form a template reference #myForm="ngForm" and on submit we pass the values from that form:
<form #myForm="ngForm" (ngSubmit)="submitForm(myForm.value)">
<input type="text" id="text" required minlength="5" [(ngModel)]="theText" name="text" #text="ngModel" >
<div *ngIf="text.errors && (text.touched || text.dirty)" class="alert alert-danger">
<div [hidden]="!text.errors?.required">
Title is required
</div>
<div [hidden]="!text.errors?.minlength">
titel moet minstens 5 karakters zijn
</div>
</div>
</form>
As a sidenote, you maybe even don't need the two-way-binding (??) here? You could extract the data from the object you get of the form values (myForm.value).
Related
I wanted to try and verify input before being submitted therefore I used the required attribute at the end of input, but it's not working and I've already tried some of the recommended solution like wrapping the input in form tag or trying to close the tag of input () but when i submit my form with an empty input it stills submited normally and doesn't declare a required field .
I would appreciate any help, thank you!!
this is a part of my code
<form id="form" style="background-color:honeydew ;" class="container text-center">
<div><br><h2> Contact Us </h2></div>
<div id="contact">
<div>
<label> Name</label>
<input type="text" placeholder="Your name " name="name" required/>
</div>
<br>
<div>
<label> Email</label>
<input type="email" placeholder="name#gmail.com" name="email" name="email">
</div>
<br>
<div>
<label> Message</label>
<input type="text" style="height:50px;" name="message">
</div>
<br>
<div><input type="button" value="submit" name="submit"><br></div>
<br>
</div>
<br>
</form>
and this is the javascript file linked to it :
//we take informations subbmitted by user from the form and we replace the form with a reply
//containing these pieces of information on the click on the submit button
var form=document.getElementById('form'),
contactForm=document.getElementById('contact'),
submitButton=contactForm.children[6].children[0];
var processForm= function(){
name=document.getElementsByName('name')[0].value,
email=document.getElementsByName('email')[0].value,
sitereplyText=document.createTextNode('this is a initialiazing value'),
sitereplyEl=document.createElement('p');
mytext= 'Hey '+name+'! Thanks for your message :) We will email you back at '+email;
sitereplyText.nodeValue=mytext;
sitereplyEl.appendChild(sitereplyText);
form.replaceChild(sitereplyEl,contactForm);
}
submitButton.addEventListener('click',processForm);
So i firstly corrected the input type into submit
<input type="submit" value="submit" name="submit">
then in the javascript file i changed
submitButton.addEventListener('click',processForm);
to
submitButton.addEventListener('form.submit()',processForm);
and it seems to work :)
I have a form which validates all the inputs. For, say, 'username' input I want to make sure it's a required field first and second that its length isn't less than 2 or more than 10 (or fits another pattern I use).
I'd like to show an error when either validation fails. How do I do this if I want to show a specific error for each case case? For example: if the input is empty show 'required', if the value is wrong show 'invalid'. Here's my code:
component:
companyNamePattern = "^[a-z0-9_-]{8,15}$";
pwdPattern = "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{6,12}$";
emailPattern = "^[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,4}$";
this.addCompForm = fb.group({
'companyName': [null,Validators.compose([Validators.required,Validators.minLength(5),Validators.maxLength(20)])],
'companyPassword': [null,Validators.compose([Validators.required,Validators.minLength(5),Validators.maxLength(20)])],
'companyEmail': [null,Validators.compose([Validators.required,Validators.email])]
})
html:
<form [formGroup] ="addCompForm" (ngSubmit) = "addCompany(addCompForm.value)">
<p>Enter the company name:</p>
<input type="text" formControlName="companyName" >
<div class="alert" *ngIf="!addCompForm.controls['companyName'].valid && addCompForm.controls['companyName'].touched" >{{nameAlert}}</div>
<p>Enter the company password:</p>
<input type="text" formControlName="companyPassword">
<div class="alert" *ngIf="!addCompForm.controls['companyPassword'].valid && addCompForm.controls['companyPassword'].touched " >{{passAlert}}</div>
<p>Enter the company email:</p>
<input type="text" formControlName="companyEmail">
<div class="alert" *ngIf="!addCompForm.controls['companyEmail'].valid && addCompForm.controls['companyEmail'].touched " >{{emailAlert}}</div>
<br>
<br>
<div class="btn-container">
<button type="submit" [disabled]="!addCompForm.valid">
<i class="material-icons">done</i>
</button>
</div>
</form>
*ngIf="addCompForm.get('companyName').hasError('required')
add this to make required field and
*ngIf="addCompForm.get('companyName').hasError('minLength')
add this for making minLength and same as for max length .hasErro('maxlength')
My html code is
<div>
<div>
<form name="form 1" ng-submit="submitForm1()">
<input type="text" required name="text1">
</form>
</div
<div>
<form name="form 2" ng-submit="submitForm2()">
<input type="text" required name="text2">
</form>
</div>
</div>
and in my controller i am accessing the form using scope.controller looks like
$scope.submitFrom1 = function(){
console.log(form1);
}
$scope.submitFrom2 = function(){
console.log(form2);
}
but in result first form will give object and second form is returning undefined
I am getting why this is happening.
You have to use ngModel for the fields inside each form to access data.
https://docs.angularjs.org/api/ng/directive/ngModel
<form name="firstForm" ng-submit="submitForm1()">
<input type="text" required name="text1" ng-model="firstForm.text1>
</form>
<form name="secondForm" ng-submit="submitForm2()">
<input type="text" required name="text1" ng-model="secondForm.text1>
</form>
In controller
$scope.firstForm.text1 to access the data from first form individually.
$scope.secondForm.text1 to access the data from second form individually.
To get full form object just use.
$scope.firstForm;
$scope.secondForm;
Remove the spaces from the form names.
<!-- remove spaces from form name
<form name="form 1" ng-submit="submitForm1()">
-->
<form name="form1" ng-submit="submitForm1()">
<input type="text" required name="text1" ng-model="a">
</form>
<!-- remove spaces from form name
<form name="form 2" ng-submit="submitForm2()">
-->
<form name="form2" ng-submit="submitForm2()">
<input type="text" required name="text2" ng-model="b">
</form>
It was causing $parse errors.
The DEMO on JSFiddle
I am using the model driven form like this .
Just like normal validations , i want that i show an error message if username and password are missing.
And Submit button should be disabled as long as username and password are not valid.
<div class="login">
<form #f="ngForm" (ngSubmit)="dologin(f)">
<div class="form-group">
<label for="username">Username</label>
<input id="username" type="text" class="form-control" name ="username" ngModel #username="ngModel">
<div [hidden]="username.valid" class="alert alert-danger"> Username is required.</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input id="password" type="password" class="form-control" name ="password" ngModel #password="ngModel">
<div [hidden]="password.valid" class="alert alert-danger"> Password is required.</div>
</div>
<button type="submit" [disabled]="username.length<0 || password.length<0" class="btn btn-primary" type="submit">Login</button>
</form>
</div>
i am seeing quite strange behaviour from validation div. Sometimes
it is showing "Password is required" and sometimes not.
i want to disable the submit button, until the form is valid .i tried
[disabled]="!f.valid"
but as i print it out f is always valid even
though i have not entered any data in username and password.
Component:
constructor(private router: Router,private authenticationService : AuthenticationService,private httpService:HttpService,private formBuilder:FormBuilder) {
this.form=formBuilder.group({
username:['',Validators.required],
password:['',Validators.required]
});
}
UPDATE
Can't bind to 'formGroup' since it isn't a known property of 'form'.
(" ][formGroup]="form"
(ngSubmit)="dologin(form.value)">
][formControl]="form.controls['password']">
[ERROR ->]
Username
[ERROR ->]
"): LoginComponent#4:8 No provider for NgControl ("
Password
[ERROR ->] ; Task: Promise.then ; Value:
Error: Template parse errors:(…) Error: Template parse errors: Can't
bind to 'formGroup' since it isn't a known property of 'form'. ("
][formGroup]="form"
(ngSubmit)="dologin(form.value)">
][formControl]="form.controls['password']">
[ERROR ->]
Username
[ERROR ->]
Thanks.
The way you have set up your HTML template is missing some key bits that actually ensure you have wired up the front end to the back end for a reactive form. What you have appears to be more in line with a template driven form mixed with model driven. In fact, the template you have posted will not even compile if you remove your FormsModule import.
To begin with remove your FormsModule import which is letting you mix the two different form types together. This will take us down a path where a strict Reactive Forms (aka model driven) implementation is required.
<form #f="ngForm" (ngSubmit)="dologin(f)"> will be changed to <form [formGroup]="form" (ngSubmit="dologin(form.value)"
Each of your inputs and warning divs will change from
<input id="username" type="text" class="form-control" name="username" ngModel #username="ngModel">
<div [hidden]="username.valid" class="alert alert-danger"> Username is required.</div>
To
<input id="username" type="text" class="form-control" name="username" formControlName="username">
The changes are because the ngModel attribute and #[name]="ngModel" are not supported in the model driven form, so instead you will use either formControlName or [formControl] syntax.
<div [hidden]="form.controls['username'].valid || form.controls['username'].pristine"
class="alert alert-danger"> Username is required.</div>
Finally, your submit button changes, note that you have type="submit" twice, from <button type="submit" [disabled]="username.length<0 || password.length<0" class="btn btn-primary" type="submit">Login</button>
To
<button type="submit" [disabled]="!form.valid" class="btn btn-primary">Login</button>
since we have successfully wired up the rest of the form the validation on the form group will now be correct
And here is a working plunker that you can play around with: https://plnkr.co/edit/Mu9vEYGB35SwUr9TEsPI?p=preview
Implementation without form builder
<form #loginForm="ngForm" (ngSubmit)="login()">
<md-input required type="email"
pattern="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"
placeholder="Email Address" #email="ngModel" name="email"
[(ngModel)]="loginModel.email"></md-input>
<div *ngIf="email.dirty && !email.valid && email.touched && email.errors" class="error-message">
<div *ngIf="email.errors.required">Email is required</div>
<div *ngIf="!email.errors.required && email.errors.pattern">This is not a valid email</div>
</div>
<md-input required type="password" placeholder="Password" #password="ngModel" name="password" [(ngModel)]="loginModel.password"></md-input>
<div *ngIf="password.dirty && !password.valid && password.touched && password.errors" class="error-message">
<div *ngIf="password.errors.required">Password is required</div>
</div>
<button ma-raised-button [disabled]="!loginForm.valid">
Login
</button>
</form>
Component:
ngOnInit() {
this.loginModel = {email: '', password: ''};
}
login() {
console.log(this.loginModel['email']);
console.log(this.loginModel['password']);
}
I'm using this code for a form in HTML:
<div class="login-wrapper">
<form>
<div class="popup-header">
<span class="text-semibold"><i class="fa fa-sign-in"></i> Logging in</span>
</div>
<div class="well">
<div class="form-group has-feedback">
<label>Username</label>
<input type="text" name="user" class="form-control" placeholder="e.g. andre#mail.de">
<i class="icon-users form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label>Password</label>
<input type="password" name="password" class="form-control" placeholder="Password">
<i class="icon-lock form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label>reCaptcha</label>
<div class="g-recaptcha" data-sitekey="..."></div>
</div>
<div class="form-actions text-right">
<input type="submit" id="loginbutton" name="loginbutton" value="Login" class="btn btn-primary">
</div>
</div>
</form>
</div>
<!-- /login wrapper -->
However, when I press the submit button, it does nothing but giving me a very strange url in my browser's address bar:
http://localhost/?user=&password=&g-recaptcha-response=&loginbutton=Login
Whenever I fill out fields, it kind of puts the content into the URL:
http://localhost/?user=peter%40griffin.com&password=somepass&g-recaptcha-response=&loginbutton=Login
The intended PHP code which should be run when pressing the button won't even run or load, since this HTML stuff apparently screws things up. I don't know what I have done the wrong way. Any suggestions?
In order for the form to submit somewhere else, you need to set the form elements action parameter.
<form action="some_file.php">
Alternatively, you can take the query string and append it directly to the file path to test your script.
http://localhost/some_file.php?user=peter%40griffin.com&password=somepass&g-recaptcha-response=&loginbutton=Login
Inside of some_file.php, you would then pull out each of the variables like
$user = $_GET['user'];
$password = $_GET['password'];
The very strange url is actually the result of a GET request.
The parameters are separated by an & so you have:
user=peter%40griffin.com&password=somepass&g-recaptcha-response=
"User" is the attribute name of your input and "peter%40griffin.com" is the value
First you need to send your form to an action using the attribute action="save.php", for example an pass the parameters using the method="POST", so the user can't see the values in the URL.
<form action="save.php" method="post">