Héctor Iglesias
Héctor Iglesias

Reputation: 51

How to display a select component underneath a checked checkbox in a selection list in Angular?

I'm trying to display a select item underneath a checkbox in Angular, which is included in a selection list:

<mat-selection-list>
    <mat-list-option 
        *ngFor="let checkbox of checkboxes" 
        color="primary" 
        checkboxPosition="before"
        [value]="checkbox" 
        [selected]="isCheckboxChecked(checkbox)" 
        (click)="changeCheckboxState(checkbox)"
    >
        <span class="extense-text">{{ checkbox.label }}</span>

        <div *ngIf="checkbox.label === 'Checkbox 3'">
        <mat-form-field>
            <mat-label>Choose an option</mat-label>
            <mat-select [(value)]="selectedOption" (selectionChange)="selectOption($event.value)">
                <mat-option *ngFor="let option of options" [value]="option">
                    {{option}}
                </mat-option>
            </mat-select>
        </mat-form-field>
        </div>
    </mat-list-option>
</mat-selection-list>

However, this is how it looks: Wrong behaviour

I can also set the select component at the bottom, but it doesn't seem natural to me:

<mat-selection-list>
    <mat-list-option 
        *ngFor="let checkbox of checkboxes" 
        color="primary" 
        checkboxPosition="before"
        [value]="checkbox" 
        [selected]="isCheckboxChecked(checkbox)" 
        (click)="changeCheckboxState(checkbox)"
    >
        <span class="extense-text">{{ checkbox.label }}</span>
    </mat-list-option>
</mat-selection-list>

<div *ngFor="let checkbox of checkboxes">
    <div *ngIf="checkbox.label === 'Checkbox 3'">
        <mat-form-field>
            <mat-label>Choose an option</mat-label>
            <mat-select [(value)]="selectedOption" (selectionChange)="selectOption($event.value)">
                <mat-option *ngFor="let option of options" [value]="option">
                    {{option}}
                </mat-option>
            </mat-select>
        </mat-form-field>
    </div>
</div>

Not what I pretend to do

Is there any way to do what I'm looking for? Thanks!

Upvotes: 1

Views: 41

Answers (1)

Naren Murali
Naren Murali

Reputation: 56054

We can use the below CSS, to make the options take the height of the children.

.custom-list-select {
  mat-list-option {
    height: 100% !important;
  }
}

Also we can use the <mat-form-field (click)="$event.stopImmediatePropagation()"> from bubbling up the events to trigger the checkbox selection, when the select is operated.

Full Code:

HTML:

<mat-selection-list class="custom-list-select">
  <mat-list-option
    *ngFor="let checkbox of checkboxes"
    color="primary"
    checkboxPosition="before"
    [value]="checkbox"
    [selected]="isCheckboxChecked(checkbox)"
    (click)="changeCheckboxState(checkbox)"
  >
    <span class="extense-text">{{ checkbox.label }}</span>

    <div *ngIf="checkbox.label === 'Checkbox 3'">
      <mat-form-field (click)="$event.stopImmediatePropagation()">
        <mat-label>Choose an option</mat-label>
        <mat-select
          [(value)]="selectedOption"
          (selectionChange)="selectOption($event.value)"
        >
          <mat-option *ngFor="let option of options" [value]="option">
            {{option}}
          </mat-option>
        </mat-select>
      </mat-form-field>
    </div>
  </mat-list-option>
</mat-selection-list>

TS:

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatListModule } from '@angular/material/list';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';

/**
 * @title Basic list
 */
@Component({
  selector: 'list-overview-example',
  templateUrl: 'list-overview-example.html',
  standalone: true,
  imports: [MatListModule, MatFormFieldModule, MatSelectModule, CommonModule],
})
export class ListOverviewExample {
  options = ['asdf', 'qwer', 'zxcv'];
  checkboxes = [
    { label: 'Checkbox 1' },
    { label: 'Checkbox 2' },
    { label: 'Checkbox 3' },
    { label: 'Checkbox 4' },
    { label: 'Checkbox 5' },
    { label: 'Checkbox 6' },
    { label: 'Checkbox 7' },
  ];
  selectedOption = '';

  isCheckboxChecked(item: any) {
    return item.checked;
  }

  changeCheckboxState(item: any) {
    item.checked = !item.checked;
  }

  selectOption(value: any) {}
}

Stackblitz Demo

Upvotes: 1

Related Questions