Search code examples
htmlangularangular-materialangular-reactive-formsangular-forms

How to change content in a div dynamically via radio button control?


I am trying to build a form that will intake scheduling information that can potentially come in multiple different formats (weekly, monthly, other). I was planning on having a schedule section of the form where the user selects the type of schedule via a radio button group. If the weekly option is chosen, a group of checkboxes will appear with weekdays so you can select the days of the week. if monthly, then the day of the month can be chosen, and so on. I have tried using the *ngIf way of making things appear, and it isn't working, and I'm getting no error messages. Any ideas on how to implement this?

I am using: -Angular material elements -Angular 2 (8) -Angular reactive forms

I have a portion of this implemented already, below is the code for the radio buttons and the first schedule portion I want to hide (apologies for the poor formatting of the code, still figuring out Stack Overflow):

<form [formGroup] = "SchedInfo" (ngSubmit)="onSubmit()">

<mat-radio-group formControlName= "sType" (ngSubmit)= "onSubmit()">
<mat-radio-button type="radio"  [value] ="true" [checked] = "value">Weekly</mat-radio-button>
<mat-radio-button type="radio"  [value] ="false" [checked] = "!value">Monthly</mat-radio-button>
</mat-radio-group>

<div class = "weeklyS" *ngIf= "sType.value">
<br>
<!-- possibly need to resturcture the section below -->
<mat-checkbox formControlName= "mo">Monday</mat-checkbox>
<mat-checkbox formControlName= "tu">Tuesday</mat-checkbox>
<mat-checkbox formControlName= "we">Wednesday</mat-checkbox>
<mat-checkbox formControlName= "th">Thursday</mat-checkbox>
<mat-checkbox formControlName= "fr">Friday</mat-checkbox>
<mat-checkbox formControlName= "sa">Saturday</mat-checkbox>
<mat-checkbox formControlName= "su">Sunday</mat-checkbox>
</div>


In the end, my goal for this is to have a schedule module that can be switched between several different input methods.

Also:

should I have one div that is repopulated with each change of selection, or should I have multiple divs that show/ hide depending on the selection?


Solution

  • What you actually need to do is to bind the value of your radio correctly and how to get the value back. This was the simples example I could come up with.

    First our template code

    <form [formGroup]="myForm" (submit)="onSubmit(myForm.value)" novalidate>
        <label id="example-radio-group-label">Pick your Type</label>
    <mat-radio-group class="example-radio-group" formControlName="sType">
      <mat-radio-button class="example-radio-button" *ngFor="let sfType of scheduleTypes" [value]="sfType">
        {{sfType}}
      </mat-radio-button>
    </mat-radio-group>
    
    
    <ng-container [ngSwitch]="getScheduleType()">
    <div  *ngSwitchCase="'Weekly'">
      Weekly Content
    </div>
    <div *ngSwitchCase="'Monthly'">
      Monthly Content
    </div>
    </ng-container>
    
    </form>
    

    Now the component code:

       import { Component, OnChanges, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
    import { FormBuilder, FormGroup, Validators } from '@angular/forms';
    
    
    export interface DataModel {
      sType: string;
    }
    /**
     * @title Radios with ngModel
     */
    @Component({
      selector: 'radio-ng-model-example',
      templateUrl: 'radio-ng-model-example.html',
      styleUrls: ['radio-ng-model-example.css'],
    })
    export class RadioNgModelExample {
      myForm: FormGroup;
    
    //List of the schedule types. You might want to change this to an ENUM
      scheduleTypes: string[] = ['Weekly', 'Monthly'];
    
      constructor(private formBuilder: FormBuilder) {
        this.buildForm();
      }
    
    //Remember to build your form properly
      public buildForm() {
        this.myForm = this.formBuilder.group({
          sType: [null]
        });
      }
    
      public onSubmit(data: DataModel) {
        //Submit Data Here
      }
    
      public getScheduleType() {
        //Get the value of your stypeControl
        return this.myForm.controls['sType'].value;
      }
    
    
    }
    

    Live Example