Formes angulaires de réactivation: production d'un tableau de valeurs de cases à cocher?

donne une liste de cases à cocher reliées à la même formControlName, Comment puis-je produire un tableau de valeurs de cases à cocher liées au formControl plutôt que de simplement les true/

8 ответов

Voici un bon endroit pour utiliser le FormArrayhttps://angular.io/docs/ts/latest/api/forms/index/FormArray-class.html

Pour commencer, nous allons construire notre tableau de contrôle avec un FormBuilder ou newing un FormArray

FormBuilder

this.checkboxGroup = _fb.group({
  myValues: _fb.array([true, false, true])
});

new FormArray

let checkboxArray = new FormArray([
  new FormControl(true),
  new FormControl(false),
  new FormControl(true)]);

this.checkboxGroup = _fb.group({
  myValues: checkboxArray
});

assez facile à faire, mais ensuite nous allons changer notre modèle et laisser le moteur templating gérer comment nous lier à notre contrôle:

modèle.html

<form [formGroup]="checkboxGroup">
    <input *ngFor="let control of checkboxGroup.controls['myValues'].controls"
    type="checkbox" id="checkbox-1" value="value-1" [formControl]="control" />     
  </form>

ici nous itérons sur notre ensemble de FormControls notre myValuesFormArray et pour chaque contrôle nous sommes liés [formControl] à ce contrôle au lieu de FormArray contrôle et <div>{{checkboxGroup.controls['myValues'].value}}</div> produit true,false,true tout en rendant votre syntaxe de template un peu moins manuelle.

Vous pouvez utiliser cet exemple: http://plnkr.co/edit/a9OdMAq2YIwQFo7gixbj?p=preview poke autour de

24
répondu silentsod 2016-12-02 20:27:03
la source

avec l'aide de silentsod answer, j'ai écrit une solution pour obtenir des valeurs au lieu d'États dans mon formBuilder.

j'utilise une méthode pour ajouter ou supprimer des valeurs dans le formArray. Il peut être une mauvaise approche, mais ça fonctionne !

composant.html

<div *ngFor="let choice of checks; let i=index" class="col-md-2">
  <label>
    <input type="checkbox" [value]="choice.value" (change)="onCheckChange($event)">
    {{choice.description}}
  </label>
</div>

composant.ts

// For example, an array of choices
public checks: Array<ChoiceClass> = [
  {description: 'descr1', value: 'value1'},
  {description: "descr2", value: 'value2'},
  {description: "descr3", value: 'value3'}
];

initModelForm(): FormGroup{
  return this._fb.group({
    otherControls: [''],
    // The formArray, empty 
    myChoices: new FormArray([]),
  }
}

onCheckChange(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++;
    });
  }
}

quand je soumets mon formulaire, par exemple mon modèle ressemble à:

  otherControls : "foo",
  myChoices : ['value1', 'value2']

il ne manque qu'une chose, une fonction pour remplir le formArray si votre modèle a déjà vérifié les valeurs.

18
répondu Guymage 2017-05-09 22:09:18
la source

si vous cherchez des valeurs de cases à cocher dans le format JSON

{ "name": "", "countries": [ { "US": true }, { "Germany": true }, { "France": true } ] }

exemple Complet ici.

Je m'excuse d'avoir utilisé les noms de pays comme valeurs des cases à cocher au lieu de celles de la question. En outre explannation -

Créer un FormGroup pour la forme

 createForm() {

    //Form Group for a Hero Form
    this.heroForm = this.fb.group({
      name: '',
      countries: this.fb.array([])
    });

    let countries=['US','Germany','France'];

    this.setCountries(countries);}
 }

que chaque case à cocher soit un FormGroup construit à partir d'un objet dont la seule propriété est la valeur de la case à cocher.

 setCountries(countries:string[]) {

    //One Form Group for one country
    const countriesFGs = countries.map(country =>{
            let obj={};obj[country]=true;
            return this.fb.group(obj)
    });

    const countryFormArray = this.fb.array(countriesFGs);
    this.heroForm.setControl('countries', countryFormArray);
  }

le tableau des groupes de formulaires pour le des cases à cocher sont utilisées pour définir le contrôle pour les "pays" dans la forme parent.

  get countries(): FormArray {
      return this.heroForm.get('countries') as FormArray;
  };

dans le modèle, utilisez un tuyau pour obtenir le nom du contrôle de la case à cocher

  <div formArrayName="countries" class="well well-lg">
      <div *ngFor="let country of countries.controls; let i=index" [formGroupName]="i" >
          <div *ngFor="let key of country.controls | mapToKeys" >
              <input type="checkbox" formControlName="{{key.key}}">{{key.key}}
          </div>
      </div>
  </div>
6
répondu aCiD 2017-08-04 12:12:54
la source

faire un événement quand il est cliqué et puis changer manuellement la valeur de true au nom de ce que la boîte de contrôle représente, alors le nom ou true évaluera la même et vous pouvez obtenir toutes les valeurs au lieu d'une liste de true/false. Ex:

composant.html

<form [formGroup]="customForm" (ngSubmit)="onSubmit()">
    <div class="form-group" *ngFor="let parameter of parameters"> <!--I iterate here to list all my checkboxes -->
        <label class="control-label" for="{{parameter.Title}}"> {{parameter.Title}} </label>
            <div class="checkbox">
              <input
                  type="checkbox"
                  id="{{parameter.Title}}"
                  formControlName="{{parameter.Title}}"
                  (change)="onCheckboxChange($event)"
                  > <!-- ^^THIS^^ is the important part -->
             </div>
      </div>
 </form>

