Skip to content

Latest commit

 

History

History
97 lines (84 loc) · 3.32 KB

step-10.md

File metadata and controls

97 lines (84 loc) · 3.32 KB

Quick Jump

Step 10 task:

If you've been following along up until now, you might have noticed that the user can edit any field in a talk, except for the tags. In this step we'll use the Angular Material chip list to make the list of tags editable.

To get started, we have to declare another mat-form-field inside the edit-talk component. The form field will contain a mat-chip-list with the talk's tags, as well as an input in which we can type our new tags.

edit-talk.component.html

...
<mat-form-field>
  <!-- Add the chip list and associate it with a new form control. -->
  <mat-chip-list #tags formControlName="tags">
    <!--
      Render out all the chips that are set to the form control.
      Also listen for the `removed` event which will notify use when to remove a tag.
    -->
    <mat-chip *ngFor="let tag of this.formGroup.get('tags').value" (removed)="removeTag(tag)">
      {{tag}}
      <!-- Add an icon that allows the user to delete a talk via click. -->
      <mat-icon matChipRemove>cancel</mat-icon>
    </mat-chip>

    <!--
      Input into which the user can type new tags. The `matChipInputTokenEnd` event will fire
      whenever the user presses enter or they focus outside the input.
    -->
    <input placeholder="Add tags"
            [matChipInputFor]="tags"
            (matChipInputTokenEnd)="addTag($event)" />
  </mat-chip-list>
</mat-form-field>
...

Now that we have our markup, we need to add the logic. We'll need a new form control which will keep track of the current chips, as well as two new event handlers: one when a chip is added and one when it's deleted. Note that we'll be editing the value of the FormControl associated with the tags, rather than the talk's tags directly. This allows us to automatically revert to the previous value, if the user decides to press "Cancel".

edit-talk.component.ts

import { MAT_DIALOG_DATA, MatDialogRef, MatChipInputEvent } from '@angular/material';

@Component()
export class EditTalkComponent {
  constructor(@Inject(MAT_DIALOG_DATA) public talk: Talk,
              private dialogRef: MatDialogRef<EditTalkComponent>,
              formBuilder: FormBuilder) {

    this.formGroup = formBuilder.group({
      ...
      tags: [talk.tags],
    });
  }

  removeTag(tag: string) {
    // Remove the tag from the tag control's value.
    const tagsControl = this.formGroup.get('tags');
    tagsControl.value.splice(tagsControl.value.indexOf(tag), 1);
  }

  addTag(event: MatChipInputEvent) {
    const tagsControl = this.formGroup.get('tags');

    // Create a new array of tags, if the talk doesn't have any,
    // otherwise add the new tag to the existing array.
    if (tagsControl.value) {
      tagsControl.value.push(event.value);
    } else {
      tagsControl.setValue([event.value]);
    }

    // Clear the input's value once the tag has been added.
    event.input.value = '';
  }
}

At this point we don't need any more logic, because of all the groundwork we set up in the previous steps. You can test out the new form field by pressing the "Edit" button on any of the talks and interacting with the mat-chip-list.