What is the best way to connect a series of checkboxes within a form utilizing Angular?

I created a form with checkboxes that allow users to select multiple options. However, when I submit the form, instead of receiving an array of objects representing the checked checkboxes, I'm not getting anything at all.

Here is what I see in the console: {fruits: Array[0]}

What I was hoping for:

{fruits: Array[1]} // The number of items in the array should correspond to the number of checkboxes selected

You can take a look at an example on stackblitz for reference

Answer №1

All the steps have been completed except for initializing the form

myForm: FormGroup = this.initializeModelForm();

The complete code snippet includes the console logging of the formArray value

import { Component } from '@angular/core';
import { FormGroup, FormArray, FormControl, FormBuilder } from '@angular/forms';

export interface Fruit {
  uid: string;
  name: string;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent   {
public checks = [
  {description: 'descr1', value: 'value1'},
  {description: "descr2", value: 'value2'},
  {description: "descr3", value: 'value3'}
];

myForm: FormGroup = this.initializeModelForm();

constructor(
  public _fb: FormBuilder
) { }

initializeModelForm(): FormGroup{
  return this._fb.group({
    otherControls: [''],
    myChoices: new FormArray([])
  })
}

onCheckChange(event) {
  console.log(event);
  const formArray: FormArray = this.myForm.get('myChoices') as FormArray;

  /* Selected */
  if(event.target.checked){
    // Add a new control in the arrayForm
    formArray.push(new FormControl(event.target.value));
  }
  /* unselected */
  else{
    // find the unselected element
    let i: number = 0;

    formArray.controls.forEach((ctrl: FormControl) => {
      if(ctrl.value == event.target.value) {
        // Remove the unselected element from the arrayForm
        formArray.removeAt(i);
        return;
      }

      i++;
    });
  }
  console.log(formArray.value);
}
}

Answer №2

When considering an approach similar to Netanel Basal's, it is essential to modify the submit function for smoother operation. One way to achieve this is by structuring a Form with values such as:

{
  "otherControls": "",
  "myChoices": [
    false,
    true,
    false
  ]
}

Although the initial data may seem unattractive, the submit function can be adjusted to transform it into a more organized format:

submit(myForm) {
    if (myForm.valid) {
      const value = { ...myForm.value };
      value.myChoices = this.checks
        .filter((x, index) => myForm.value.myChoices[index])
        .map(x => x.value);
      this.result = value;
    }
  }

This modification will result in a cleaner output, like so:

{
  "otherControls": "",
  "myChoices": [
    "value2"
  ]
}

While the submit process may become slightly more complex, the form structure itself becomes streamlined and intuitive:

<form *ngIf="myForm" [formGroup]="myForm" (submit)="submit(myForm)">
  <div formArrayName="myChoices">
  <div *ngFor="let choice of myForm.get('myChoices').controls; let i=index" class="col-md-2">
    <label>
      <input type="checkbox" [formControlName]="i">
      {{checks[i].description}}
    </label>
  </div>
  </div>
  <button type="submit">submit</button>
</form>

This method eliminates the need for external functions and minimizes complications typically associated with dynamic forms. By setting up the form initially as:

initModelForm(): FormGroup {
    return this._fb.group({
      otherControls: [""],
      myChoices: new FormArray(this.checks.map(x => new FormControl(false)))
    });
  }

For further reference, see this StackBlitz demo

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

Retrieve the content of a text field with jQuery

Check out this block of HTML: <div class="sub-middle-column"> <div class="div-header">Grandsire <a "#", class="table-control-focus sub-header-table-focus" id="table-control-focus-t" >abc</a> <ul class="table-controls h ...

Building a High-Performance Angular 2 Application: A Comprehensive Guide from Development to

Recently, I began developing an Angular2 project using the quickstart template. My main concern now is determining which files are essential for deployment on my live server. I am unsure about the specific requirements and unnecessary files within the qu ...

Searching for a specific set of rows within an array? Look no further than jQuery and JavaScript

I'm struggling to find the right title for my project, but I'm doing my best to capture its essence. I am in the process of developing a calculator that compares values within multiple arrays. Each data item in my array consists of 34 rows, wit ...

Deleting files with a dedicated function (Dropzone.js)

I need to implement functionality that removes the uploaded file when a 'cancel' button is clicked. Here's how my HTML code looks: <div reqdropzone="reqDropzoneConfig"> <form id="requisitionupload" class="dropzone dz-clickable" ac ...

How can you direct a user to a specific page only when certain conditions are met?

Currently using React in my single page application. I have a good grasp on how Routes function and how to create a PrivateRoute. The issue arises when I need to verify the user's identity before granting access to a PrivateRoute. My attempt at imple ...

The submission of the form with the ID "myForm" using document.getElementById("myForm").submit() is

<form name="formName" id="formName" action="" method="post" autocomplete="off"> <input type="hidden" name="text1" id="text1" value='0' /> <input type="button" name ="submit" onClick="Submit()" value="submit"> ...

Switching button class when hovering over another div

When you click on the "collapsible-header" div, I want the text "TE LAAT" in the button to change to "NU BETALEN". Currently, the CSS code changes the text on hover, but I want it to change on click when the collapsible-header also has the active class. T ...

Repeated URL causes Node to redirect

I am currently working on a project that involves redirecting users if they enter a specific URL, especially for redirecting from a Heroku domain. During my testing phase on localhost, I noticed that the redirect URL keeps getting repeated: http://localh ...

How can we modify this function to interpret multiple selections at once?

For the task of displaying multiple selections from a scrolling list to an alert, I have implemented the following function: var toppings = ""; function displaySelectedToppings() { var topList = document.getElementById('to ...

Issues with Vite's global import feature not functioning properly in a production build

My current setup involves loading all markdown files within a directory using a glob import. The code snippet below depicts this functionality: const useGetChangelogs = () => { const [changelogs, setChangelogs] = useState<string[]>([]); useEf ...

A Complication Arises with Browser Functionality When Embedding an Iframe within

I am experiencing a peculiar problem while embedding an iframe with a specific src inside an absolutely positioned div. Here's the basic structure of the webpage: .container { position: relative; overflow: hidden; width: 100%; heigh ...

A guide on implementing getStaticProps using TypeScript in Next.js

Why am I consistently receiving undefined results when attempting to retrieve all posts from my backend? What could be causing this issue? import { AppContext } from '@/helpers/Helpers' import axios from 'axios' import { GetStaticProps} ...

Testing useEffect with React hooks, Jest, and Enzyme to add and remove event listeners on a ref

Here is a component I've been working on: export const DeviceModule = (props: Props) => { const [isTooltipVisible, changeTooltipVisibility] = useState(false) const deviceRef = useRef(null) useEffect(() => { if (deviceRef && dev ...

Mastering the correct usage of the submitHandler method in the jQuery validation plugin

Here is a snippet of documentation from the jQuery validation plugin: "Use submitHandler to execute some code before submitting the form, without triggering the validation again." submitHandler: function(form) { $.ajax({ type: 'POST&apos ...

What are the consequences of altering meta tags once the DOM has fully loaded?

While delving into the A-Frame source code, I noticed that the library uses JavaScript to set various meta tags. It seems safe in the context of A-Frame as Mozilla recommends importing their library as a blocking, synchronously loaded script in the <he ...

Using Jquery to dynamically adjust the size of a div based on the width and height of the browser window

How can I dynamically change the height of a .test div based on the browser width and height? I want the value to update whenever the browser is resized. $(document).ready( function() { window.onresize = function(event) { resizeDiv(); ...

What is the best way to switch the direction of the arrows based on the sorting order?

Is there a way to dynamically change the direction of arrows based on sorting, similar to the example shown here? sortingPipe.ts: import { SprBitType } from '../spr-bit-type/sprBitType'; import { Pipe, PipeTransform } from '@angular/core& ...

Unable to confirm form validation with Vue

Recently, I started working with Vue and encountered a problem while running the code below. The error message "ReferenceError: $vAddress is not defined" keeps popping up. Despite my efforts to search for solutions online, I couldn't find any that add ...

What causes the appearance of an HTTP header error and how can we identify the bug?

I tried to convert XML to JSON using two files which are included here. However, I keep encountering an error. Despite searching on SO for solutions, I haven't been able to find the answers. main.js /** SET ENGINE TO PUG */ app.set("views", ...

Display pie charts on a Google Map

Utilizing a combination of JavaScript and GoogleMaps technology Within my application, there exists a screen showcasing a Google Map. In addition to this map, I have incorporated statistics detailing Population growth data displayed in the form of Pie Cha ...