Learn how to dynamically disable unchecked checkboxes and apply specific CSS classes to checked checkboxes in Angular 12 with TypeScript

Currently, I am working on a project where I have successfully stored checkboxes dynamically using a JSON array of objects. However, I am facing an issue that requires your expertise. My goal is to allow the selection of only 5 checkboxes. Once this limit has been reached, I need to disable any unchecked checkboxes and apply specific CSS changes to those disabled checkboxes. I have attempted to implement this functionality but have encountered difficulties in changing the class of unselected checkboxes once the selection count hits 5.

<div class="pinnedtoolsbox" *ngFor="let item of menuList">
  <div>
    <div class="pinnedtoolbox-caption">
      
      <div>
      
        <img src="{{item.icon}}"/>
     
          
      </div>
      <div>
        <span>{{item.title}}</span>
     

      </div>
      
      </div>
  </div>

  

  <div  *ngFor="let sublist of item.submenus; let i=index" >
  
  <label [ngClass]="sublist.selected ? 'submenulist_label_checked': 'submenulist_label'">
   <div>
   <img [src]="sublist.selected ? 'assets/icons/listmenuiconwhite.svg': 'assets/icons/listicon.svg'"/>
   </div>
   <div>
    {{ sublist.menu }} 
    

    <input type="checkbox"
    [(ngModel)]="sublist.selected" 
    [disabled]="disableCheckbox(sublist)"  
    (change)="changeSelection($event, sublist)"
    
    style="display:none;">
   </div>
  
  </label>
  </div>

  </div>

component.ts file

private _jsonURL = 'assets/menus.json';

public getJSON(): Observable<any> {
 return this.http.get(this._jsonURL);
}   

[{"title":"one",
"submenus": [
    {
        "id":1, "menu": "home", "selected": false
    },
    {
        "id":2, "menu": "about", "selected": false
    },   
]
 
},

{"title":"two",
    
"submenus": [
    {
        "id":1, "menu": "Status", "selected": false
    },
    {
        "id":2, "menu": "Balance", "selected": false
    },
]
},
]


checkboxList = [];
public maxElementCheckbox = 5;


changeSelection($event, item){

if ($event.target.checked) {
 
  this.checkboxList.push(item);
 
 }

else {
  
  this.checkboxList.splice(this.checkboxList.indexOf(item), 1);
  console.log("esle part");
}
console.log(this.checkboxList);
}

 public disableCheckbox(id): boolean {

return this.checkboxList.length >= this.maxElementCheckbox && !this.checkboxList.includes(id);

}

Answer №1

I noticed that your ngClass doesn't have a condition to check unselected checkboxes after selecting 5 checkboxes. Here is a suggestion:

HTML:

<div class="pinnedtoolsbox" *ngFor="let item of menuList">
  <div *ngFor="let sublist of item.submenus; let i = index">
    <label
      [ngClass]="checkboxList.length >= maxElementCheckbox && !sublist.selected ? 'submenulist_label' : 'submenulist_label_checked'">
      <div>
        <input
          type="checkbox"
          [(ngModel)]="sublist.selected"
          [disabled]="disableCheckbox(sublist)"
          (change)="changeSelection($event, sublist)"/>
          <label>{{sublist.menu}}</label>
      </div>
    </label>
  </div>
</div>

TYPESCRIPT:

menuList = [
    {
      title: 'one',
      submenus: [
        {
          id: 1,
          menu: 'home',
          selected: false,
        },
        {
          id: 2,
          menu: 'about',
          selected: false,
        },
      ],
    },

    {
      title: 'two',

      submenus: [
        {
          id: 1,
          menu: 'Status',
          selected: false,
        },
        {
          id: 2,
          menu: 'Balance',
          selected: false,
        },
        {
          id: 3,
          menu: 'Test1',
          selected: false,
        },
        {
          id: 4,
          menu: 'Test2',
          selected: false,
        },
        {
          id: 5,
          menu: 'Test3',
          selected: false,
        },
      ],
    },
  ];

  checkboxList = [];
  public maxElementCheckbox = 5;

  changeSelection($event, item) {
    if ($event.target.checked) {
      this.checkboxList.push(item);
    } else {
      this.checkboxList.splice(this.checkboxList.indexOf(item), 1);
    }
  }

  public disableCheckbox(id): boolean {
    return (
      this.checkboxList.length >= this.maxElementCheckbox &&
      this.checkboxList.indexOf(id) == -1
    );
  }

CSS:

.submenulist_label {
  color: red;
}

Feel free to check out the live demo.

Answer №2

If you want the checkboxes to be disabled once the limit of 5 is reached, one option is to implement a counter in your changeSelection function and display an error message if the limit is exceeded.

Alternatively, you could use a selector to target all checkbox elements without an active attribute using .querySelectorAll('.specificClassForTheCheckboxes'), or give each checkbox a unique id to easily select them based on their selected attribute value of false.

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

The footer should remain at the bottom of the page without being permanently fixed

Is there a way to keep the bootstrap footer at the bottom without fixing it in place? In the code example below, the footer should always appear at the bottom. The white space after the footer should come before it. Using sticky-bottom achieves this, but ...

