Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular - How to reorder items in FormArray?

Tags:

angular

I have a large form that contains a bunch of controls. Within this form, I have an array of form groups which are my "rules".

I need to add the ability to change the order of the rule, not only its value but its visual place in the DOM.

Here is what my setup looks like:

enter image description here

Each one of those rules is a component that has its own form groups etc. The order they are initially displayed is based on their current stored processing order value.

Below each rule I have a button to move the rule up or down which is what I am working on.

With reactive forms, does the index of a form group determine its position in the component UI? For example, if I wanted to move a rule up, could I change that form groups index to currentIndex-1 and perhaps the rule above to +1 in order to change places?

My goal here is to be able to move those components up and down on the UI. I am trying to stay away from a drag and drop library due to the amount of rules on this page.

Update:

Here is a plunker of my setup:

https://plnkr.co/edit/S77zywAa7l900F0Daedv?p=preview

like image 960
SBB Avatar asked Sep 28 '17 00:09

SBB


2 Answers

There are several methods on FormArray like removeAt and insert that can help you to achieve your goal.

template.html

<button class="button" (click)="move(-1, i)">Move Up</button> &nbsp; 
<button class="button" (click)="move(1, i)">Move Down</button>

component.ts

move(shift, currentIndex) {
  const rules = this.rulesForm.get('ruleData.rules') as FormArray;

  let newIndex: number = currentIndex + shift;
  if(newIndex === -1) {
    newIndex = rules.length - 1;
  } else if(newIndex == rules.length) {
    newIndex = 0;
  }

  const currentGroup = rules.at(currentIndex);
  rules.removeAt(currentIndex);
  rules.insert(newIndex, currentGroup)
}

Plunker Example

like image 73
yurzui Avatar answered Oct 17 '22 02:10

yurzui


Here is a short es6 version of "move" method:

move(shift: number, i: number,): void {
    const { controls } = this.rulesForm.get('ruleData.rules');
    [ controls[i], controls[i+shift] ] = [ controls[i+shift], controls[i] ];
    this.rulesForm.patchValue(controls);
}

Plunker Example

like image 22
Dima Petrashchuk Avatar answered Oct 17 '22 01:10

Dima Petrashchuk