Adding onBlur validation for radio buttons and checkboxes in Angular Material UI

Currently, I am working on implementing checkboxes and radio buttons using Angular Material UI. My main issue lies in achieving the desired red outline effect when a required field is left unselected by the user. Even after applying the necessary 'requiredTrue' validator, this functionality doesn't seem to work as expected. Here's a snippet of the HTML code:

    <div>
        @for (i of checkboxValues; track i){
            <mat-checkbox 
                [value]="i.key"
                [checked]="i.selected"             
            >
                {{i.value}}
            </mat-checkbox>
        }
    </div>
<mat-radio-group [formControl]="radioFormControl">
    @for (i of radioValues; track i){        
        <mat-radio-button 
            [value]="opt" 
        >
            {{i.value}}
        </mat-radio-button>
    }
</mat-radio-group>

I attempted to encompass the <mat-option> and <mat-checkboxes> within a <mat-form-field> element but encountered an error message stating 'Error: mat-form-field must contain a MatFormFieldControl', which I have been unable to troubleshoot. As a newcomer to Angular, there might be something crucial that I'm overlooking.

Answer №1

If you're looking to add a red border using custom CSS, here's an example of how it can be done:

.mat-mdc-radio-group.ng-touched.ng-invalid {
  .mdc-radio__outer-circle {
    border-color: red !important;
  }
  .mdc-label {
    color: red;
  }
}

.mat-mdc-checkbox.ng-touched.ng-invalid {
  .mdc-checkbox__background {
    border-color: red !important;
  }
  .mdc-label {
    color: red !important;
  }
}

Keep in mind that adding a mandatory checkbox validation with a red border might not be the best user experience unless necessary. The code provided focuses on styling radio groups easily without using mat form field.

For the full implementation, refer to the HTML and TypeScript codes below:

HTML Code:

<form [formGroup]="form" (ngSubmit)="form.markAllAsTouched();">
  <mat-label>Enter your Selection</mat-label>
  <br />
  <mat-radio-group aria-label="Select an option" formControlName="radios">
    @for (item of radioValues; track item){
    <mat-radio-button [value]="item.id">{{item.label}}</mat-radio-button>
    }
  </mat-radio-group>
  <br />
  @if(form.get('radios'); as radio) { @if (radio?.touched &&
  radio?.errors?.required) {
  <mat-error>Selection is required</mat-error>
  } }
  <hr />
  <mat-label>Enter your Checkboxes</mat-label>
  @for (item of checkboxValues; track item){
  <mat-checkbox [value]="item.key" [formControlName]="item.value">
    {{item.value}}
  </mat-checkbox>
  }
  <hr />
  <br />
  <button type="submit">submit</button>
</form>

TypeScript Code:

import { Component } from '@angular/core';
import {
  FormControl,
  FormGroup,
  ReactiveFormsModule,
  Validators,
} from '@angular/forms';
import { MatRadioModule } from '@angular/material/radio';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatFormFieldModule } from '@angular/material/form-field';
import { CommonModule } from '@common';

/**
 * @title Basic radios
 */
@Component({
  selector: 'radio-overview-example',
  templateUrl: 'radio-overview-example.html',
  styleUrl: 'radio-overview-example.css',
  standalone: true,
  imports: [
    MatRadioModule,
    ReactiveFormsModule,
    MatCheckboxModule,
    CommonModule,
    MatFormFieldModule,
  ],
})
export class RadioOverviewExample {
  radioValues = [
    { id: 1, label: 'apple' },
    { id: 2, label: 'banana' },
  ];
  checkboxValues = [
    { key: 'apple', value: 'apple', selected: false },
    { key: 'banana', value: 'banana', selected: false },
    { key: 'orange', value: 'orange', selected: false },
  };
  form = new FormGroup({
    radios: new FormControl(null, Validators.required),
  });

  ngOnInit() {
    this.checkboxValues.forEach((item: any) => {
      this.form.addControl(
        item.value,
        new FormControl(null, Validators.required)
      );
    });
    // this.form.get('radios')!.markAsTouched();
    // this.form.get('radios')!.markAsDirty();
  }
}

To see the errors, simply click on the submit button!

Check out the Stackblitz Demo for more details.

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 generate an index.ts file in an Angular 14 shared library that exports all contents from a specific directory?

Utilizing Angular 14 for my shared library project, the structure looks like this: + projects + my-lib - package.json + src - public-api.ts + lib + helpers - index.ts ...

Displaying object properties in React and rendering them on the user interface

