What is a creative way to design a mat-radio-group without traditional radio buttons?

I am looking to create a component that offers users a list of selections with the ability to make only one choice at a time. The mat-radio-group functionality seems to be the best fit for this, but I prefer not to display the actual radio button next to the labels within my group. I would like to extend the label to trigger any (change) event by clicking on the label itself.

What is the most elegant solution to remove the radio buttons from my radio group while maintaining the appearance of the labels?

Answer №1

If you want to create a unique custom form control, consider implementing a custom directive with an HTML structure like this:

<select-component [(ngModel)]="value">
    <div select value="1">One</div>
    <div select>Two</div>
</select-component>

To achieve this, we will create a directive with the selector [select]:

@Directive({
  selector: '[select]',
})
export class SelectDirective implements AfterViewInit {
  @Input('value') value:any;
  control:any;
  @HostBinding('class.selected') 
  get isSelected(){
    return this.control && this.control.value == this.value ? true : undefined;
  }
  @HostBinding('class.select') setClass() { return true; }
  @HostListener('click') onclick() {
    console.log(this.value);
    if (this.control)
      this.control.setValue(this.value);
  }
  constructor(private el: ElementRef) {}

  ngAfterViewInit() {
      this.value = this.value || this.el.nativeElement.innerHTML;
  }
}

In this code snippet, we assign a value to this.value in ngAfterViewInit if it is not previously defined. We also have two class bindings for styling purposes: one for the component and another when the div is selected.

The SelectComponent acts as a custom form control. In ngAfterViewInit, we link the directives inside it to communicate with the component:

@Component({
  selector: 'select-component',
  template: `<ng-content></ng-content>`,
   providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => SelectComponent),
      multi: true
    }

  ]
})
export class SelectComponent implements ControlValueAccessor, AfterViewInit {
  @ContentChildren(SelectDirective) selects: QueryList<SelectDirective>;
  value: any;
  disabled: boolean = false;
  onChange: any;
  onTouched: any;

  writeValue(value: any[] | any): void {
    this.value = value;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

  ngAfterViewInit() {
    this.selects.forEach(x => {
      x.control = this;
    });
  }

  setValue(value) {
    this.value = value;
    this.onChange(value);
  }
}

Check out the complete implementation on StackBlitz.

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

Show ng-message when email is invalid in Angular Material without using ng-pattern

I need to show an error message that says Please enter valid email. when an invalid email is entered, but I cannot use the ng-pattern attribute with this specific regex pattern. <md-input-container class="md-block" flex-gt-xs> <label>Ema ...

Exploring the world of CSS and designing layouts using multiple div elements

Upon reviewing this website, I must admit it is getting close to what I envision. However, being a perfectionist and new to HTML and CSS, I find myself struggling to achieve the desired outcome. The layout consists of two divs named topred and top yellow, ...

Error: Ionic 2 encountered an error: Highcharts has produced Error #17 - learn more at www.highcharts.com/errors/17

I'd like to incorporate a highchart gauge in my project, but I'm encountering an issue: Uncaught (in promise): Error: Highcharts error #17: www.highcharts.com/errors/17 error I've been advised to load the highcharts-more.js file, but I&a ...

Enhance user interactivity on your website by incorporating jQuery and CSS for

<table id="tab"> <tr aaa="one" bbb="ooo"><td>xxx</td><</tr> <tr aaa="two" bbb="one"><td>xxx</td><</tr> <tr aaa="three" bbb="one"><td>xxx</td><</tr> ...

What is the best way to transform the data stored in Observable<any> into a string using typescript?

Hey there, I'm just starting out with Angular and TypeScript. I want to get the value of an Observable as a string. How can this be achieved? The BmxComponent file export class BmxComponent { asyncString = this.httpService.getDataBmx(); curr ...

Develop a CSS layout for the specified design

Aiming to achieve a unique layout using dynamic html strings. The challenge arises when transitioning to the second page as the layout does not adjust upward and images cannot be added to the first page. Attempting to implement the following sample code ...

Limiting the size of textboxes in Twitter Bootstrap

I am currently working with bootstrap text boxes in the following manner: <div class="row"> <div class="col-lg-4"> <p> <label>Contact List</label> <select class="form-control" id="list" name="li ...

Troubleshooting problem with Z-Index conflict in Flash animation

I am facing an issue with two HTML divs - one containing a flash movie and the other simple text. I want to place the textual div on top of the flash movie div, but no matter how I set their positions in CSS or adjust their Z-Index values, the text keeps ...

Using Rails to assign a page-specific CSS class within a shared layout

Is there a way to apply unique CSS classes to specific tags within a common layout? In my application.html.erb layout file, the application.css.scss is loaded using <%= stylesheet_link_tag "application". . . %>, which then includes all CSS files in ...

The 'id' property is not found within the 'Order[]' type

Encountering a perplexing issue in my HTML where it keeps showing an error claiming that the 'id' property does not exist on type Order[] despite its clear existence The error message displayed: Property 'id' does not exist on type &ap ...

Tips for positioning an inline label and input field in an Angular application using CSS and HTML: How to align the label to the left and the input

I'm currently developing an Angular form with multiple label-input field combinations. I have managed to style the labels and input fields with inline block so that they appear on the same row. However, I am facing a challenge in aligning the label to ...

Unable to assign value to a public variable in Angular

I am facing an issue where I am trying to retrieve a value from the localStorage and assign it to a variable. However, when I try to use that variable in functions, it is coming up as undefined. code export class DashboardService { public token: any; ...

Detecting Changes in the Backend with Angular

I'm curious about the best way to notify the frontend when there is a change in the backend. How can this situation be effectively handled? While developing an application on Azure, I have considered two possibilities, but none of them seem ideal. The ...

A step-by-step guide for updating a minor version of Angular with Angular CLI

I've been searching online for the answer to this straightforward question, but can't seem to find it anywhere... In my angular 4 project (made with angular cli), I want to utilize the newly introduced http interceptors in version 4.3. Could so ...

Encrypt and decrypt your store with ngrx-store-localstorage

I am attempting to encrypt data stored using ngrx-store-localstorage, following the instructions provided in the documentation: import { ActionReducer, MetaReducer } from '@ngrx/store'; import { localStorageSync } from 'ngrx-store-localstor ...

What is the best way to format my JSON data as a table on the screen?

I need to display my data in a table format at the bottom of the screen, as shown in the screenshot below. Here is an example of the top part code: This code snippet is also used for movies. <View> <Text key={item.symbol}>{item.symbol}<Te ...

Disable the borders on HTML input fields

I am looking to implement a search feature on my website. It seems that in Firefox and Internet Explorer, the search function appears fine without any unexpected borders. Firefox IE However, when viewing the search function in Chrome and Safari, there ...

How to style tables in CSS with specific border spacing inside cells

I've been struggling with this issue for months now and even Google hasn't been able to provide a solution. My problem is that I want to add spacing between <td> and <th> tags in a table, but whenever I do, the spacing appears on the ...

I'm currently working on creating an online store using Next.js and TypeScript, but I'm struggling to effectively incorporate my fake product data array into the site

"using client" import Container from "@/components/Container"; import ProductDetails from "./ProductDetails"; import ListRating from "./ListRating"; import { products } from "@/utils/products"; interface I ...

Turning off the ability to horizontally scroll in an iframe using touch controls

I am trying to disable horizontal scrolling in an iframe on my website, particularly when a user uses touch input and drags horizontally. The scroll bars can still be visible and draggable when touched directly. Unfortunately, I do not have control over th ...