Removing an object from a JSON array based on checkbox selection in Angular 4

0:
CategoryId: "31b7a227-9fda-4d14-8e1f-1dee5beeccb4"
Code: "GMA0300"
Description: "PA-5215: Renamed"
Enabled: true
Favorite: false
Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd"
InstrumentType: null
Moniker: "1GMA0300"
Name: "Celiac Disease Panel (tTG IgG, tTG IgA, DGP IgG)"
Tests: Array(3)
  0:
   Code: "GMA0304"
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781"
   Name: "Deamidated Gliadin Peptide (DGP) IgG"
 __proto__: Object
  1: {Id: "2fcd610f-d453-4c4f-a8dc-1a5f50e88548", Code: "GMA0301", Name: 
 "Tissue Transglutaminase (tTG) IgA"}
  2: {Id: "de41b236-4866-419a-a6f4-5f7c1440d30f", Code: "GMA0302", Name: 
 "Tissue Transglutaminase (tTG) IgG"}
 length: 3
 __proto__: Array(0)
 TestsSelectable: false

Here we have an array named selectedPanels, which contains subarrays of objects. These subarrays are mapped into panels, each containing checkboxes and expandable rows for Tests, which are also arrays with checkboxes.

When the panel checkbox is selected, all child checkboxes within Tests are also selected, resulting in a total Tests length of 3. However, when each test checkbox is deselected, the Tests length should decrease. The issue arises when using splice, as it removes the entire row upon deselecting each test checkbox, including the parent panel checkbox. The desired behavior is to only reduce the array length when deselecting individual tests, without removing the entire row.

You can view an image illustrating this issue here.

HTML File:

<label class="custom-control custom-checkbox">
    <input type="checkbox" class="custom-control-input" [name]="panel.Id + '-' + panel.Moniker" [ngModel]="checkAllTestsSelected(panel)"
      (ngModelChange)="onPanelCheckboxUpdate($event, panel)" [id]="panel.Id + '-' + panel.Moniker">
    <span class="custom-control-indicator"></span>
  </label>

 </ng-template>
 <ng-template ngbPanelContent>
<div class="individual-panel" *ngFor="let test of panel.Tests">
  <span class="text-dimmed">{{test.Name}}</span>
  <span *ngIf="panel.Name.includes('ENA') || panel.Name.includes('Celiac')">
  <label class="custom-control custom-checkbox">
    <input type="checkbox" class="custom-control-input" [name]="test.Id + '-' + test.Code"
           [ngModel]="testSelectionSession.SelectedPanelIds.indexOf(panel.Id) > -1 || testSelectionSession.SelectedPanelIds.indexOf(test.AssociatedPanel?.Id) > -1"
           (ngModelChange)="onTestCheckboxUpdate($event, test, panel)" [id]="test.Id + '-' + test.Code">
    <span class="custom-control-indicator"></span>
  </label>
  </span>
</div>

TS File:

checkAllTestsSelected(panel: TestOrderPanel) {
  // Implement logic here
 }

 onPanelCheckboxUpdate($event: boolean, panel: TestOrderPanel) {
   // Implement logic here
 }

 onTestCheckboxUpdate($event: boolean, test: TestOrderPanelTest, panel: TestOrderPanel) {
  // Implement logic here
 }

The array in question is stored in selectedPanels. Any insights on how to address this issue would be greatly appreciated. Can anyone offer assistance?

Answer №1

If you want to enhance your ngFor loop in the template by adding an index ('let i = index' in the code snippet below), you can utilize this index in your onTestCheckboxUpdate() function to modify your source array accordingly:

Here is an example of how you can achieve this:

<ul>
    <li *ngFor="let item of items; let i = index" [attr.data-index]="I">
        {{item}}
        <button (click)="removeItem(i)">Remove '{{item}}' from the array</button>
    </li>
</ul>

In your TypeScript file, you can have something like this:

items = ['cat', 'dog', 'mouse', 'frog', 'horse', 'bird'];

removeItem(itemIndex: number) {
    this.items.splice(itemIndex, 1);
}

Give it a try and see if this fits your requirements. You can check out a simplified version of this concept here.

Answer №2

In order to determine the number of items that are checked or not checked, you can implement the following method. The code has been updated to include a 'checked' property for each item in the data array. You can also view the code on Stackblitz.

TS File:

items = [
    {name: 'cat'},
    {name: 'dog'},
    {name: 'horse'},
    {name: 'mouse'}
];

checkCount = this.items.length;

checkItem(itemIndex:number){
    if(this.items[itemIndex]['checked'] === undefined){
        this.items[itemIndex]['checked'] = false;
    } else {
        this.items[itemIndex]['checked'] = !this.items[itemIndex]['checked'];
    }
    this.checkCount = this.items.filter(item => item['checked'] === true || item['checked'] === undefined).length;
}

HTML File:

<ul>
    <li *ngFor="let item of items; let i = index">
        <label>{{item.name}}</label>
        <input type="checkbox" checked (click)="checkItem(i)">
    </li>
</ul>

Check count: {{checkCount}}

See an example on here.

If you require two-way binding, you can utilize a formControl to store the 'checked' variable for each checkbox, instead of a simple boolean. Take a look at an example of this here.

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

Despite correctly declaring jquery-ui.js and numeric.js, the jQuery datepicker and numeric plugins are not working as expected

