16

I am working on angular2 application and getting problem in storing values of multiple check boxes in form field.

Type script

form : FormGroup;
cities = ["Mohali", "Chandigarh", "Ludhiana", "Amritsar"];
zip_codes = ["282001", "456123", "123456", "140412"];

constructor(private formBuilder : FormBuilder)
{
    this.form = this.formBuilder.group({
       cities   : this.formBuilder.array(["Mohali", "Amritsar"]),
       zip_codes : this.formBuilder.array(["456123"])
    });
}

HTML

<div *ngFor="let city of cities">
    <input type="checkbox" formControlName="cities" value="city">
    <span>{{city}}</span>
</div>

<div *ngFor="let zipCode of zip_codes">
    <inbput type="checkbox" formControlName="zip_codes" value="zipCode">
     <span>{{zipCode}}</span>
</div>

I want to store checked cities and zip_codes in form field and when I have default values in form field then the values are in array will be checked automatically.

2
  • 1
    Which items should be checked? Commented Jul 24, 2017 at 5:21
  • I updated my question. Commented Jul 24, 2017 at 5:25

2 Answers 2

28

One way would be like this:

1) Setup FormArray fields with false default values

this.form = this.formBuilder.group({
  cities   : this.formBuilder.array(this.cities.map(x => !1)),
  zip_codes : this.formBuilder.array(this.zip_codes.map(x => !1))
});

2) The template will look like this:

<div *ngFor="let city of cities; let i = index" formArrayName="cities">
  <input type="checkbox" [formControlName]="i">
  <span>{{city}}</span>
</div>

<div *ngFor="let zipCode of zip_codes; let i = index" formArrayName="zip_codes">
  <input type="checkbox" [formControlName]="i">
  <span>{{zipCode}}</span>
</div>

3) Submit form

convertToValue(key: string) {
  return this.form.value[key].map((x, i) => x && this[key][i]).filter(x => !!x);
}

onSubmit() {
  const valueToStore = Object.assign({}, this.form.value, {
    cities: this.convertToValue('cities'),
    zip_codes: this.convertToValue('zip_codes')
  });
  console.log(valueToStore);
}

4) Default values

const defaultCities = ["Mohali", "Amritsar"];
const defaultZipCodes = ["456123"];
this.form = this.formBuilder.group({
  cities: this.formBuilder.array(this.cities.map(x => defaultCities.indexOf(x) > -1)),
  zip_codes: this.formBuilder.array(this.zip_codes.map(x => defaultZipCodes.indexOf(x) > -1))
});

Plunker Example

Sign up to request clarification or add additional context in comments.

7 Comments

I don't want this type of output ( "cities": [true, true, true, true]), I want ("cities" : ["Mohali", "Amritsar"]).
@LakhvirSingh Try to submit button
Thank you its works but you are using variable to store defaultCities and defaultZipCodes but in my situation I don't know that I will get cities array from api because every array and its html generating based on api response. If I get cities array in api then it will automatically generate its html and add new control in form.
@LakhvirSingh I used variables just for example. You can update value after getting from server like this.form.get('cities').patchValue(this.cities.map(x => citiesFromServer.indexOf(x) > -1)); plnkr.co/edit/M5mIx5idfUDpRmiaxCPk?p=preview
How can I get values of form if I use Object.assign() separately on both fields (cities, zip_codes). Because when I am using separately on both fields I will get only one field value at a time, but I want both fields value together but using Object.assign() separately.
|
8

I liked very much the answer of @yurzui But had an issue with getting the values back .. So..

My solution - solved it for Angular 5 with Material View
The connection is through the

formArrayName="notification"

(change)="updateChkbxArray(n.id, $event.checked, 'notification')"

This way it can work for multiple checkboxes arrays in one form. Just set the name of the controls array to connect each time.

constructor(
  private fb: FormBuilder,
  private http: Http,
  private codeTableService: CodeTablesService) {

  this.codeTableService.getnotifications().subscribe(response => {
      this.notifications = response;
    })
    ...
}


createForm() {
  this.form = this.fb.group({
    notification: this.fb.array([])...
  });
}

ngOnInit() {
  this.createForm();
}

updateChkbxArray(id, isChecked, key) {
  const chkArray = < FormArray > this.form.get(key);
  if (isChecked) {
    chkArray.push(new FormControl(id));
  } else {
    let idx = chkArray.controls.findIndex(x => x.value == id);
    chkArray.removeAt(idx);
  }
}
<div class="col-md-12">
  <section class="checkbox-section text-center" *ngIf="notifications  && notifications.length > 0">
    <label class="example-margin">Notifications to send:</label>
    <p *ngFor="let n of notifications; let i = index" formArrayName="notification">
      <mat-checkbox class="checkbox-margin" (change)="updateChkbxArray(n.id, $event.checked, 'notification')" value="n.id">{{n.description}}</mat-checkbox>
    </p>
  </section>
</div>

At the end you are getting to save the form with array of original records id's to save/update. The UI View

The relevat part of the json of the form

Will be happy to have any remarks for improvement.

Here is the Gist

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.