The process of removing an item from an array when a checkbox is deselected in Angular 4

I am currently working with an array of objects where each object contains another array.

panels = [{
  Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd",
  Name: "Celiac test",
  Tests: [{
      Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
      Name: "test 1 (DGP) IgG"
    },
    {
      Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
      Name: "test 2 (DGP) IgG"
    },
    {
      Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
      Name: "test 3 (DGP) IgG"
    }
  ]
}],

My goal is to create a bootstrap accordion with checkboxes based on this data structure.

The design requires a main checkbox for the object, followed by individual checkboxes for the array elements.

When I click the main Panel checkbox, it should also select all the Tests checkboxes and store the panel object in a variable called selectedPanel. Deselecting the main Panel should unselect all Tests checkboxes as well.

While I have accomplished this functionality, the main challenge lies in removing a Test checkbox from selectedPanel and updating its length when deselected.

If anyone can provide assistance with this issue, it would be greatly appreciated.

I have created a demo on Stackblitz:

Stackblitz

Answer №1

If you're looking for a solution, consider the following approach.

<ngb-accordion #acc="ngbAccordion">
  <ngb-panel *ngFor="let panel of panels; let i = index" id="{{panel.Id}}" [title]="panel.Name">
     <ng-template ngbPanelTitle>
        <span class="panel-length"><strong>{{panel.Tests.length}}</strong></span>

            <input type="checkbox" class="form-check-input ml-5" id="{{panel.Id}}" name="{{panel.Name}}">


      </ng-template>
    <ng-template ngbPanelContent>
    <div class="individual-panel" *ngFor="let test of panel.Tests, let j = index;">
          <span class="text-dimmed">{{test.Name}}</span>
            <input type="checkbox" class="form-check-input ml-5" id="{{test.Id}}" name="{{test.Name}}" (click)="checkItem(i, j)">  
        </div>
    </ng-template>
  </ngb-panel>
</ngb-accordion>

   <!-- <span class="panel-length"><strong>{{panels.Tests.length}}</strong></span> -->

TS

checkItem(i, j){
   this.panels[i].Tests.splice(j, 1);
   console.log(this.panels[i].Tests);
  }

This suggestion is provided in hopes that it may be of assistance to you.

Answer №2

If you want to see a quick demonstration, check out my Stackblitz demo HERE

In this demo, the parent checkbox controls the toggle of its child checkboxes, and each checkbox has a checked parameter to indicate which one is selected.

This setup simplifies the process of managing the state of each checkbox without having to manually manipulate them on every change.

Answer №3

Check out this Stackblitz example: https://stackblitz.com/edit/angular-bsszc9?file=src/app/app.component.ts

This code snippet serves as a quick illustration of a technique that could be utilized.

In the code, I have added an isShown property to the tests. It's important to refactor these tests into separate objects within their own module.

