Validating an email address in Angular 2.3.1 - javascript

I am trying to do some email validation on an angular 2 form, however I cannot make it work.
Here is my register.html form :-
<div class="row">
<div class="col-lg-10 col-offset-2">
<div class="well bs-component">
<form name="registerForm" class="form-horizontal" (ngSubmit)="onSubmit(email, password, name, surname, username, homephonenumber, mobilenumber)" >
<fieldset>
<legend>Register</legend>
<div class="form-group">
<label for="username" class="col-lg-2 control-label">UserName</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="username" [(ngModel)]="username" placeholder="Username" required minlength="4" maxlength="20">
</div>
</div>
<div class="form-group">
<label for="email" class="col-lg-2 control-label">Email</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="email" [(ngModel)]="email" placeholder="Email" required minlength="4" >
<div *ngIf="email.dirty && !email.valid" class="alert alert-danger">
<p *ngIf="email.errors.required">mailAddressis required.</p>
<p *ngIf="email.errors.incorrectMailFormat">Email format is invalid.</p>
</div>
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label">Password</label>
<div class="col-lg-10">
<input type="password" class="form-control" name="password" [(ngModel)]="password" placeholder="Password" required minlength="4">
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button>
<button type="submit" class="btn btn-primary">Register</button>
</div>
</div>
</fieldset>
</form>
</div>
and in my register.component.ts I have the following:-
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import {UserService} from 'app/services/user.service';
import {FormGroup, FormControl, Validators} from "#angular/forms";
#Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
registerForm: FormGroup;
constructor(private _userService:UserService, private _router:Router) { }
ngOnInit() {
this.registerForm = new FormGroup({
email: new FormControl('', this.validateEmail)
});
}
onSubmit(email, password, name, surname, username, homephonenumber, mobilenumber){
this._userService.register(email, password, name, surname, username, homephonenumber, mobilenumber)
.subscribe((result) => {
// if(result.access_token != null) {
// this._router.navigate(['']);
// }
});
}
validateEmail(c: FormControl) {
let EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+#[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
return EMAIL_REGEXP.test(c.value) ? null : {
validateEmail: {
valid: false
}
};
}
Do I need anything else to make the validation work?
Thanks for all your help and time.

HTML5 is having email type that validates by default.
<input type="email" class="form-control" name="email" [(ngModel)]="email" placeholder="Email" required minlength="4" >
Other way around is to use ng-pattern
<input ng-pattern = '/^(([^<>()\[\]\.,;:\s#\"]+(\.[^<>()\[\]\.,;:\s#\"]+)*)|(\".+\"))#(([^<>()[\]\.,;:\s#\"]+\.)+[^<>()[\]\.,;:\s#\"]{2,})$/i' type="email" name="email" class="form-control" ng-model="email" required="" />
<p class="help-block error-block">Enter a valid email address.</p>

