Angular exercise with a few task

Viewed 45

I'm trying to solve an angular exercise with the following tasks:

/* MODIFY THE CODE TO ACCOMPLISH THE FOLLOWING

  1. Enable the Band Name field if all the other fields are filled out
  2. Modify the bandName() validator to only be valid if the following rules are met a) The band name must start with the first letter of of the First Name field b) The band name must contain the age
  3. The background of Band Name must be the appropriate color which corresponds to the department
  4. Modify the template to restrict age input to only a number */

I kinda got stuck on a very early stage, for some reason i don't get there is no communication at all between the logic and the view component since i'm not able to console log any of the form group attributes. this is the first time i'm working with the form builder group and i'm not really familiar with it. Thanks for everyone. this is my code:

Script:

import { Component, OnInit } from '@angular/core';
import {
  FormBuilder,
  FormGroup,
  Validators,
  ValidatorFn,
  AbstractControl,
} from '@angular/forms';
@Component({
  selector: 'app-quiz',
  templateUrl: './quiz.component.html',
  styleUrls: ['./quiz.component.css']
})
export class QuizComponent implements OnInit {

  colorAssociation = {
    Technology: 'lightblue',
    Design: 'lightgreen',
    Education: 'purple'
  };

  form: FormGroup;
  bandNameForm: FormGroup;
  constructor(private formBuilder: FormBuilder) {}

  getBackgroundColor() {
    let color = '';
    if (this.form) {
      let dept = this.form.value.department;
      if (dept) {
        color=this.colorAssociation[dept];
      }
    }
    return color;
  }


  ngOnInit() {
    this.form = this.formBuilder.group({
      firstName: ['', Validators.required],
      age: ['', Validators.required],
      department: ['', Validators.required],
    });
    this.bandNameForm = this.formBuilder.group({
      bandName: ['', bandName(this.form)],
    });
    this.form.setValidators(areTheFieldsFilledOut(this.bandNameForm,this.form));
    this.bandNameForm.controls.bandName.disable();
  }


}

export function bandName(form: FormGroup): ValidatorFn {
  return (control: AbstractControl): { [key: string]: any } | null => {
    let error = 'Invalid';
    let value = control.value;
    let firstLetter = '';
    let age;
    if (form) {
      let firstName = form.value.firstName;
      age = form.value.age;
      console.log(value);

      if (firstName) {
        firstLetter = firstName[0];
      }
      if (value.indexOf(firstLetter)===0 && value.includes(age)) {
        error=null;
      }
    }
    // fill out the rest of the validator logic
    return error ? { error: { value: error } } : null;
  };
}


export function areTheFieldsFilledOut(bandNameForm: FormGroup, form:FormGroup): ValidatorFn {
  return (control:AbstractControl): { [key: string]: any } | null => {
    let error = 'Invalid';
    
    if (
      !(form.value.age === '') &&
      !(form.value.department === '') &&
      !(form.value.firstname === '')
    ) {
      bandNameForm.controls.bandName.enable();
    }
    return error ? { error: { value: error } } : null;
  };


}

Template:

<form [formGroup]="form">
        
    <label for="firstName">First Name
        <input type="text"
        formControlName="firstName"
        >
    </label>
    <label for="age">age
        <input type="number"
        formControlName="age"
        >
    </label>
    <br><br>
    <h4>Department:</h4>
    <br><br>
    <p>
        <label>
            <input formControlName="department" value="technology" type="radio">
            <span>Technology</span>
        </label>
    </p>
    <p>
        <label>
            <input formControlName="department" value="education" type="radio" />
            <span>Education</span>
        </label>
    </p>
     <p>
        <label>
            <input formControlName="department" value="design" type="radio"  />
            <span>Design</span>
        </label>
    </p>
    <br><br>

    <form [formGroup]="bandNameForm">
        <label>
            <input type="text" formControlName="band">
            <span>Band Name</span>
        </label>

    </form>
    <br><br>
        
    <button type="submit" class="waves-effect waves-light btn">Submit</button>

</form>
1 Answers

Minor Mistake

All I had to change was the formControlName for the bandNameForm in the template (band -> bandName). It has to match the name of the FormControl in the FormGroup.

Template:

<input type="text" formControlName="bandName" />

Disabling Submit

Template:

[disabled]="!bandNameForm.valid"

Dynamic Background Color

Template:

[ngStyle]="getBGC()"

Script:

getBGC() {
    const dep = this.form.get('department').value
    return { 'backgroundColor' : this.colorAssociation[dep] }
}

* I also changed the object holding the color values to not start with a capital letter (to match the names in the FormGroup).

Here's a Stackblitz that prints the values when pressing submit. I'll leave the actual exercise to you until you get stuck.

Related