panels = [{
  CategoryId: "31b7a227-9fda-4d14-8e1f-1dee5beeccb4",
  Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd",
  Name: "Celiac test",
  Tests: [
  {Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 1 (DGP) IgG", 
   isShown: true },
  {
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 2 (DGP) IgG", 
   isShown: true },
  {
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 3 (DGP) IgG", 
   isShown: true}
]
},
{
  CategoryId: "31b7a227-9fda-4d14-8e1f-1dee5beeccb4",
  Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd",
  Name: "Comprehensive test",
  Tests: [
  {Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 1  (DGP) IgG"},
  {
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 2  (DGP) IgG"},
  {
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 3  (DGP) IgG"}
]
}]

Clicking the input box triggers a click event that sets the test.isShown property to false. The *ngIf directive will hide the test from being displayed. (Note: A new ng-container was introduced due to restrictions on using *ngFor and *ngIf in the same container).

<ng-container *ngFor="let test of panel.Tests">
  <div class="individual-panel" *ngIf='test.isShown'>
    <span class="text-dimmed">{{test.Name}}</span>
    <input type="checkbox" class="form-check-input ml-5" id="{{test.Id}}" name="{{test.Name}}" (click)="hide( test )" >   
  </div>
</ng-container>

The method below gets triggered by the click event. Alternatively, you could remove the test from the array (although this may not be recommended as it can affect data integrity);

hide( test ) {
  test.isShown = false;
}

This explanation aims to demonstrate a simple technique. For better maintainability, consider refactoring into smaller classes/modules. I hope this helps! ;)

Answer №4

To start, you must include an additional attribute in your panels and Tests arrays to keep track of the checkbox state. The structure of your panels array should look like this:

panels = [{
  Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd",
  Name: "Celiac test",
  checked: false,
  Tests: [{
      Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
      Name: "test 1 (DGP) IgG",
      checked: false
    },
    {
      Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
      Name: "test 2 (DGP) IgG",
      checked: false
    },
    {
      Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
      Name: "test 3 (DGP) IgG",
      checked: false
    }
  ]
}]

Next, you need to evaluate the checkbox value to determine if you want to include that specific test in your selectedPanel or not.

I assume that both your panels and Tests have a unique Id attribute

You can access the updated version of your stackblitz here

I trust this aligns with the intended behavior you are aiming for.

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

Guiding a WordPress Form Submission to a Different Page

I'm currently using WordPress to create a form with the following code: [contact-form][contact-field label='What message would you like to send?' type='textarea' required='1'/]Word Limit: 50 words[contact-field label=&ap ...

What is the reason buttons in mat-menus do not submit?

I have implemented a mat-menu to showcase a list of choices for the user. The objective is to trigger the submission of my formGroup when a user selects an option from the menu. dropdown.component.html <form [formGroup]="myForm" (ngSubmit)=onSubmit(my ...

`Manipulating binding and text options in a dropdown selection using knockout.js`

I've read through various sources and websites but still can't figure out what's wrong with my code. It seems like everything should be working fine, but I'm getting [Object object] as options. Html <select data-bind="options: Cit ...

Connect a responsive div to a main div

I'm relatively new to the world of Javascript, CSS, and HTML. Currently, I'm attempting to anchor a div to the center and bottom of its parent div. The parent div contains a responsive background image and my fa fa-arrow icon is correctly positi ...

Issue encountered while attempting to install dependencies using Stackblitz

I recently attempted to add ng-select to my StackBlitz project by including it in the dependencies section and importing it in app.module.ts. However, I encountered an error. You can view my code here. import { NgModule } from "@angular/core"; import { Br ...

Updating the table row by extracting data and populating it into a form

As part of my project, I am implementing a feature where I can input 'Actors' into a table using a Form. This functionality allows me to select a row in the table and retrieve the data of the chosen Actor back into the form for updating or deleti ...

Initiate a Gravity Forms form refresh after modifying a hidden field with jQuery

TO SUM IT UP: Is there a way in Javascript to activate an update on a Gravity Form that triggers the execution of conditional logic? ORIGINAL QUESTION: I'm using Gravity Forms and I have set up an "on change" event $('#gform_1').find(&apos ...

Looking to alter the appearance of a div within an iframe by matching it with the title of the parent window using javascript?

I am currently working on a parent page titled Criatweb, which contains an iframe page. My goal is to modify the display of a specific div within the iframe page only when its title matches Criatweb. I attempted to implement the following script within t ...

JS: Modifying this function to manage a click on a hyperlink

After following the guide provided here I have successfully implemented a drop down list that sends the value to an external PHP script, retrieves HTML output, and displays it in a "div" on the same page. It works flawlessly. My next objective is to send ...

What steps do I need to take in order to make fullscreen slides?

Seeking assistance in developing full-screen slides similar to those found on the following website... The browser scrollbar should be hidden, and the slides should automatically transition when scrolling up/down or using the up/down arrow keys, with the a ...

What should the formatting of a web3py ABI be for an ethereum contract that produces array outputs?

I need to reverse engineer the ABI of an unknown function in an ethereum contract. Here is the raw output split into 256-bit chunks: '0000000000000000000000000000000000000000000000000000000000000060' # unknown '00000000000000000000000000000 ...

Tips for selecting a specific input field in a ReactJS component with multiple inputs

I am currently developing a ReactJS application where I have implemented a component responsible for generating an HTML table. Within this component, I utilize Map to create rows using a child component. These rows contain multiple input fields that users ...

Navigation menu featuring unique links for varying pages

This application is built on Ruby on Rails, using Ruby version 2.1.4 and Rails version 4.1.14. I have a Javascript dropdown menu in the header bar that displays a list of items. However, I'm struggling to figure out how to dynamically change the menu ...

Interpolating strings with Angular does not result in binding

My goal is to populate the template using string interpolation. However, when I attempt to reference the variable in the template, I receive the following error: core.js:1350 ERROR TypeError: Cannot read property 'status' of undefined. HTML ...

Utilizing Firefox and Selenium with Python: A guide to dynamically accessing HTML elements

Currently, I am utilizing a combination of Python, Selenium, Splinter, and Firefox to develop an interactive web crawler. The Python script provides the options, then Selenium launches Firefox and executes certain commands. At this point, I am looking fo ...

Is a JavaScript variable automatically global if not declared with var?

Here is the code snippet from one of my files: function refreshGridSuccess(responseText, entity) { oTable = $('#dataTable').dataTable({ "sScrollX": "100%", In a different file, I have the following code: $('#d ...

Dealing with errors in promises

At times, when creating a promise, there may be unusual scenarios such as the database refusing the connection or an invalid host name parameter. For instance: In db.js const mysql = require('mysql'); module.exports.connect = (options) => { ...

Guide on deploying an Angular 2 CLI project on a locally hosted Ubuntu production server

I'm currently working on setting up a locally hosted Ubuntu server and I'm looking to deploy an Angular 2 CLI project on it. I'm fairly new to Angular 2, so any assistance would be greatly appreciated! ...

Unable to connect with API data in Angular 6

I have been using an API to retrieve data and display it on a webpage. While I am able to see the response in the console, I am facing difficulty binding the data to the user interface. Nothing is appearing on the screen as expected. This is my HTML code: ...

Sending multiple files as the source of a page to clients in Node.js: A step-by-step guide

Currently, I am developing a web application using node.js. Here is a snippet from my index.html file: <h1 id="h">hello</h1> <script src="client.js"></script> My goal is to update the innerHTML of the h1 elemen ...