try like this:
Html:
<form id="frmForgetPwd" name="frmForgetPwd" #frm="ngForm">
<div class="form-group">
<label>Registered Email Address</label>
<input type="email" class="form-control" focus
id="emailID" name="emailID" autofocus
#email="ngModel"
ngModel
required>
</div>
<button type="submit (click)="forgotPassword(email.value)">
Submit
</button>
</form>
component:
forgotPassword(emailid: string) {
this.errors = [];
if (emailid == "") {
this.errors.push(new error("invalidemail",Messages.EMAIL_IN_VALID));
return false;
}
let EMAIL_REGEXP = /^([\w-\.]+#([\w-]+\.)+[\w-]{2,4})?$/;
if (!EMAIL_REGEXP.test(emailid)) {
this.errors.push(new error("invalidemail",Messages.EMAIL_IN_VALID));
return false;
}
}

Related

setFirstName() is not a function, and returns undefined

I am working on a full stack application using react, and I am creating a website that adds a user to the database, I am using a class based component:
PersonalDetails.js
import styles from "../styles/style.module.css";
import { Component } from "react";
class PersonalDetails extends Component {
constructor({
firstName,
setFirstName,
lastName,
setLastName,
username,
setUsername,
mobile,
setMobile,
email,
setEmail,
preferedLanguage,
setPreferedLanguage,
}) {
super({
firstName,
setFirstName,
lastName,
setLastName,
username,
setUsername,
mobile,
setMobile,
email,
setEmail,
preferedLanguage,
setPreferedLanguage,
});
}
handleFnameChange = (event) => {
this.props.setFirstName(event.target.value);
console.log(this.props.setFirstName);
console.log(this.firstName);
};
handleLnameChange = (event) => {
this.setLastName(event.target.value);
};
handleUnameChange = (event) => {
this.setUserName(event.target.value);
};
handleMobileChange = (event) => {
this.setMobile(event.target.value);
};
handleEmailChange = (event) => {
this.setEmail(event.target.value);
};
handleLanguageChange = (event) => {
this.setPreferedLanguage(event.target.value);
};
render() {
return (
<div>
<div className={styles.sectionTitle}>
<h3>Personal Details</h3>
<hr></hr>
</div>
<div className={styles.doubleContainer}>
<div className={styles.inputlabelContainer}>
<label for="fname" className={styles.personalDetailsLabel}>
First Name
<span className={styles.star}>*</span>
</label>
<input
id="fname"
value={this.firstName}
onChange={this.handleFnameChange}
className={styles.personalDetailsInput}
type="text"
placeholder="Enter First Name"
required
></input>
</div>
<div className={styles.inputlabelContainer}>
<label for="lname" className={styles.personalDetailsLabel}>
Last Name
<span className={styles.star}>*</span>
</label>
<input
id="lname"
value={this.lastName}
onChange={this.handleLnameChange}
className={styles.personalDetailsInput}
type="text"
placeholder="Enter Last Name"
required
></input>
</div>
</div>
<div className={styles.doubleContainer}>
<div className={styles.inputlabelContainer}>
<label for="uname" className={styles.personalDetailsLabel}>
User Name
<span className={styles.star}>*</span>
</label>
<input
id="uname"
value={this.username}
onChange={this.handleUnameChange}
className={styles.personalDetailsInput}
type="text"
placeholder="Enter User Name"
required
></input>
</div>
<div className={styles.inputlabelContainer}>
<label for="mobilenb" className={styles.personalDetailsLabel}>
Mobile Number
<span className={styles.star}>*</span>
</label>
<input
id="mobilenb"
value={this.mobile}
onChange={this.handleMobileChange}
className={styles.personalDetailsInput}
type="tel"
placeholder="Enter Mobile Number"
required
></input>
</div>
</div>
<div className={styles.doubleContainer}>
<div className={styles.inputlabelContainer}>
<label for="email" className={styles.personalDetailsLabel}>
Email
<span className={styles.star}>*</span>
</label>
<input
id="email"
value={this.email}
onChange={this.handleEmailChange}
className={styles.personalDetailsInput}
type="email"
placeholder="Enter Email Address"
required
></input>
</div>
<div className={styles.inputlabelContainer}>
<label for="piflanguage" className={styles.personalDetailsLabel}>
Preferred Interface Language
<span className={styles.star}>*</span>
</label>
<select
id="piflanguage"
value={this.preferedLanguage}
onChange={this.handleLanguageChange}
className={styles.inputlabelContainer}
>
<option value="English">English</option>
<option value="Arabic">Arabic</option>
<option value="French">French</option>
</select>
</div>
</div>
</div>
);
}
}
export default PersonalDetails;
Explanation:
When I use this.setFirstName in the handleFnameChange() I get the error that this.setFirstName() is not a function, and when I use this.props.setFirstName() I get the result of firstName as undefined, the same for all other functions(setLastName, setMobile...)
What's the problem?

How to valid checkbox in a form

I have a basic question but i can't find the solution .
how can i force my user to check the box : accept the condition ? (j'acceptes les conditions d'utilisations = i agree terms & conditions )
here is a pictures of my form :
here is my HTML:
<section id="formDom">
<form class="column g-3 needs-validation" novalidate>
<div class="col-md-4">
<label for="validationCustom01" class="form-label">Nom</label>
<input type="text" class="form-control" placeholder="Dupont" id="firstName" required>
<div class="valid-feedback">
Ok
</div>
</div>
<div class="col-md-4">
<label for="validationCustom01" class="form-label">prénom</label>
<input type="text" class="form-control" placeholder="Jean" id="lastName" required>
<div class="valid-feedback">
Ok
</div>
</div>
<div class="col-md-4">
<label for="validationCustomUsername" class="form-label">Adresse mail</label>
<div class="input-group has-validation">
<span class="input-group-text" id="inputGroupPrepend">#</span>
<input type="email" class="form-control" id="email" aria-describedby="inputGroupPrepend"
placeholder="jeandupont#gmail.com" required>
<div class="invalid-feedback">
Adresse mail requise
</div>
</div>
</div>
<div class="col-md-4">
<label for="validationCustom01" class="form-label">Ville</label>
<input type="text" class="form-control" placeholder="Paris" id="city" required>
<div class="valid-feedback">
Ok
</div>
</div>
<div class="col-md-4">
<label for="validationCustom03" class="form-label">Adresse</label>
<input type="text" class="form-control" placeholder="1 rue de Paris" id="adress" required>
<div class="invalid-feedback">
adresse réquise
</div>
</div>
<div class="col-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
<label class="form-check-label" for="invalidCheck">
J'accepte les conditions d'utilisations
</label>
<div class="invalid-feedback">
Vous devez accepteer les conditions d'utilisations
</div>
</div>
</div>
<div class="col-md-4">
<button id="buyBtn" class="btn btn-primary basket-btn" type="submit">Acheter</button>
</div>
</form>
</section>
Actually the user is forced to fill the form but he can submit without check the box ( accept condition )
Here is the JS :
function validForm() {
const form = document.querySelector('.needs-validation');
form.addEventListener('submit', function (event) {
event.preventDefault();
event.stopPropagation();
cameraIds = getBasket().map(item => { return item.id });
const contact = {
email: document.getElementById("email").value,
firstName: document.getElementById("firstName").value,
lastName: document.getElementById("lastName").value,
city: document.getElementById("city").value,
address: document.getElementById("adress").value,
}
createOrder(contact, cameraIds, (order, error) => {
if (error) {
alert('Merci de remplir le formulaire');
} else {
localStorage.clear();
location.assign(`confirmation.html?id=${order.orderId}`)
}
form.classList.add('was-validated');
})
})
}
validForm();
PS : i'm using BOOTSTRAP but i think you got it ^^
if(document.getElementById('invalidCheck').checked==true)
//you'r accepted the terms
else
//you should accept the terms
You can check if a checkbox is checked or not by testing the checked property of the input element:
var isChecked = document.querySelector('input[type="checkbox"]').checked;
if(!isChecked) {
alert("You must accept the terms before proceeding");
}
In your case, it will be:
var isChecked = document.querySelector('.needs-validation .form-check-input').checked;
You can check for document.getElementById("").checked

How to Get Value and Do Validation of Input inside *ngFor Angular

I have a Form (multiple Input fields) inside ngFor and i want to get values and validate them and add them to Users array to send it back to API.
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div *ngFor="let user of users">
<div class="form-group">
<label>First Name</label>
<input type="text" formControlName="firstName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.firstName.errors }" />
<div *ngIf="submitted && f.firstName.errors" class="invalid-feedback">
<div *ngIf="f.firstName.errors.required">First Name is required</div>
</div>
</div>
<div class="form-group">
<label>Last Name</label>
<input type="text" formControlName="lastName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.lastName.errors }" />
<div *ngIf="submitted && f.lastName.errors" class="invalid-feedback">
<div *ngIf="f.lastName.errors.required">Last Name is required</div>
</div>
</div>
</div>
<div class="form-group">
<button [disabled]="loading" class="btn btn-primary">Register</button>
</div>
</form>
.ts
export class AppComponent {
users=[
{id: 1},
{id: 2},
{id: 3}
]
registerForm: FormGroup;
submitted = false;
constructor(private formBuilder: FormBuilder){
this.registerForm = this.formBuilder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required]
});
}
get f() { return this.registerForm.controls; };
onSubmit() {
this.submitted = true;
// stop here if form is invalid
if (this.registerForm.invalid) {
return;
}
console.log(this.registerForm.value) // here i am getting value from last edited index.
}
}
Edit:
Stackblitz Exmple
You have to create array of FormGroup using users array.
Try this:
component.ts
this.registerForm = this.formBuilder.group({
userDetails: this.formBuilder.array(this.users.map(item=>{
return this.createItem(item)
})),
});
Since userDetails control is array of formGroup you don't need to use users array in html.
component.html
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div formArrayName="userDetails" *ngFor="let item of registerForm.get('userDetails').controls; let i = index;">
<div [formGroupName]="i">
<div class="form-group">
<label>First Name</label>
<input type="text" formControlName="firstName" class="form-control" />
<div *ngIf="submitted && registerForm.controls['userDetails'].invalid" class="invalid-feedback">
<div>First Name is required</div>
</div>
</div>
<div class="form-group">
<label>Last Name</label>
<input type="text" formControlName="lastName" class="form-control" />
<div *ngIf="submitted && registerForm.controls['userDetails'].invalid" class="invalid-feedback">
<div>Last Name is required</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<button [disabled]="loading" class="btn btn-primary">Register</button>
</div>
</form>
Example
you cant use a simple FormControl, for array values. formControl is only for a single value, so only the last edited value will be attached to them, you need to use
https://angular.io/api/forms/FormArray for that