element, it's strange that I am not receiving any error messages. However, despite this, the jquery datepicker function and numeric plugin are not working on the intended input fields they are supposed to be linked to. This particular page is a simpl ...

Moving the Promise.all feature from AngularJs to VueJs

I'm currently facing a challenge with moving a function from AngularJs to VueJs. I would really appreciate any help or suggestions you may have! items = { one: {...details here...}, two: {}, } In AngularJs: var promises = []; var deferred = $ ...

Establishing the Time-to-Live (TTL) with Redis-OM and Node Object Mapping

Recently, I stumbled upon the exciting new Redis-OM Node Object Mapping feature. Although I have limited experience with Redis, I am eager to dive into it now. Currently, I have a basic function in place for creating rooms but I want these rooms to automa ...

Can you explain the significance of the ColSpan property in the Material UI TablePagination?

Why is ColSpan used in this code snippet? Reference: https://material-ui.com/components/tables/#table Check for the arrow symbol <TableFooter> <TableRow> <TablePagination rowsPerPageOptions={[5, ...

What are the steps to create a button within an Onsen sliding menu?

For instance, if I have a menu at http://codepen.io/onsen/pen/IDvFJ, how can I insert a new element named page3, so that when a user clicks on it, it triggers the following code: Appmenu.onclick('page3', function(){ alert("Hello"); }) ...

Retrieve Data from Angular's ngRedux Store

Wanting to retrieve and react to changes in data from ngRedux-store, I am looking to utilize it in a guard with the CanActivate interface. In my previous method of fetching data, I typically used this code snippet: @select(['auth', 'IsAuth ...

After manipulating the array, Vue fails to render the input fields generated by the v-for directive

After setting the value externally, Vue component won't re-render array items. The state changes but v-for element does not reflect these changes. I have a component that displays items from an array. There are buttons to adjust the array length - &a ...

Firestore real-time document listener disrupts sorting functionality

I've encountered a Firestore problem that I'm hoping the community can assist me with. It seems that my active document snapshot listener is causing issues with sorting behavior, and I'm struggling to understand why. Upon initializing my c ...

I am facing an issue with my getServerSideProps function being undefined in my Next.js application, despite using a class component. Can anyone help me troub

Hey there, I'm currently facing an issue with retrieving props using getServerSideProps. I've tried various solutions but haven't been able to make it display properly. Below is the code snippet: import React, { Component } from 'react& ...

Attempting to activate an ASP button that is created within a gridview after pressing the enter key within a textbox

I am currently working on a gridview with dynamically generated rows, each row containing text boxes and buttons. The goal is to update the database with values from the textboxes when UpdateBtn1 is clicked. Users should be able to either click the button ...

Can someone guide me on how to extract checkbox values in a post method using Angular

I'm facing an issue with a table that contains a list of rules. Whenever the checkboxes are clicked, I want them to send a "true" value to an API endpoint. However, I keep receiving an error stating that the "associated_rule" is undefined. After tryi ...

Is it possible to include two of these on a single page with unique variables? (Using JQuery)

I am looking to create two similar pages, each with different percentages. However, when I try modifying the JS or changing class/ID names, it keeps pulling data from the first SPAN element. http://jsfiddle.net/K62Ra/ <div class="container"> <di ...

List component in Angular not refreshing after sorting the array in the service

Currently, I am delving into the realm of Angular (version 5+) to enhance my skills by working on a small project. The project involves setting up basic routing functionalities to showcase the ContactList component upon selecting a navigation tab. Addition ...

How to populate the space beneath the `AreaChart` curve in `recharts` when data includes positive and negative values

How can I modify my chart, created using the recharts library in JavaScript, so that the area under the curve fills to the bottom of the visible area instead of stopping at zero? This is how it currently looks: https://i.sstatic.net/CCHXu.png My goal is ...

Build a new shop using a section of data from a JSON database

Let's say I have a JSON store that is set up as shown below var subAccountStore = new Ext.data.JsonStore({ autoLoad: true, proxy: { type:'ajax', url : '/opUI/json/subaccount.action?name="ABC"' }, fields: ['acc ...

Can someone help me figure out how to trigger my function after my jQuery 'each' function has completed along with all the AJAX calls it includes?

Hello all, seeking some guidance here. I have experimented with various solutions from SO and other sources. This particular one caught my attention as I tried to ensure that my function wouldn't execute until all ajax calls were completed. However, I ...

When using form.serialize() in Django forms, an empty object is being sent

Upon clicking the button, my AJAX request is sending an empty object Object { } instead of form data. The form on my page consists of checkboxes and its HTML structure is as follows: <form method="post" action="" data-id="filter-form"> //Included ...

Troubleshooting Problem with Installing Angular2-Google-Maps Component in FountainJS Application

Using the FountainJS Angular2 generator with Typescript and Systems.js has been helpful for scaffolding my project. Check it out here However, I encountered an issue while trying to add a component to the project. Upon importing {GOOGLE_MAPS_DIRECTIVES}, ...

Is there a way to stop the execution of myFunc after it has been performed 5 times using clearInterval?

This code is designed to notify online shoppers that they need to choose a color from a dropdown menu before adding an item to their shopping cart. If no color is selected, the text will blink to alert them. How can I modify this code so that the blinking ...

`` I am experiencing a problem with CSS display block in Internet Explorer

Looking to implement a basic tab menu using a combination of tables and div elements. The goal is to have the tabs switch styles when clicked, giving the appearance of being toggled, while also swapping out the corresponding content in separate div blocks ...