简体   繁体   中英

How to make specific <div> show if checkbox with specific name is checked off?

I have an Angular Material Stepper element, and the first <mat-step> contains a list of checkboxes for the user to check.

The following is the first <mat-step> with the checkboxes:

<mat-step [stepControl]="itemCheckboxes">
  <ng-template matStepLabel>Select The Items You Want</ng-template>
  <span *ngIf="items.length === 0">No items currently in your account.</span>
  <ul style="list-style-type:none; padding-left: 0px;">
    <li *ngFor="let item of items">
      <mat-checkbox (change)="onCheckboxChange($event, item.name)">{{ item.name }}</mat-checkbox>
    </li>
  </ul>
  <div>
    <button mat-button matStepperNext>Next</button>
  </div>
</mat-step>

I'm trying to make a specific <div> show in a following <mat-step> , only if checkboxes with specific {{item.name}} s are checked.

For example, if the user checks a checkbox named "Banana", then the specific <div> related to the checked "Banana" checkbox would show. And if the user checks a checkbox named "Apple", then a different <div> would show.

How would I write the code to achieve this? I am trying to edit an existing project, and I am very new to coding, but I need to get this done quickly, so step-by-step details would be much appreciated. Thank you!

You need understand "Angular philosophy". Angular correlation the variables in .ts (the model) with the elements in html (the view)

So if you declare a variable

myvariable:boolean=true

And you checkbox is

 <mat-checkbox [(ngModel)]="myvariable">Banana</mat-checkbox>

The [(ngModel)] relation in two direction -binding two ways- the variable and the check-box. If you check the checkbox, the variable becomes true, if you uncheck the chackbox, the variable becomes false.

So you can write in anywhere

<div *ngIf="myvariable">
   If you see this is because the checkbox is true
</div>

Well you has an array of "items", so if you make a binding -use [(ngModel)] to a variable

 <mat-checkbox [(ngModel)]="item.checked">{{ item.name }}</mat-checkbox>

You can write

<div *ngIf="items[0].checked">
   You check the first element of the list before
</div>

Update if we want to know if "Banana" is checked

Well, I suppose we has an array of object

items=[{name:"Banana"},{name:"apple"},{name:"orange"}...]

When checked one or more we convert the array in some like

items=[{name:"Banana",checked:true},{name:"apple"},{name:"Orange",checked:false}...]

See that one or more elements can has no property "checked"

a function like

isSelect(fruit:string)
{
    return this.items.find(x=>x.checked && x.name==fruit)!=null
}

return true or false. Now you has several options:

1.-Using a getter

get isBananaSelected()
{
    return this.isSelect("Banana")
}

And use in ngIf

   <div *ngIf="isBananaSelected">...</div>

2.-Use an auxiliar variable that calcule when the stepper change the step

<mat-horizontal-stepper (selectionChange)="selectionChange($event)">

isVisibleDiv:boolean=false //and auxiliar variable
selectionChange(event)
{
  if (event.selectedIndex==1){ //remember the index is 0 for the first step, 1 for the second...
      this.isVisibleDiv=this.isSelect("Banana")
  }
}

//and 
<div *ngIf="isVisibleDiv">...</div>

3.-Use an auxiliar variable and call the function each change in a select

<mat-checkbox (change)="isVisibleDiv=this.isSelect("Banana")">

NOTE: It's looks like that a getter is the best bet, but be carefull, a getter is executed several times, the second option only execute when change the step and the third option executed each change in any check-box. (really for simplex functions -like in this case- you has not note a better or worst performance), but we need choose between simply and performance

You can use ng-template & ngTemplateOutlet . Here is the DEMO . The example shown only the showing of the template. When checkbox is unchecked the template reference can be removed from the array

import {
  Component,
  TemplateRef,
  VERSION,
  ViewChild
} from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  templates = [];
  items = [{
      name: "Banana"
    },
    {
      name: "Apple"
    },
    {
      name: "Orange"
    },
    {
      name: "Brinjal"
    }
  ];
  @ViewChild("Banana") Banana: TemplateRef < any > ;
  @ViewChild("Apple") Apple: TemplateRef < any > ;
  @ViewChild("Orange") Orange: TemplateRef < any > ;
  @ViewChild("Brinjal") Brinjal: TemplateRef < any > ;
  onCheckboxChange(event, name) {
    this.templates.push(this[name]);
  }
}
<ng-template matStepLabel>Select The Items You Want</ng-template>
<span *ngIf="items.length === 0">No items currently in your account.</span>
<ul style="list-style-type:none; padding-left: 0px;">
  <li *ngFor="let item of items">
    <mat-checkbox (change)="onCheckboxChange($event, item.name)">{{ item.name }}</mat-checkbox>
  </li>
</ul>
<div>
  <button mat-button matStepperNext>Next</button>
</div>

<div *ngFor="let tmpl of templates">
  <ng-container [ngTemplateOutlet]="tmpl"></ng-container>
</div>


<ng-template #Banana>
  <span>Banana</span></ng-template>

<ng-template #Apple>
  <span>Apple</span></ng-template>

<ng-template #Orange>
  <span>Orange</span></ng-template>

<ng-template #Brinjal>
  <span>Brinjal</span></ng-template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM