Chandan K. Jilukara
Chandan K. Jilukara

Reputation: 1

Array Filters in Angular 2

Note: I'm new to software development and I just got started with frontend development with Angular 2.

I'm planning to build a filter array of checkboxes which will return the checked values upon submit.

My code is as below.

I declared the ranges and tenures in a TS file.

let amountRanges = [
  { id: 1, label: 'amtRange1', low: '25000', high:'50000' },
  { id: 2, label: 'amtRange2', low: '50001', high:'100000' },
  { id: 3, label: 'amtRange3', low: '100001', high:'200000' },
  { id: 4, label: 'amtRange4', low: '200001', high:'300000' },
  { id: 5, label: 'amtRange5', low: '300001', high:'400000' },
  { id: 6, label: 'amtRange6', low: '400001', high:'500000' }
]

export { amountRanges }

let tenureRanges = [
  { id: 1, label: 'tenure6', name:'6 Months' },
  { id: 2, label: 'tenure12', name:'12 Months' },
  { id: 3, label: 'tenure18', name:'18 Months' },
  { id: 4, label: 'tenure24', name:'24 Months' },
  { id: 5, label: 'tenure30', name:'30 Months' },
  { id: 6, label: 'tenure36', name:'36 Months' }
]

export { tenureRanges }

Here is the HTML code

<section>
    <h4>Filters</h4>
    <hr>
    <form [formGroup]="form">
        <!-- Loan Amount Filter -->
        <div class="form-group">
        <label>LOAN AMOUNT</label>
        <div>
            <ul class="list-unstyled" formArrayName="amtranges">
                <li *ngFor="let range of form.controls.amtranges.controls; let i = index">
                    <input type="checkbox" formControlName="{{i}}"> &#8377;{{amtArray[i].low}} - &#8377;{{amtArray[i].high}}
                </li>
            </ul>
            </div>
        </div>

        <div class="form-group">
        <label>LOAN TENURE</label>
        <div>
            <ul class="list-unstyled" formArrayName="tenures">
                <li *ngFor="let tenure of form.controls.tenures.controls; let i = index">
                    <input type="checkbox" formControlName="{{i}}"> {{tenureArray[i].name}}
                </li>
            </ul>
            </div>
        </div>

        <div><strong>Model value:</strong><br />{{filter | json}}</div>

        <div class="row">
            <div class="col-sm-6"><button type="button" class="btn btn-primary" [disabled]="!form.valid" (click)="submitForm()">Submit</button></div>
            <div class="col-sm-6"><button type="button" class="btn btn-default" (click)="this.form.reset()">Reset</button></div>
        </div>
    </form>
</section>

I'm running the Angular2 component as below

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

import { amountRanges, tenureRanges } from './borrower-filter.interface';

@Component({
  moduleId: module.id,
  selector: 'borrower-filters',
  templateUrl: './borrower-filters.component.html',
  styleUrls: ['./borrower-filters.component.css']
})

export class BorrowerFiltersComponent implements OnInit {

  //Loan Amount
  amtArray: any = [];
  amtBoxArray: FormArray;
  //Loan Tenure 
  tenureArray: any = [];
  tenureBoxArray: FormArray;

  //Filter
  filter: any = [];

  form: FormGroup;

  constructor(private _fb: FormBuilder) { }

  ngOnInit() {
    this.initializeData();
    this.buildForm();
  }

  buildForm() {

    this.amtBoxArray = new FormArray([]);
    for( let d in this.amtArray ) {
      this.amtBoxArray.push( new FormControl(( this.filter.indexOf( this.amtArray[d].label ) > -1 )))
    }
    this.tenureBoxArray = new FormArray([]);
    for ( let d in this.tenureArray ) {
      this.tenureBoxArray.push( new FormControl(( this.filter.indexOf( this.tenureArray[d].label ) > -1 )))
    }

    this.form = this._fb.group(
      { 'amtranges': this.amtBoxArray },
      { 'tenures' : this.tenureBoxArray }
      );

  }

  submitForm() {
    if( this.form.valid ) {
      this.filter = [];
      for( let db in this.amtBoxArray.controls ) {
        if( this.amtBoxArray.controls[ db ].value == true ) {
          this.filter.push( this.amtArray[ db ].label )
        }
      }
      for( let db in this.tenureBoxArray.controls ) {
        if( this.tenureBoxArray.controls[ db ].value == true ) {
          this.filter.push( this.tenureArray[ db ].label )
        }
      }
    }
  }

  initializeData() {
    amountRanges.forEach( range => {
      this.amtArray.push( range );
    });
    tenureRanges.forEach( range => {
      this.tenureArray.push( range );
    });
  }

}

I want the checked checkbox labels into a filter array. The problem is not building properly and the submit button is not returning the filter json.

Upvotes: 0

Views: 1437

Answers (2)

Viraj
Viraj

Reputation: 1420

Below is one of way,

Note: This is not close to Form Control(Template Driven Or Data/Form Driven) of Angular 2.

But alternative way to achieve and get selected record in Angular 2.

<ul class="list-unstyled">
    <li *ngFor="let range of tenureRanges; let i = index">
        <input type="checkbox" [(ngModel)]="range.checked"> &#8377;{{range.name}} - &#8377;{{range.label}}
    </li>
</ul>



    let tenureRanges = [
      { id: 1, label: 'tenure6',  name:' 6 Months',checked:false },
      { id: 2, label: 'tenure12', name:'12 Months',checked:false  },
      { id: 3, label: 'tenure18', name:'18 Months',checked:false  },
      { id: 4, label: 'tenure24', name:'24 Months',checked:false  },
      { id: 5, label: 'tenure30', name:'30 Months',checked:false  },
      { id: 6, label: 'tenure36', name:'36 Months',checked:false  }
    ]

// In Submit function,You can do this to get selected value, it will return array of checked value.

let arrayOfSelectedValue=this.tenureRanges.filter(f=>f.checked).map(f=>f.id);

Upvotes: 0

yurzui
yurzui

Reputation: 214047

Your mistake is located here:

this.form = this._fb.group(
  { 'amtranges': this.amtBoxArray },
  { 'tenures' : this.tenureBoxArray }
);

your config should be in the first parameter like:

this.form = this._fb.group({ 
  'amtranges': this.amtBoxArray,
  'tenures' : this.tenureBoxArray 
});

You can also take a look at source code

export class FormBuilder {
  /**
   * Construct a new {@link FormGroup} with the given map of configuration.
   * Valid keys for the `extra` parameter map are `validator` and `asyncValidator`.
   *
   * See the {@link FormGroup} constructor for more details.
   */
  group(controlsConfig: {[key: string]: any}, extra: {[key: string]: any} = null): FormGroup {
    const controls = this._reduceControls(controlsConfig);
    const validator: ValidatorFn = extra != null ? extra['validator'] : null;
    const asyncValidator: AsyncValidatorFn = extra != null ? extra['asyncValidator'] : null;
    return new FormGroup(controls, validator, asyncValidator);
  }

Upvotes: 3

Related Questions