composant.ts

onCheckboxChange(event) {
    //We want to get back what the name of the checkbox represents, so I'm intercepting the event and
    //manually changing the value from true to the name of what is being checked.

    //check if the value is true first, if it is then change it to the name of the value
    //this way when it's set to false it will skip over this and make it false, thus unchecking
    //the box
    if(this.customForm.get(event.target.id).value) {
        this.customForm.patchValue({[event.target.id] : event.target.id}); //make sure to have the square brackets
    }
}

cette capture l'événement après qu'il ait été déjà changé en vrai ou faux par des formes angulaires, si c'est vrai je change le nom au nom de ce que la case à cocher représente, qui si nécessaire évaluera également à true si elle est vérifiée pour true / false aussi bien.

4
répondu canada11 2017-05-16 20:41:12
la source

TEMPLATE PART: -

    <div class="form-group">
         <label for="options">Options:</label>
         <div *ngFor="let option of options">
            <label>
                <input type="checkbox"
                   name="options"
                   value="{{option.value}}"
                   [(ngModel)]="option.checked"
                                />
                  {{option.name}}
                  </label>
              </div>
              <br/>
         <button (click)="getselectedOptions()"  >Get Selected Items</button>
     </div>

CONTROLLER PART: -

        export class Angular2NgFor {

          constructor() {
             this.options = [
              {name:'OptionA', value:'first_opt', checked:true},
              {name:'OptionB', value:'second_opt', checked:false},
              {name:'OptionC', value:'third_opt', checked:true}
             ];


             this.getselectedOptions = function() {
               alert(this.options
                  .filter(opt => opt.checked)
                  .map(opt => opt.value));
                }
             }

        }
2
répondu Abhishek Srivastava 2016-12-02 14:06:03
la source

additionnez mes 5 cents) Ma question

{
   name: "what_is_it",
   options:[
     {
      label: 'Option name',
      value: '1'
     },
     {
      label: 'Option name 2',
      value: '2'
     }
   ]
}

modèle.html

<div class="question"  formGroupName="{{ question.name }}">
<div *ngFor="let opt of question.options; index as i" class="question__answer" >
  <input 
    type="checkbox" id="{{question.name}}_{{i}}"
    [name]="question.name" class="hidden question__input" 
    [value]="opt.value" 
    [formControlName]="opt.label"
   >
  <label for="{{question.name}}_{{i}}" class="question__label question__label_checkbox">
      {{opt.label}}
  </label>
</div>

composant.ts

 onSubmit() {
    let formModel = {};
    for (let key in this.form.value) {
      if (typeof this.form.value[key] !== 'object') { 
        formModel[key] = this.form.value[key]
      } else { //if formgroup item
        formModel[key] = '';
        for (let k in this.form.value[key]) {
          if (this.form.value[key][k])
            formModel[key] = formModel[key] + k + ';'; //create string with ';' separators like 'a;b;c'
        }
      }
    }
     console.log(formModel)
   }
1
répondu Chemaxa 2017-08-26 22:54:34
la source

ma solution-résolu pour L'Angle 5 avec la vue du matériel

La connexion est à travers l'

formArrayName= "notification"

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

de cette façon, il peut fonctionner pour des tableaux de cases à cocher multiples dans une forme. Il suffit de définir le nom du tableau de commandes pour se connecter à chaque fois.

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>

À la fin vous obtenez à sauvegardez le formulaire avec le tableau des id d'enregistrements originaux pour sauvegarder/mettre à jour. The UI View

The relevat part of the json of the form

serons heureux d'avoir de vos remarques pour l'améliorer.

1
répondu Tzvi Gregory Kaidanov 2018-05-23 14:58:53
la source

il est beaucoup plus facile de faire cela dans Angular 6 qu'il ne l'était dans les versions précédentes, même si les informations de la case à cocher sont chargées de manière asynchrone à partir d'une API.

La première chose à réaliser est que, grâce à Angulaires 6 keyvalue tuyau nous n'avons pas besoin d'avoir à utiliser FormArray plus, et peut à la place nicher un FormGroup.

tout d'Abord, passer FormBuilder dans le constructeur

constructor(
    private _formBuilder: FormBuilder,
) { }

alors initialisez notre formulaire.

ngOnInit() {

    this.form = this._formBuilder.group({
        'checkboxes': this._formBuilder.group({}),
    });

}

lorsque notre checkbox options données est disponible, itérez-le et nous pouvons le pousser directement dans le emboîté FormGroupFormControl, sans devoir compter sur des tableaux de recherche indexés par nombre.

options.forEach((option: any) => {
    const checkboxes = <FormGroup>this.form.get('checkboxes');
    checkboxes.addControl(option.title, new FormControl(true));
});

enfin, dans le modèle nous avons juste besoin d'itérer le keyvalue des cases à cocher: pas de let index = i, et les cases à cocher sera automatiquement dans l'ordre alphabétique: beaucoup plus propre.

<form [formGroup]="form">

    <h3>Options</h3>

    <div formGroupName="checkboxes">

        <ul>
            <li *ngFor="let item of form.get('checkboxes').value | keyvalue">
                <label>
                    <input type="checkbox" [formControlName]="item.key" [value]="item.value" /> {{ item.key }}
                </label>
            </li>
        </ul>

    </div>

</form>
0
répondu Danny Pritchard 2018-09-17 18:14:24
la source

Autres questions sur javascript angular checkbox angular2-forms