Angular 8 reactive forms with enum and checkboxes

Viewed 6676

I'm trying to do a sort of pokedex in Angular 8. I have an enum with all the types (elements) of pokemons. Then I have my form displaying all these types in checkboxes. i'm sending my datas to a Firebase database. Everything is working fine.

My problem is that I don't know how to send the values checked to the database.

So how can I have an array of checked checkboxes. For example ["Eau","Feu","Electrik"] ?

My model:

export class Pokemon {

  id: number;
  nom: string;
  type: Types[];
  description: string;
  photo: string;

  constructor(id: number, nom: string, type: Types[], description: string) {

    this.id = id;
    this.nom = nom;
    this.type = type;
    this.description = description;

  }

}


export enum Types {
  Insecte = 'Insecte',
  Dragon = 'Dragon',
  Fee = 'Fee',
  Feu = 'Feu',
  Spectre = 'Spectre',
  Sol = 'Sol',
  Normal = 'Normal',
  Psy = 'Psy',
  Acier = 'Acier',
  Tenebre = 'Tenebre',
  Electrik = 'Electrik',
  Combat = 'Combat',
  Vol = 'Vol',
  Plante = 'Plante',
  Glace = 'Glace',
  Poison = 'Poison',
  Roche = 'Roche',
  Eau = 'Eau'
}

My component.ts :

  export class AjouterPokemonComponent implements OnInit {

  pokemonForm: FormGroup;
  fileIsUploading = false;
  fileUrl: string;
  fileUploaded = false;

  values = Object.keys(Types);


  constructor(private formBuilder: FormBuilder, private pokemonService: PokemonService, private router: Router) { }

  ngOnInit() {
    this.initForm();
    console.log(this.values);
  }

  initForm() {
    this.pokemonForm = this.formBuilder.group({
      id: ['', Validators.required],
      nom: ['', Validators.required],
      type: ['', Validators.required],
      description: ''
    });
  }

  // save the pokemon
  onSavePokemon() {
    const id = this.pokemonForm.get('id').value;
    const nom = this.pokemonForm.get('nom').value;
    const type = this.pokemonForm.get('type').value;
    const description = this.pokemonForm.get('description').value;

    const newPokemon = new Pokemon(id, nom, type, description);
    if (this.fileUrl && this.fileUrl !== '') {
      newPokemon.photo = this.fileUrl;
    }
    this.pokemonService.createNewPokemon(newPokemon);
    this.router.navigate(['/liste-pokemon']);
  }

My component.html :

<div class="row">
  <div class="col-sm-8 col-sm-offset-2">
    <h2>Enregistrer un nouveau Pokemon</h2>
    <form [formGroup]="pokemonForm" (ngSubmit)="onSavePokemon()">

      <div class="form-group">
        <label for="id">ID</label>
        <input type="text" id="id" class="form-control" formControlName="id">
      </div>

      <div class="form-group">
        <label for="nom">Nom</label>
        <input type="text" id="nom" class="form-control" formControlName="nom">
      </div>

      <div class="form-group form-check form-check-inline" *ngFor="let type of values">
        <input class="form-check-input" type="checkbox" formControlName="type" id="type">
        <label class="form-check-label" for="type">{{type}}</label>
      </div>

      <div class="form-group">
        <label for="description">Description</label>
        <textarea id="description" class="form-control" formControlName="description"></textarea>
      </div>

      <div class="form-group">
        <h4>Ajouter une photo</h4>
        <input type="file" (change)="detectFiles($event)" class="form-control" accept="image/*">
        <p class="text-success" *ngIf="fileUploaded">Fichier chargé !</p>
      </div>

      <button class="btn btn-success" [disabled]="pokemonForm.invalid || fileIsUploading" type="submit">Enregistrer</button>

    </form>
  </div>
</div>

Here's a picture of my form : enter image description here

1 Answers

The following code will work. We need to use formArray

html

  ////remaining html code ////

  <div class="form-group form-check form-check-inline" *ngFor="let type of values">
    <input class="form-check-input" [value]="type" type="checkbox" (change)="onCheckChange($event)" id="type">
    <label class="form-check-label" for="type">{{type}}</label>
  </div>

 ////remaining html code ////

component.ts

//// remaining code ////

types:any[]=[]; // for storing types values as array..
pokemonForm: FormGroup;
fileIsUploading = false;
fileUrl: string;
fileUploaded = false;

values = Object.keys(Types);


constructor(private formBuilder: FormBuilder,   
  // private pokemonService: PokemonService, private router: Router
) { }

ngOnInit() {
  this.initForm();
  console.log(this.values);
}

initForm() {
   this.pokemonForm = this.formBuilder.group({
     id: ['', Validators.required],
     nom: ['', Validators.required],
     types: new FormArray([]), 
     // types: new FormArray([],[Validators.required]) if you want to add validators
     description: ''
  });
 }

 // save the pokemon
 onSavePokemon() {
    // store final array after submit
   const id = this.pokemonForm.get('id').value;
   const nom = this.pokemonForm.get('nom').value;
   const description = this.pokemonForm.get('description').value;

    // After submit store all checked values in array 
    ////// for final saving selected arrays //////////

    const formArray1: FormArray = this.pokemonForm.get('types') as FormArray;
    let j: number = 0;

    formArray1.controls.forEach((ctrl: FormControl) => {
      console.log("ctrl is ",ctrl);
      this.types.push(ctrl.value); // types declared on top

       j++;
    });
   console.log("typesi s ",this.types);  prints final selected checkedvalues





 }

 onCheckChange(event) {
    const formArray: FormArray = this.pokemonForm.get('types') as FormArray;

    /* Selected */
    if(event.target.checked){
       // Add a new control in the arrayForm
       formArray.push(new FormControl(event.target.value));
     }
     /* unselected */
     else{
        // find the unselected element
       let i: number = 0;

      formArray.controls.forEach((ctrl: FormControl) => {
        if(ctrl.value == event.target.value) {
        // Remove the unselected element from the arrayForm
        formArray.removeAt(i);
        return;
       }

       i++;
      });
   }
   console.log("Total Form is ",this.pokemonForm);



  }

Note I commented router & pokemonService as i dont have those classes code.

Related