*** Extraits de code : Les Formulaires pilotés par le template. ***
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Pokemon } from './pokemon';
import { PokemonsService } from './pokemons.service';
@Component({
selector: 'edit-pokemon',
template: `
<h2 class="header center">Editer {{ pokemon?.name }}</h2>
<p class="center">
<img *ngIf="pokemon" [src]="pokemon.picture"/>
</p>
<pokemon-form [pokemon]="pokemon"></pokemon-form>
`,
})
export class EditPokemonComponent implements OnInit {
pokemon: Pokemon = null;
constructor(
private route: ActivatedRoute,
private pokemonsService: PokemonsService) {}
ngOnInit(): void {
let id = +this.route.snapshot.params['id'];
this.pokemon = this.pokemonsService.getPokemon(id);
}
}
.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* bordure verte */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* bordure rouge */
}
<form *ngIf="pokemon" (ngSubmit)="onSubmit()" #pokemonForm="ngForm">
<div class="row">
<div class="col s8 offset-s2">
<div class="card-panel">
<!-- Pokemon name -->
<div class="form-group">
<label for="name">Nom</label>
<input type="text" class="form-control" id="name"
required
pattern="^[a-zA-Z0-9àéèç]{1,25}$"
[(ngModel)]="pokemon.name" name="name"
#name="ngModel">
<div [hidden]="name.valid || name.pristine"
class="card-panel red accent-1">
Le nom du pokémon est requis (1-25).
</div>
</div>
<!-- Pokemon hp -->
<div class="form-group">
<label for="hp">Point de vie</label>
<input type="number" class="form-control" id="hp"
required
pattern="^[0-9]{1,3}$"
[(ngModel)]="pokemon.hp" name="hp"
#hp="ngModel">
<div [hidden]="hp.valid || hp.pristine"
class="card-panel red accent-1">
Les points de vie du pokémon sont compris entre 0 et 999.
</div>
</div>
<!-- Pokemon cp -->
<div class="form-group">
<label for="cp">Dégâts</label>
<input type="number" class="form-control" id="cp"
required
pattern="^[0-9]{1,2}$"
[(ngModel)]="pokemon.cp" name="cp"
#cp="ngModel">
<div [hidden]="cp.valid || cp.pristine"
class="card-panel red accent-1">
Les dégâts du pokémon sont compris entre 0 et 99.
</div>
</div>
<!-- Pokemon types -->
<form class="form-group">
<label for="types">Types</label>
<p *ngFor="let type of types">
<label>
<input type="checkbox"
class="filled-in"
id="{{ type }}"
[value]="type"
[checked]="hasType(type)"
[disabled]="!isTypesValid(type)"
(change)="selectType($event, type)"/>
<span [attr.for]="type">
<div class="{{ type | pokemonTypeColor }}">
{{ type }}
</div>
</span>
</label>
</p>
</form>
<!-- Submit button -->
<div class="divider"></div>
<div class="section center">
<button type="submit"
class="waves-effect waves-light btn"
[disabled]="!pokemonForm.form.valid">
Valider</button>
</div>
</div>
</div>
</div>
</form>
<h3 *ngIf="!pokemon" class="center">Aucun pokémon à éditer...</h3>
import { Component, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { PokemonsService } from './pokemons.service';
import { Pokemon } from './pokemon';
@Component({
selector: 'pokemon-form',
templateUrl: './app/pokemons/pokemon-form.component.html',
styleUrls: ['./app/pokemons/pokemon-form.component.css']
})
export class PokemonFormComponent implements OnInit {
@Input() pokemon: Pokemon; // propriété d'entrée du composant
types: Array<string>; // types disponibles pour un pokémon : 'Eau', 'Feu', etc ...
constructor(
private pokemonsService: PokemonsService,
private router: Router) { }
ngOnInit() {
// Initialisation de la propriété types
this.types = this.pokemonsService.getPokemonTypes();
}
// Détermine si le type passé en paramètres appartient ou non au pokémon en cours d'édition.
hasType(type: string): boolean {
let index = this.pokemon.types.indexOf(type);
if (index > -1) return true;
return false;
}
// Méthode appelée lorsque l'utilisateur ajoute ou retire un type au pokémon en cours d'édition.
selectType($event: any, type: string): void {
let checked = $event.target.checked;
if (checked) {
this.pokemon.types.push(type);
} else {
let index = this.pokemon.types.indexOf(type);
if (index > -1) {
this.pokemon.types.splice(index, 1);
}
}
}
// Valide le nombre de types pour chaque pokémon
isTypesValid(type: string): boolean {
if (this.pokemon.types.length === 1 && this.hasType(type)) {
return false;
}
if (this.pokemon.types.length >= 3 && !this.hasType(type)) {
return false;
}
return true;
}
// La méthode appelée lorsque le formulaire est soumis.
onSubmit(): void {
console.log("Submit form !");
let link = ['/pokemon', this.pokemon.id];
this.router.navigate(link);
}
}