Within my React application, I am retrieving data from an API using the following code snippet: function PlayerPage() { interface PlayerDataType { id: number; handle: string; role: string; avatar: string; specialAbilities: null; s ...

A guide to incorporating dhtmlx scheduler into your Angular 4 project

Currently, I am utilizing dhtmlx scheduler to handle my events. While I was able to import the necessary js files successfully, I have encountered an issue when it comes to saving data in the database. My backend is built using Spring Boot framework. Can ...

Is it advisable to send an http request within the ngOnInit of an Angular Universal component?

During my Angular app development, I did not encounter any errors while running it via ng serve. However, when I switched to SSR (Server-Side Rendering), I started receiving an error in my server log whenever a component that makes an http request as part ...

Regardless of the chosen criteria displayed in the React.js | Material UI <Select> defect

I've been struggling to output the selected values using console.log, but I am receiving random results regardless of the value chosen. Can someone please assist me with this issue? Below is the code snippet: import React, { Component } from "react" ...

Installing a package using npm in the exact directory (both locally and in the package.json file)

I apologize for any simplicity in my question and if it seems repetitious. I am trying to add an external package, such as material-ui, as a dependency located at a specific path like ./node_module/my-material-ui. However, I have not been able to find a w ...

When uploading from Angular 2, PHP fails to populate the $_POST and $_FILES variables

I'm encountering difficulties when trying to upload files and data to my server using Angular 2 and PHP. After following the instructions in File Upload In Angular 2? to upload data and files from Angular 2, everything appears to be functioning corre ...

Managing MUI form fields using React

It seems like I may be overlooking the obvious, as I haven't come across any other posts addressing the specific issue I'm facing. My goal is to provide an end user with the ability to set a location for an object either by entering information i ...

encountering a problem integrating react-dropzone into a project using react-16.13.1

I'm having an issue adding the package https://www.npmjs.com/package/react-dropzone to my TypeScript React project using Yarn as the package manager. I ran the command yarn add @types/react-dropzone, but it ended up installing a deprecated package h ...

Tips for storing an array of ReplaySubjects in a single variable in an Angular application

I am looking to store several ReplaySubjects in a single array. Here is my code: public filteredSearch: ReplaySubject<any[]> = new ReplaySubject(1); this.filteredSearch[id].next(filter(somedata)); When I run this code, I encounter an error saying ...

Tips for making a oneOf field nullable using TypeScript and AJV

A field named platform exists in my code, and it can hold either a string or an array of strings (string[]). The field can also be nullable or undefined if not passed as input. TypeScript Interface export interface IEntityLeaderboardQuery { rank: stri ...

Guide to connecting data from the backend to the frontend in the select option feature using Angular 9

I have a backend system where I store a number representing a selected object, which I am trying to display in a select option using Angular. Currently, the select option only displays a list of items that I have predefined in my TypeScript code using enu ...

Guide: Populating an MUI Autocomplete TextField using data fetched from Axios

I have created a registration form for pets which includes an MUI Autocomplete component in the text field for selecting the pet type. However, I am facing an issue when trying to pre-fill the Autocomplete component with data from the database while edit ...

What is the best way to show nested labels on separate lines simultaneously?

Despite attempting to utilize the map method as suggested in my research, it appears that it may not be suitable for the structure I am working with: const stepLabels = [ { labels1: ['First One'] }, { labels2: ['Second One', 's ...

Error: Oops! The super expression can't be anything other than null or a function in JavaScript/TypeScript

I am facing an issue with class inheritance in my code. I have a class A that extends class B, which in turn extends class C. Whenever I try to create a new instance of class A within a function, I encounter the following error message: Uncaught TypeError: ...

Learn the steps to navigate the user to a different tab panel on the same page using ReactJS

I'm working on an authentication page with an <AppBar> that has two <TabPanel>s. After a user submits their information in the register tab, I want to automatically redirect them to the login tab. I've tried looking for a solution to ...

Submit numerous queries to verify the presence of a name and assign it to the name attribute

I have a collection of unique devices. As part of a process, I need to assign a default name to each device ("DeviceX" - where X is a sequential number), but some of the names may already be in use. To handle this, I must make a request to check ...

Exploring the intricacies of a specific Angular route through dialogue

Currently, I am working on enhancing the user experience by allowing data editing through dialogs. I have opted to move this functionality to a separate component so that it can read and edit the designated data efficiently without cluttering the main page ...

Guide to integrating a material ui component into a redux form Field

I am seeking a solution for wrapping a material ui component into the redux-form Field component. How can I achieve this? <FormControl variant='outlined' className={classes.textField}> <InputLabel ref={ref => ...

What is the reason behind not being able to perform a null check on an array entry in Typescript

I've got an array filled with objects that may be either null or a Gamepad: let devices: (Gamepad | null)[] = navigator.getGamepads() If the first item in the array happens to be a valid Gamepad, I need to perform a specific action: let device: Gam ...