arraysangularlistformsangular-ngmodel

Creating customer form list array which can be clicked on to edit or delete


im currently working on a small task which is essentially a customer form where users can submit data and the data is then stored in an array and presented as a list.

I have managed to complete the form and i can submit data into an array and output it into a list. i am know trying to figure out how i can then click on the data in the list and have the data re-populate the fields in the form and for me then to edit or delete.

i have searched online for "clickable lists" and "actionable lists" but there doesnt seem to be anything i can use as it is all static. i have seen someone use a button in the list but that also doesnt work as all my data is then added to one big button. i have come across material UI but i would prefer to do it without using a library.

i have attached my code below:

contacts.component.html:

    <!-- <p>contacts works!</p> -->

    <div class="main">
        <!-- <input type="text" class="inputSearch" placeholder="search"> -->
        <label for="name" class="nameLbl">Name</label>
        <ul>
            <li *ngFor="let contact of contacts">{{contact.firstName}}</li>
        </ul>
    </div>

    <form #add="ngForm" (ngSubmit)="addContact(add) ; add.resetForm()">


        <div class="form-group">
            <label for="text">First Name</label>
            <input class="inpt" type="text" id="text" name="firstName" ngModel />
        </div>
        <div class="form-group">
            <label for="text">Last Name</label>
            <input class="inpt" type="text" id="text" name="lastName" ngModel />
        </div>
        <div class="form-group">
            <label for="text">Email</label>
            <input class="inpt" type="email" id="text" name="email" ngModel />
        </div>
        <div class="form-group">
            <label for="text">Address 1</label>
            <input class="inpt" type="text" id="text" name="address1" ngModel />
        </div>
        <div class="form-group">
            <label for="text">Address 2</label>
            <input class="inpt" type="text" id="text" name="address2" ngModel />
        </div>
        <div class="form-group">
            <label for="text">City</label>
            <input class="inpt" type="text" id="text" name="city" ngModel />
        </div>
        <div class="form-group">
            <label for="text">PostCode</label>
            <input class="inpt" type="text" id="text" name="postcode" ngModel />
        </div>
        <div class="form-group">
            <label for="text">Telephone</label>
            <input class="inpt" type="number" id="text" name="telephone" ngModel />
        </div>

        <br>
        <button class="addContactBtn">Add Contact</button>
    </form>

</div>```


contacts.component.ts:

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-contacts',
      templateUrl: './contacts.component.html',
      styleUrls: ['./contacts.component.css']
    })
    export class ContactsComponent {
    
      contacts: any = []
    
    
    
      addContact(add: any) {
        console.log("Contact Added", add);
        this.contacts.push(add.value)
        console.log(this.contacts);
        
      }
    
    
    }


Solution

  • app.component.ts

    import { Component, OnInit } from '@angular/core';
    import {
      FormBuilder,
      FormControl,
      FormGroup,
      Validators,
    } from '@angular/forms';
    
    import { emailValidator } from './email-validator.directive';
    
    interface Contact {
      firstName: string;
      lastName: string;
      email: string;
      address1: string;
      address2: string;
      city: string;
      zipCode: string;
    }
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss'],
    })
    export class AppComponent implements OnInit {
      fg!: FormGroup;
    
      contacts: Contact[] = [
        {
          firstName: 'Test',
          lastName: 'Test',
          email: 't@tt.com',
          address1: 'test',
          address2: 'test',
          city: 'test',
          zipCode: '123',
        },
      ];
    
      get firstNameField(): FormControl {
        return this.fg.get('firstName') as FormControl;
      }
    
      get lastNameField(): FormControl {
        return this.fg.get('lastName') as FormControl;
      }
    
      get emailField(): FormControl {
        return this.fg.get('email') as FormControl;
      }
    
      get address1Field(): FormControl {
        return this.fg.get('address1') as FormControl;
      }
    
      get address2Field(): FormControl {
        return this.fg.get('address2') as FormControl;
      }
    
      get zipCodeField(): FormControl {
        return this.fg.get('zipCode') as FormControl;
      }
    
      constructor(private fb: FormBuilder) {}
    
      ngOnInit(): void {
        this.initForm();
      }
    
      initForm(): void {
        this.fg = this.fb.group({
          firstName: ['', [Validators.required]],
          lastName: ['', [Validators.required]],
          email: ['', [Validators.required, Validators.email]],
          address1: ['', [Validators.required]],
          address2: ['', [Validators.required]],
          city: ['', [Validators.required]],
          zipCode: ['', [Validators.required]],
        });
      }
    
      saveContact(): void {
        console.log(this.fg);
        if (this.fg.valid) {
          this.contacts.push(this.fg.value);
          this.fg.reset();
        }
      }
    
      edit(index: number): void {
        const data = this.contacts[index];
        this.fg.patchValue(data);
      }
    
      delete(index: number): void {
        this.contacts.splice(index, 1);
      }
    }
    

    app.component.html

    <form [formGroup]="fg">
      <label for="firstName">First Name:</label>
      <input
        type="text"
        class="form-control"
        formControlName="firstName"
        placeholder="First Name"
      />
    
      <label for="lastName">Last Name:</label>
      <input
        type="text"
        class="form-control"
        formControlName="lastName"
        placeholder="Last Name"
      />
    
      <label for="email">Email:</label>
      <input
        type="email"
        class="form-control"
        formControlName="email"
        placeholder="Email"
      />
    
      <label for="address1">Address1:</label>
      <input
        type="text"
        class="form-control"
        formControlName="address1"
        placeholder="Address1"
      />
    
      <label for="address2">Address2:</label>
      <input
        type="text"
        class="form-control"
        formControlName="address2"
        placeholder="Address2"
      />
    
      <label for="address2">City:</label>
      <input
        type="text"
        class="form-control"
        formControlName="city"
        placeholder="City"
      />
    
      <label for="address1">Zip Code:</label>
      <input
        type="text"
        class="form-control"
        formControlName="zipCode"
        placeholder="Zip Code"
      />
    
      <button (click)="saveContact()">Save</button>
    </form>
    
    <div style="padding:1rem">
      <ul>
        <li *ngFor="let contact of contacts; let i = index">
          <p>First Name: {{ contact.firstName }}</p>
          <p>Last Name: {{ contact.lastName }}</p>
          <button (click)="edit(i)">Edit</button>
          <button (click)="delete(i)">Delete</button>
        </li>
      </ul>
    </div>
    

    the working example is here