Leveraging the power of mat-option and mat-radio-button within a mat-select or mat-selection-list

I'm currently working on a unique form element that combines checkboxes and radio buttons to create a multi-level selection feature.

For instance, you can use it to configure properties for a car where a radio option (Digital or FM) is dependent on the selection of another option (Radio):

  • [v] Stero
  • [v] Radio
  • ---(o) Digital
  • ---( ) FM
  • [ ] Child seats
  • [ ] Rear camera

The radio buttons should only be visible when the corresponding "parent" checkbox is selected, like in the case of the Radio option.

<mat-form-field>
  <mat-select [(value)]="viewValue" #multipleSelect (openedChange)="onMultipleChange($event, multipleSelect.selected)" multiple>
    <ng-container *ngFor="let property of carProperties">

      <!-- Display the property if it has no subProperties, otherwise show nested options -->
      <mat-option *ngIf="!property.subProperties; else nestedOption" [value]="property.value">
        {{property.value}}
      </mat-option>
      <ng-template #nestedOption>
        <mat-checkbox #parentOption>
          {{property.value}}
        </mat-checkbox>
        <ng-container *ngIf="parentOption.checked">
          <ng-template #radioOptions>
            <mat-radio-group (change)="radioChange($event)"> <!-- Not sure what the ngModel should be here -->
              <mat-radio-button *ngFor="let subProperty of property.subProperties" [value]="subProperty.value">
                {{subProperty.value}}
              </mat-radio-button>
            </mat-radio-group>
          </ng-template>
        </ng-container>
      </ng-template>
    </ng-container>
  </mat-select>
</mat-form-field>

I have managed to develop a solution but encounter an exception when selecting a radio button:

"Value must be an array in multiple-selection mode at getMatSelectNonArrayValueError (select.es5.js:116) at MatSelect.push.."

This issue seems to arise from how the mat-select component processes changes within its structure, particularly with respect to the placement of radio buttons. Can anyone provide guidance on structuring the mat components to achieve the desired functionality?

Answer №1

I believe a simpler approach could be taken to avoid over-complicating the code. Instead of relying on if-else statements, consider hiding or showing checkboxes based on sub-properties. Here is a more streamlined version that should achieve the desired outcome:

<mat-form-field>
    <mat-select [(value)]="viewValue" #multipleSelect multiple>
        <ng-container *ngFor="let property of carProperties">
            <mat-option [value]="property.value">
                {{ property.value }}
            </mat-option>
            <div *ngIf="property.subProperties && valueSelected(property.value)">
                <mat-radio-group>
                    <mat-radio-button *ngFor="let subProperty of property.subProperties"
                        [value]="subProperty.value"
                        style="display: block; padding: 12px 12px 12px 32px;">
                        {{ subProperty.value }}
                    </mat-radio-button>
                </mat-radio-group>
            </div>
        </ng-container>
    </mat-select>
</mat-form-field>

Furthermore, in the .ts file:

viewValue: string[] = [ ];
carProperties = [
    { value: 'Stereo' },
    { value: 'Radio',
      subProperties: [
        { value: 'Digital' },
        { value: 'FM' }
      ]
    }, { value: 'Child seats' },
    { value: 'Rear camera' }
];

