Update DOc - Forms
This commit is contained in:
parent
da8cdfc368
commit
3c1b4dc851
252
docs/forms.md
252
docs/forms.md
@ -0,0 +1,252 @@
|
|||||||
|
# Forms
|
||||||
|
|
||||||
|
Angular offers two different approach to retrieving data from a from.
|
||||||
|
- Template-driven (predefined)
|
||||||
|
- Reactive (Manual setup but flexible)
|
||||||
|
|
||||||
|
## Template driven
|
||||||
|
### Creating the Form and registering the controls
|
||||||
|
|
||||||
|
Import the Form module in the `app.module.ts`.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
@NgModules({
|
||||||
|
imports: [ FormsModule ]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Register the imput with the `ngModel` directive.
|
||||||
|
|
||||||
|
<img src="../img/form_ngModel.png" alt="overview" width="450"/>
|
||||||
|
|
||||||
|
### Submitting and using the Form
|
||||||
|
|
||||||
|
app.component.html
|
||||||
|
```html
|
||||||
|
<form (ngSubmit)="onSubmit(f)" #f="ngForm">
|
||||||
|
```
|
||||||
|
|
||||||
|
app.component.ts
|
||||||
|
```ts
|
||||||
|
onSubmit(form: ngForm) {
|
||||||
|
console.log(form);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<img src="../img/ngForm_json.png" alt="overview" width="300"/>
|
||||||
|
|
||||||
|
#### @ViewChild
|
||||||
|
|
||||||
|
Here we can retrive the data also without submitting the form
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { ViewChild } from '@angular/core';
|
||||||
|
|
||||||
|
export class AppComponent {
|
||||||
|
@ViewChild('f') signupForm: ngForm;
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
console.log(this.signupForm);
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### FormValidation
|
||||||
|
|
||||||
|
By adding an attribute like `required`, `email` to the html form. Angular detects as a directive and validates it automatically.
|
||||||
|
|
||||||
|
[Angular Validators](https://angular.io/api/forms/Validators)
|
||||||
|
|
||||||
|
#### Using the Form state
|
||||||
|
|
||||||
|
```html
|
||||||
|
<button
|
||||||
|
type="submnit"
|
||||||
|
[disabled]="!f.valid">Submit</button>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `f` referes to the local reference declaredy§ in the form.
|
||||||
|
|
||||||
|
Visually can be showen that a input is invalid by adding this CSS definition.
|
||||||
|
|
||||||
|
```css
|
||||||
|
input.ng-invalid.ng-touched {
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It shows only a red boder when the input field has been modified.
|
||||||
|
|
||||||
|
Showing some hint text
|
||||||
|
```html
|
||||||
|
<label for="email">Mail</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id="email"
|
||||||
|
class="form-control"
|
||||||
|
ngModel
|
||||||
|
name="email"
|
||||||
|
required
|
||||||
|
email
|
||||||
|
#email="ngModel">
|
||||||
|
<span class="help-block" *ngIf="!email.valid && email.touched">Please enter a valid email!</span>
|
||||||
|
```
|
||||||
|
|
||||||
|
`setValue` and `patchValue` helps to preset the form with predefined values. With `setValue` overrides the whole form, and `patchValue` updates only a specific inputfield. `patchValue` is aviable only from the `form` (`signupForm.form.patchValue({userData: { username: 'bliblubla'}});`).
|
||||||
|
|
||||||
|
## Reactive driven
|
||||||
|
|
||||||
|
Import the Form module in the `app.module.ts`.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
@NgModules({
|
||||||
|
imports: [ ReactiveFormsModule ]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
app.component.html
|
||||||
|
```html
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
|
||||||
|
<form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
|
||||||
|
<div formGroupName="userData">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="username"
|
||||||
|
formControlName="username"
|
||||||
|
class="form-control">
|
||||||
|
<span
|
||||||
|
*ngIf="!signupForm.get('userData.username').valid && signupForm.get('userData.username').touched"
|
||||||
|
class="help-block">
|
||||||
|
<span *ngIf="signupForm.get('userData.username').errors['nameIsForbidden']">This name is invalid!</span>
|
||||||
|
<span *ngIf="signupForm.get('userData.username').errors['required']">This field is required!</span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">email</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="email"
|
||||||
|
formControlName="email"
|
||||||
|
class="form-control">
|
||||||
|
<span
|
||||||
|
*ngIf="!signupForm.get('userData.email').valid && signupForm.get('userData.email').touched"
|
||||||
|
class="help-block">Please enter a valid email!</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="radio" *ngFor="let gender of genders">
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
formControlName="gender"
|
||||||
|
[value]="gender">{{ gender }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div formArrayName="hobbies">
|
||||||
|
<h4>Your Hobbies</h4>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
type="button"
|
||||||
|
(click)="onAddHobby()">Add Hobby</button>
|
||||||
|
<div
|
||||||
|
class="form-group"
|
||||||
|
*ngFor="let hobbyControl of signupForm.get('hobbies').controls; let i = index">
|
||||||
|
<input type="text" class="form-control" [formControlName]="i">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
*ngIf="!signupForm.valid && signupForm.touched"
|
||||||
|
class="help-block">Please enter valid data!</span>
|
||||||
|
<button class="btn btn-primary" type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
app.component.ts
|
||||||
|
```ts
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.css']
|
||||||
|
})
|
||||||
|
export class AppComponent implements OnInit {
|
||||||
|
genders = ['male', 'female'];
|
||||||
|
signupForm: FormGroup;
|
||||||
|
forbiddenUsernames = ['Chris', 'Anna'];
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.signupForm = new FormGroup({
|
||||||
|
'userData': new FormGroup({
|
||||||
|
'username': new FormControl(null, [Validators.required, this.forbiddenNames.bind(this)]),
|
||||||
|
'email': new FormControl(null, [Validators.required, Validators.email], this.forbiddenEmails)
|
||||||
|
}),
|
||||||
|
'gender': new FormControl('male'),
|
||||||
|
'hobbies': new FormArray([])
|
||||||
|
});
|
||||||
|
// this.signupForm.valueChanges.subscribe(
|
||||||
|
// (value) => console.log(value)
|
||||||
|
// );
|
||||||
|
this.signupForm.statusChanges.subscribe(
|
||||||
|
(status) => console.log(status)
|
||||||
|
);
|
||||||
|
this.signupForm.setValue({
|
||||||
|
'userData': {
|
||||||
|
'username': 'Max',
|
||||||
|
'email': 'max@test.com'
|
||||||
|
},
|
||||||
|
'gender': 'male',
|
||||||
|
'hobbies': []
|
||||||
|
});
|
||||||
|
this.signupForm.patchValue({
|
||||||
|
'userData': {
|
||||||
|
'username': 'Anna',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
console.log(this.signupForm);
|
||||||
|
this.signupForm.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddHobby() {
|
||||||
|
const control = new FormControl(null, Validators.required);
|
||||||
|
(<FormArray>this.signupForm.get('hobbies')).push(control);
|
||||||
|
}
|
||||||
|
|
||||||
|
forbiddenNames(control: FormControl): {[s: string]: boolean} {
|
||||||
|
if (this.forbiddenUsernames.indexOf(control.value) !== -1) {
|
||||||
|
return {'nameIsForbidden': true};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
forbiddenEmails(control: FormControl): Promise<any> | Observable<any> {
|
||||||
|
const promise = new Promise<any>((resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (control.value === 'test@test.com') {
|
||||||
|
resolve({'emailIsForbidden': true});
|
||||||
|
} else {
|
||||||
|
resolve(null);
|
||||||
|
}
|
||||||
|
}, 1500);
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
BIN
img/form_ngModel.png
Normal file
BIN
img/form_ngModel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 137 KiB |
BIN
img/ngForm_json.png
Normal file
BIN
img/ngForm_json.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 206 KiB |
Loading…
Reference in New Issue
Block a user