Skip to main content

Angular Form Text including form array and validation

Recipe-Edit-component.Ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { FormGroup, FormControl, FormArray, Validators } from '@angular/forms';

import { RecipeService } from '../recipe.service';

@Component({
  selector: 'app-recipe-edit',
  templateUrl: './recipe-edit.component.html',
  styleUrls: ['./recipe-edit.component.css']
})
export class RecipeEditComponent implements OnInit {
  id: number;
  editMode = false;
  recipeForm: FormGroup;

  constructor(private route: ActivatedRoute,
              private recipeService: RecipeService,
              private router: Router) {
  }

  ngOnInit() {
    this.route.params
      .subscribe(
        (params: Params) => {
          this.id = +params['id'];
          this.editMode = params['id'] != null;
          this.initForm();
        }
      );
  }

  onSubmit() {
    // const newRecipe = new Recipe(    //   this.recipeForm.value['name'],    
//   this.recipeForm.value['description'],    //   this.recipeForm.value['imagePath'],   
 //   this.recipeForm.value['ingredients']);   
 if (this.editMode) {
      this.recipeService.updateRecipe(this.id, this.recipeForm.value);
    } else {
      this.recipeService.addRecipe(this.recipeForm.value);
    }
    this.onCancel();
  }

  onAddIngredient() {
    (<FormArray>this.recipeForm.get('ingredients')).push(
      new FormGroup({
        'name': new FormControl(null, Validators.required),
        'amount': new FormControl(null, [
          Validators.required,
          Validators.pattern(/^[1-9]+[0-9]*$/)
        ])
      })
    );
  }

  onDeleteIngredient(index: number) {
    (<FormArray>this.recipeForm.get('ingredients')).removeAt(index);
  }

  onCancel() {
    this.router.navigate(['../'], {relativeTo: this.route});
  }

  private initForm() {
    let recipeName = '';
    let recipeImagePath = '';
    let recipeDescription = '';
    let recipeIngredients = new FormArray([]);

    if (this.editMode) {
      const recipe = this.recipeService.getRecipe(this.id);
      recipeName = recipe.name;
      recipeImagePath = recipe.imagePath;
      recipeDescription = recipe.description;
      if (recipe['ingredients']) {
        for (let ingredient of recipe.ingredients) {
          recipeIngredients.push(
            new FormGroup({
              'name': new FormControl(ingredient.name, Validators.required),
              'amount': new FormControl(ingredient.amount, [
                Validators.required,
                Validators.pattern(/^[1-9]+[0-9]*$/)
              ])
            })
          );
        }
      }
    }

    this.recipeForm = new FormGroup({
      'name': new FormControl(recipeName, Validators.required),
      'imagePath': new FormControl(recipeImagePath, Validators.required),
      'description': new FormControl(recipeDescription, Validators.required),
      'ingredients': recipeIngredients    });
  }

}

Recipe-Edit-component.html


<div class="row">
    <div class="col-xs-12">
        <form [formGroup]="recipeForm" (ngSubmit)="onSubmit()">
            <div class="row">
                <div class="col-xs-12">
                    <button type="submit" class="btn btn-success" [disabled]="!recipeForm.valid">Save
                    </button>
                    <button type="button" class="btn btn-danger" (click)="onCancel()">Cancel</button>
                </div>
            </div>
            <div class="row">
                <div class="col-xs-12">
                    <div class="form-group">
                        <label for="name">Name</label>
                        <input  type="text" id="name" formControlName="name" class="form-control">
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-xs-12">
                    <div class="form-group">
                        <label for="imagePath">Image URL</label>
                        <input type="text"  id="imagePath"  formControlName="imagePath" class="form-control" #imagePath>
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-xs-12">
                    <img [src]="imagePath.value" class="img-responsive">
                </div>
            </div>
            <div class="row">
                <div class="col-xs-12">
                    <div class="form-group">
                        <label for="description">Description</label>
                        <textarea  type="text"  id="description" class="form-control"  formControlName="description" rows="6"></textarea>
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-xs-12" formArrayName="ingredients">
                    <div class="row"   *ngFor="let ingredientCtrl of recipeForm.get('ingredients').controls; let i = index" [formGroupName]="i" style="margin-top: 10px;">
                        <div class="col-xs-8">
                            <input  type="text"   class="form-control" formControlName="name">
                        </div>
                        <div class="col-xs-2">
                            <input       type="number" class="form-control" formControlName="amount">
                        </div>
                        <div class="col-xs-2">
                            <button   type="button"   class="btn btn-danger" (click)="onDeleteIngredient(i)">X
                            </button>
                        </div>
                    </div>
                    <hr>
                    <div class="row">
                        <div class="col-xs-12">
                            <button   type="button" class="btn btn-success"  (click)="onAddIngredient()">Add Ingredient
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>

Comments

Popular posts from this blog

Recursive query in Laravel

<?php /** * Created by PhpStorm. * User: Zafar Hayat * Date: 6/26/2020 * Time: 7:06 PM */ namespace App\Services; use Illuminate\Support\Facades\DB; class FileWithDeepSearch { /** * @var PHPFunction */ private $PHPFunction ; /** * @var Common */ private $common ; /** * @var Filters */ private $filters ; public function __construct( PHPFunction $PHPFunction , Common $common , Filters $filters ) { $this -> PHPFunction = $PHPFunction ; $this -> common = $common ; $this -> filters = $filters ; } public function getQuery( array $data ) { $currentDirectoryFilesQuery = $this ->getCurrentDirectoryFilesQuery( $data ); $recursiveQuery = $this ->getRecursiveQuery( $data ); $recursiveQuery = $recursiveQuery ->unionAll( $currentDirectoryFilesQuery ); return $recursiveQuery ; } private function getCurrentDire...

How To Update PHP In XAMPP

 downloaded the version of PHP that I wanted (7.1.17) and then I strategically replaced the one I had in XAMPP with it. Here are the steps I followed. Download your desired PHP binary from  here . Make sure you download the same build type as your current version. If you don’t know what this is, go ahead and download an  x86 Thread Safe  version since most XAMPP installations have that build. In my case, I downloaded the 7.1.17 VC14 x86 Thread Safe  build. Extract the contents of the Zip file. Create a backup of your current  xampp/php  folder. I called mine php-backup7.1.2 Still inside /xampp, create a new php folder, then copy the contents of the extracted zip file into it. If you have custom configurations in the php.ini file, copy and replace it from your old php folder to the new one. If you didn’t previoisly edit the your php.ini, then skip this step. In my case I had previously installed drivers for sql server and defined them in my php....

Jmeter

JMeter Advantages Open source license : JMeter is totally free,  allows developer use the source code for the development Friendly GUI : JMeter is extremely easy to use and doesn't take time to get familiar with it Platform independent : JMeter is 100% pure Java desktop application. So it can run on multiple platforms Full multithreading framework . JMeter allows concurrent and simultaneous sampling of different functions by a separate thread group Visualize Test Result:  Test result can be displayed in a different format such as chart, table, tree and log file Easy installation : You just copy and run the *.bat file to run JMeter. No installation needed. Highly Extensible : You can write your own tests. JMeter also supports visualization plugins allow you to extend your testing Multiple testing strategy : JMeter supports many testing strategies such as  Load Testing , Distributed Testing, and  Functional Testing . Simulation : JMeter can simulate mul...