valueSelected(value: string): boolean {
    return this.viewValue.indexOf(value) !== -1;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to troubleshoot substrings for accurately reading URLs from an object?

While a user inputs a URL, I am attempting to iterate through an object to avoid throwing an error message until a substring does not match the beginning of any of the URLs in my defined object. Object: export const urlStrings: { [key: string]: string } = ...

Steps to refresh a variable when the SMS read plugin successfully completes

I'm attempting to make a post call within the success callback of my SMS read plugin code. I can successfully print _this.otpnumber in the console. Please refer to my stack trace image link getSMS(){ var _this= this; var fil ...

What is the best way to solve the Hackerrank Binary Tree problem using TypeScript and output the

Here is the coding challenge from Hackerrank: Given a pointer to the root of a binary tree, you are required to display the level order traversal of the tree. In level-order traversal, nodes are visited level by level from left to right. Implement the fun ...

Using a unique Angular module in various projects: A step-by-step guide

I am looking to develop a shared module that will house components such as login, sidebar, as well as pipes, services, and directives. @NgModule({ declarations: [ AppComponent, LoginComponent, SidebarComponent, InitialsPipe ], import ...

Can a single shield protect every part of an Angular application?

I have configured my application in a way where most components are protected, but the main page "/" is still accessible to users. I am looking for a solution that would automatically redirect unauthenticated users to "/login" without having to make every ...

Incorporating a new attribute into the JQueryStatic interface

I am trying to enhance the JQueryStatic interface by adding a new property called someString, which I intend to access using $.someString. Within my index.ts file, I have defined the following code: interface JQueryStatic { someString: string; } $.s ...

Struggling with parsing JSON in TypeScript/React because of type issues

Upon receiving an API response, I would like to parse the data since it is in the form of an array of objects. Here's an example of how the JSON looks: { "totalSize": "56", "sortedKeys": [ { & ...

Having trouble upgrading to the newest version of angular-cli on my Ubuntu 14.04 system

I'm currently in the process of updating my angular-cli version by running: npm install -g <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="70111e17051c11025d131c11025d14">[email protected]</a> However, I enco ...

Angular2 fire fails because the namespace 'firebase' does not export the member 'Promise'

I recently set up Angular 2 Fire on my project. "angularfire2": "^5.0.0-rc.0", Now, in my root module (app module), I have the following setup: export const firebaseConfig = { apiKey: "mykey", authDomain: "....", databaseURL: "...", projectId: ...

The error message encountered while using webpack with TypeScript and React is: "Unexpected token React.Component

I am currently working on setting up a project using webpack, typescript, and react. I have implemented babel to transpile my typscript/react code. However, when starting the development server, I encountered the following error: Module parse failed: Un ...

Preventing angular router events from being logged in the console

In the process of developing an angular application, I have encountered a challenge with the {RouterModule} from @angular/router. Although I rely on console.log to troubleshoot my app, the router module has unleashed a flurry of router events in the conso ...

I am experiencing an issue with mydaterangepicker and primeng where it is not displaying properly in the table header. Can anyone assist me with this

I am attempting to integrate mydaterangepicker () with primeng turbotable (since primeng calendar does not meet the requirements), but I am having trouble with its display. Could you please assist me with some CSS code or suggest an alternative solution? ...

Generating a fresh array based on the size of its existing elements is the key feature of the ForEach method

When running this forEach loop in the console, it extracts the property "monto_gasto" from an array of objects in the firebase database. Here's how it looks: something.subscribe(res => { this.ingresos = res; ...

I'm experiencing an issue with my Next.js Airbnb-inspired platform where I am unable to save a listing to my favorites

While working on my Next.js Airbnb clone project, I encountered an issue with adding a Listing to favorites. The heart button component's color does not change when clicked, despite receiving a success response. Moreover, the addition to favorites is ...

Struggling to apply custom styles to ng-content? Find out why the ::ng-deep selector

Attempting to customize the appearance of elements inside <ng-content> within anuglar2 <au-fa-input > <input type="text" class="form-control" placeholder="email" #input> </au-fa-input> In the CSS of the au-fa-input component, ...

How can we utilize caching for an HTTP GET request in Angular 9 only when the navigator is offline?

My Angular 9 application utilizes http.get calls to communicate with an API, and I have integrated angular-pwa for offline capabilities. One challenge I am facing is ensuring that when the browser is online, two specific requests do not use cached respons ...

Getting into nested information in a JSON string using TypeScript

I need help accessing the data values (data1, data2, and date) from this JSON structure. I would like to store these values in an array that can be sorted by date: { "07" : { "07" : { "data1" : "-1", "data2" : "test", "date" : "1995-07-07" ...

Guide on displaying tooltip messages for a custom directive in Visual Studio Code

I have developed a custom directive called app-subscriber. When I hover the mouse over it, I want to display a tooltip message saying "This is for subscribers and requires an email address". Is this achievable? Do I need to create a new VS Code extension f ...

Replacing the previous observation

My events app features an all-events component that showcases all the events created. Upon loading the all-events component, the events are fetched from the database. Below is a snippet of the relevant code from the Typescript file of the all-events compo ...

Having trouble using the Aceternity interface as it keeps giving me a type error

I am facing an issue when trying to integrate the Acternity UI component library with nextjs. The error message I keep encountering is: "Property 'pathLengths' is missing in type '{}' but required in type '{ pathLengths: MotionValu ...