Fin section 13 : Formulaires

This commit is contained in:
Lucien Cartier-Tilet 2023-02-24 16:57:25 +01:00
parent 3cc7bb6f63
commit a789a10203
Signed by: phundrak
GPG Key ID: BD7789E705CB8DCA
9 changed files with 208 additions and 3 deletions

View File

@ -1,4 +1,5 @@
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
@ -8,7 +9,7 @@ import { PokemonModule } from './pokemon/pokemon.module';
@NgModule({
declarations: [AppComponent, PageNotFoundComponent],
imports: [BrowserModule, PokemonModule, AppRoutingModule],
imports: [BrowserModule, FormsModule, PokemonModule, AppRoutingModule],
providers: [],
bootstrap: [AppComponent],
})

View File

@ -48,6 +48,7 @@
</div>
<div class="card-action">
<a (click)="goToPokemonList()">Retour</a>
<a (click)="goToEditPokemon(pokemon)">Modifier</a>
</div>
</div>
</div>

View File

@ -26,4 +26,8 @@ export class DetailPokemonComponent implements OnInit {
goToPokemonList() {
this.router.navigate(['/pokemons']);
}
goToEditPokemon(pokemon: Pokemon) {
this.router.navigate(['/edit/pokemon', pokemon.id]);
}
}

View File

@ -0,0 +1,5 @@
<h2 class="center">Éditer {{ pokemon?.name }}</h2>
<p *ngIf="pokemon" class="center">
<img alt="" [src]="pokemon.picture" />
</p>
<app-pokemon-form *ngIf="pokemon" [pokemon]="pokemon"></app-pokemon-form>

View File

@ -0,0 +1,25 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Pokemon } from '../pokemon';
import { PokemonService } from '../pokemon.service';
@Component({
selector: 'app-edit-pokemon',
templateUrl: './edit-pokemon.component.html',
styles: [],
})
export class EditPokemonComponent implements OnInit {
pokemon: Pokemon | undefined;
constructor(
private route: ActivatedRoute,
private pokemonService: PokemonService
) {}
ngOnInit() {
const pokemonId: string | null = this.route.snapshot.paramMap.get('id');
if (pokemonId) {
this.pokemon = this.pokemonService.getPokemonById(+pokemonId);
}
}
}

View File

@ -0,0 +1,7 @@
.ng-valid[required] {
border-left: 5px solid #42a948;
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442;
}

View File

@ -0,0 +1,107 @@
<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>

View File

@ -0,0 +1,49 @@
import { Component, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Pokemon } from '../pokemon';
import { PokemonService } from '../pokemon.service';
@Component({
selector: 'app-pokemon-form',
templateUrl: './pokemon-form.component.html',
styleUrls: ['./pokemon-form.component.css'],
})
export class PokemonFormComponent implements OnInit {
@Input() pokemon: Pokemon;
types: string[];
constructor(private pokemonService: PokemonService, private router: Router) {}
ngOnInit(): void {
this.types = this.pokemonService.getPokemonTypeList();
}
hasType(type: string) {
return this.pokemon.types.includes(type);
}
selectType($event: Event, type: string) {
const isChecked: boolean = ($event.target as HTMLInputElement).checked;
if (isChecked) {
this.pokemon.types.push(type);
} else {
const index = this.pokemon.types.indexOf(type);
this.pokemon.types.splice(index, 1);
}
}
onSubmit() {
console.log('Submit form!');
this.router.navigate(['/pokemon', this.pokemon.id]);
}
isTypesValid(type: string): boolean {
if (this.pokemon.types.length === 1 && this.hasType(type)) {
return false;
}
if (this.pokemon.types.length > 2 && !this.hasType(type)) {
return false;
}
return true;
}
}

View File

@ -7,10 +7,14 @@ import { ListPokemonComponent } from './list-pokemon/list-pokemon.component';
import { DetailPokemonComponent } from './detail-pokemon/detail-pokemon.component';
import { RouterModule, Routes } from '@angular/router';
import { PokemonService } from './pokemon.service';
import { FormsModule } from '@angular/forms';
import { PokemonFormComponent } from './pokemon-form/pokemon-form.component';
import { EditPokemonComponent } from './edit-pokemon/edit-pokemon.component';
const pokemonRoutes: Routes = [
{ path: 'pokemons', component: ListPokemonComponent },
{ path: 'edit/pokemon/:id', component: EditPokemonComponent },
{ path: 'pokemon/:id', component: DetailPokemonComponent },
{ path: 'pokemons', component: ListPokemonComponent },
];
@NgModule({
@ -19,8 +23,10 @@ const pokemonRoutes: Routes = [
PokemonTypeColorPipe,
ListPokemonComponent,
DetailPokemonComponent,
PokemonFormComponent,
EditPokemonComponent,
],
imports: [CommonModule, RouterModule.forChild(pokemonRoutes)],
imports: [CommonModule, FormsModule, RouterModule.forChild(pokemonRoutes)],
providers: [PokemonService],
})
export class PokemonModule {}