Convert my information to an XML document

Successfully, I have loaded the content of an XML file into my PHP document using the following method: $(document).ready(function () { $.ajax({ type: "GET", url: "abstimmer.xml", dataType: "xml", success: function ...

The process of transferring information from a JSON API to TypeScript models

When working with my JSON API in my services, I need to pass the data to my models. What is the most efficient way to accomplish this task? Currently, I am following this process: import { Attachment } from '.'; export class Contact { id: nu ...

What is the process for establishing Many-to-Many connections with personalized field titles using Bookshelf.js?

I am interested in setting up a many-to-many relationship using Bookshelf.js and I would like to customize the names for the foreign key columns. Additionally, I want to have access to the helper table in Bookshelf just like in the example below: var Phys ...

Step-by-step guide on generating a fluid list with Express and HTML

Looking to create a dynamic list by fetching data from a JSON file. I want the list items to redirect me to specific content based on their IDs when clicked. However, my current approach is not working as expected, and the list needs to be truly dynamic. ...

Ways to add parameters to each external URL using Angular

Seeking thoughts on implementing a feature in Angular to append a parameter to all external URLs or URLs from a specific domain. Let's take as an example. If I were using jQuery, I could achieve this on document ready by doing something like: $(‘ ...

socket.io initialization and finalization events

Currently, I am integrating socket.io with express 3 for my application development. I am interested in implementing loader animations that will appear when a message is incoming and disappear once the message has been received. Similar to how jQuery&apos ...

The user interface design transforms as a PDF file is being generated through html2pdf

I am experiencing an unusual problem while using html2pdf to convert an HTML page to a PDF file and download it. The conversion process is successful and the PDF file is downloaded without any issues. However, when I click on a button to generate the file, ...

It is possible that req.user may be undefined, especially when using express and passport.js

I am facing an issue with my Node.js TypeScript authentication system that utilizes passport. The problem arises when I attempt to access req.user in a specific route, resulting in the error message: Object is possibly 'undefined'. This behavio ...

Changing the InnerHTML of a tag in JavaScript using class and id attributes

When it comes to handling these links <div class="post_actions"> <a class="color-transition article_delete" href=""><i class="fa fa-pencil"></i></a> <a class="color-transition article_edit" href="#" id="1">< ...

The smooth scroll feature is not functioning properly on the animated mouse-scroll down button

I've recently added an Animated Mouse Scroll Down button on my website. However, when I click the button, the smooth scroll feature is not working as expected. Important Note: I already have a separate button for navigating to the next section where ...

How to use Angular 2 to communicate with JavaScript API whenever the router switches to

I am currently working on an Angular2 component that has a template which relies on JavaScript calls to load various components such as Facebook, Google Maps, and custom scripts. The necessary scripts are already loaded in the index.html file, so all I ne ...

Tips for including an element at the start while creating a map()

enum StatusEnum { accepted = "AC", rejected = "RJ", } const select = (Object.keys(StatusEnum) as Array<keyof typeof StatusEnum>).map((x) => ({ value: x, name: x + "_random", })) /** * Console.log(select) * [ ...

Issue with Yup and Formik not validating checkboxes as expected

I'm struggling to figure out why the validation isn't functioning as expected: export default function Check() { const label = { inputProps: { "aria-label": "termsOfService" } }; const formSchema = yup.object().shape({ ...

When you add a new library using npm and it has a dependency on another existing library, it could potentially cause conflicts or issues with

After successfully installing a library, I am now looking to install another library that relies on the first one. I have some uncertainty about what will occur: The second library will utilize the shared library already installed for its functionality ...

jQuery fails to hide DIVs when jQuery.show() has been utilized in a previous event

I've always considered myself pretty proficient in jQuery, but this particular issue has me stumped. Essentially, I have a click event that should hide one DIV (a placeholder) and show two others (an input section and control buttons section). However ...

Retrieving width and height of the content block inner in Framework7, excluding navbar and toolbar dimensions

Is there a reliable way to determine the width and height of the page content-block-inner, excluding the navbar and toolbar? This measurement can vary across different devices and operating systems. I attempted to assign an id to the content-block-inner a ...

Retrieving an assortment of objects from a database and showcasing them using React

Attempting to retrieve an array of objects led me to this issue. Please excuse the messy code, I am still learning. export class App extends Component { state ={ character:[] } componentDidMount(){ fetch('https://swapi.dev/api/people/ ...

Steps to include a data-xx attribute in the displayed <table> within a Vuetify 2 v-simple-table

I am facing an issue where I want to include an HTML data-xxxx attribute to the HTML <table> within a v-simple-table. However, when I add the data attribute to the <v-simple-table>, it ends up being placed in a surrounding div two levels above ...

Getting Rid of Angular Material Suggestions: A Step-by-Step Guide

<md-autocomplete ng-model="ctrl.searchText" md-selected-item="ctrl.selectedItem" md-selected-item-change="ctrl.selectedItemChange(item)" md-search-text="ctrl.searchText" md-search-text-change="ctrl.searchTextChange(ctrl.searchText)" ...