Post method for submitting a form on api

There is a form on angular 8
my-form.component.html
<div class="container">
<form novalidate [formGroup]="registrationForm">
<div class="form-group">
<label for="firstName">Имя:</label>
<input #spy required pattern=[A-Za-zА-Яа-яЁё]{2,} name="firstName" id="firstName" type="text" class="form-control" formControlName="firstName">
</div>
<div class="form-group">
<label for="lastName">Фамилия:</label>
<input #spy required pattern=[A-Za-zА-Яа-яЁё]{2,} name="lastName" id="lastName" type="text" class="form-control" formControlName="lastName">
</div>
<div class="form-group">
<label for="email">E-mail:</label>
<input #spy required email name="email" id="email" type="email" class="form-control" formControlName="email">
</div>
<!--{{ spy.className }}-->
<button type="submit" class="btn btn-succes" (click)="submit(myForm)">Отправить</button>
</form>
When the user writes data, the submit button should send data to the API using the POST method.
If you need any code, leave a comment
ts code:
import { FormGroup, FormControl } from '#angular/forms';
import {HttpClient} from '#angular/common/http';
#Component({
selector: 'app-my-form',
templateUrl: './my-form.component.html',
styleUrls: ['./my-form.component.css']
})
export class MyFormComponent implements OnInit {
registrationForm: FormGroup;
constructor() { }
ngOnInit() {
this.registrationForm = new FormGroup({
firstName: new FormControl(),
lastName: new FormControl(),
email: new FormControl()
});
}
}```
i have simple example for you....
reference
----html----
<header class="masthead">
<div class="container h-100">
<div class="row h-100 align-items-center justify-content-center">
<div class="col-6">
<div class="text-center">
<hello name="{{ name }}"></hello>
<hr>
</div>
<form #send="ngForm" (ngSubmit)="sendFRMData(send.value)">
<div class="form-group">
<label for="title" class="text-muted">Title</label>
<input type="text" class="form-control" id="title"
name="titlefrm" ngModel #title='ngModel' required>
<span class="help-block text-danger" *ngIf="!title.valid &&
title.touched">Please give Title!!</span>
</div>
<div class="form-group">
<label for="body" class="text-muted">Body</label>
<input type="text" class="form-control" id="body" name="bodyfrm" ngModel
#body='ngModel' required>
<span class="help-block text-danger" *ngIf="!body.valid &&
body.touched">Please
give Body!!</span>
</div>
<div class="form-group">
<label for="userId" class="text-muted">UserID</label>
<input type="text" class="form-control" id="userId" name="userIdfrm" ngModel
#userid='ngModel' required>
<span class="help-block text-danger" *ngIf="!userid.valid &&
userid.touched">Please give UserID!!</span>
</div>
<div class="row">
<div class="col-sm-6">
<input class="form-control btn btn-success" type="submit"
[disabled]='!send.valid'>
</div>
<div class="col-sm-6">
<input class="form-control btn btn-info" type="button" value="EDIT"
(click) = 'onEdit()'>
</div>
</div>
</form>
</div>
</div>
</div>
</header>
----ts----
import { NgForm } from '#angular/forms';
#ViewChild('send') send: NgForm;
constructor(private sendData: HttpService) {
}
sendFRMData(data: any) {
const payload = {
title: data.titlefrm,
body: data.bodyfrm,
userId: data.userIdfrm
}
this.sendData.try(payload).subscribe(
(data: any) => {
this.respondedData = JSON.stringify(data);
this.alert = true;
}
);
}
----service----
try(data){
return
this.http.post('https://jsonplaceholder.typicode.com/posts',data,{
headers: {
"Content-type": "application/json; charset=UTF-8"
}
});
}
hope you get your answer...
Seems like you are not able to get form values in your submit function.
change your click event from (click)="submit(myForm)" to (click)="submit(myForm.value)" then in your submit function you can call post method
submit(formValueObject) {
console.log(formValueObject);
this.httpService.post(url, formValueObject).subscribe((res:any)=> {
//your response
})
}
I hope it helps

What is the best / most elegant way for doing form validation and styling validation error messages in Angular 2 (Reactive Forms)?

I am creating a (relatively) simple form using Angular 2 reactive forms. The fields are simple: first name, last name, email, password, and post code. There are confirm fields for email and password. There are also some relatively simple validation rules, i.e. first name and last name must be longer than two characters, email must be a valid email address etc.
For the UI, I am using Bootstrap to style the form and add visual validation highlights, e.g. using has-error on divs for fields that did not validate. After adding it in, I find that the HTML is very cluttered and there must be a better way to simplify the form, e.g. using custom validators or custom form controls. I would appreciate if you could help me getting to the best way of developing the form and improving my Angular 2 skills (I am a beginner in this framework).
Template below:
<div class="well">
<form class="form-horizontal" name="nameForm" [formGroup]="nameForm" (ngSubmit)="save(nameForm.value, nameForm.valid)" novalidate>
<div class="form-group" [ngClass]="{ 'has-error': !nameForm.controls.firstname.pristine && !nameForm.controls.firstname.valid }">
<label for="firstname" class="control-label">First name</label>
<input type="text" class="form-control" name="firstname" placeholder="First name" formControlName="firstname"
required minlength="2" />
<span [hidden]="nameForm.controls.firstname.valid || (nameForm.controls.firstname.pristine && !submitted)" class="text-danger">
First name is required (minimum 2 characters).
</span>
</div>
<div class="form-group" [ngClass]="{ 'has-error': !nameForm.controls.lastname.pristine && !nameForm.controls.lastname.valid }">
<label for="lastname" class="control-label">Last name</label>
<input type="text" class="form-control" name="lastname" placeholder="Last name" formControlName="lastname"
required minlength="2" />
<span [hidden]="nameForm.controls.lastname.valid || (nameForm.controls.lastname.pristine && !submitted)" class="text-danger">
Last name is required (minimum 2 characters).
</span>
</div>
<div class="form-group" [ngClass]="{ 'has-error': !nameForm.controls.email.pristine && !nameForm.controls.email.valid }">
<label for="email" class="control-label">Your e-mail address</label>
<input type="email" class="form-control" name="email" placeholder="E-mail address" formControlName="email"
required />
<span [hidden]="nameForm.controls.email.valid || (nameForm.controls.email.pristine && !submitted)" class="text-danger">
Valid e-mail address required
</span>
</div>
<div class="form-group" [ngClass]="{ 'has-error': !nameForm.controls.emailrepeat.pristine && !nameForm.controls.emailrepeat.valid }">
<label for="emailrepeat" class="control-label">Your e-mail address (repeat)</label>
<input type="email" class="form-control" name="emailrepeat" placeholder="E-mail address again" formControlName="emailrepeat" required />
<span [hidden]="(nameForm.controls.email.valid && nameForm.controls.emailrepeat.value == nameForm.controls.email.value) || (nameForm.controls.emailrepeat.pristine && !submitted)" class="error">
E-mail addresses must match
</span>
</div>
<div class="form-group" [ngClass]="{ 'has-error': !nameForm.controls.password.pristine && !nameForm.controls.password.valid }">
<label for="passsword" class="control-label">Password</label>
<input type="password" class="form-control" name="password" formControlName="password"
minlength="5" required />
<span [hidden]="nameForm.controls.password.valid || (nameForm.controls.password.pristine && !submitted)" class="error">
Password is required (minimum 5 characters)
</span>
</div>
<div class="form-group" [ngClass]="{ 'has-error': !nameForm.controls.passwordrepeat.pristine && !nameForm.controls.passwordrepeat.valid }">
<label for="repeatpasssword" class="control-label">Password (repeat)</label>
<input type="password" class="form-control" name="passwordrepeat" formControlName="passwordrepeat"
required />
<span [hidden]="(nameForm.controls.passwordrepeat.valid && nameForm.controls.passwordrepeat.value == nameForm.controls.password.value) || (nameForm.controls.passwordrepeat.pristine && !submitted)" class="error">
Passwords must match
</span>
</div>
<div class="form-group">
<label for="postcode" class="control-label">Postcode</label>
<input type="number" class="form-control" name="postcode" placeholder="E.g. 2000" formControlName="postcode"
/>
</div>
<button type="submit" class="btn btn-default" [disabled]="nameForm.invalid">Next</button>
</form>
</div>
Component code:
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormControl, FormBuilder, Validators } from '#angular/forms';
#Component({
selector: 'enrol',
templateUrl: './enrol.component.html',
styleUrls: ['./enrol.component.css']
})
export class EnrolComponent implements OnInit {
public member: Member;
public nameForm: FormGroup;
public submitted: boolean;
public events: any[] = [];
constructor(private fb: FormBuilder) { }
ngOnInit() {
const emailRegex = '^[a-z0-9]+(\.[_a-z0-9]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,15})$';
// Initialise form here:
this.nameForm = this.fb.group({
firstname: [null, [<any>Validators.required, <any>Validators.minLength(2)]],
lastname: [null, [<any>Validators.required, <any>Validators.minLength(2)]],
email: [null, [<any>Validators.required, <any>Validators.pattern(emailRegex)]],
emailrepeat: [null, [<any>Validators.required, <any>Validators.pattern(emailRegex)]],
password: [null, [<any>Validators.required]],
passwordrepeat: [null, [<any>Validators.required]],
postcode: null
})
}
save (model: Member, isValid: boolean) {
this.submitted = true;
// check if model is valid
// if valid, call API to save it
console.log(model, isValid);
}
}
export interface Member {
firstname: string;
lastname: string;
password: string;
passwordrepeat: string;
email: string;
emailrepeat: string;
postcode?: number;
}
PS - comments on code style etc are also much welcome. I am a back-end developer by trade and not that wellversed in front-end development.

Categories