@angular/forms#FormArray TypeScript Examples

The following examples show how to use @angular/forms#FormArray. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: form-validator-util.ts    From data-annotator-for-machine-learning with Apache License 2.0 7 votes vote down vote up
static markControlsAsTouched(formElement: AbstractControl): void {
    if (formElement instanceof FormControl) {
      formElement.markAsTouched();
    } else if (formElement instanceof FormGroup) {
      Object.keys(formElement.controls).forEach((key) => {
        this.markControlsAsTouched(formElement.get(key));
      });
    } else if (formElement instanceof FormArray) {
      formElement.controls.forEach((control) => {
        this.markControlsAsTouched(control);
      });
    }
  }
Example #2
Source File: announce-module.component.ts    From 6PG-Dashboard with MIT License 6 votes vote down vote up
buildForm({ announce }: any) {
    const formGroup = new FormGroup({ events: new FormArray([]) });
    
    for (let i = 0; i < this.events.length; i++) {
      const event = this.events[i];
      const config = announce.events.find(e => e.event === event); 

      (formGroup.get('events') as FormArray).push(new FormGroup({
        event: new FormControl(event),
        enabled: new FormControl(Boolean(config?.channelName && config?.message) ?? false),
        channelName: new FormControl(config?.channelName ?? ''),
        message: new FormControl(config?.message ?? `\`${EventType[event]}\` was triggered in **[GUILD]**!`, Validators.maxLength(512))
      }));     
    }
    return formGroup;
  }
Example #3
Source File: entity-type-form.component.ts    From radiopanel with GNU General Public License v3.0 6 votes vote down vote up
public removeField(i: number, subfieldIndex?: number) {
		const fieldsGroup = this.form.get('fields') as FormArray;

		if (subfieldIndex !== undefined) {
			return (fieldsGroup.at(subfieldIndex).get('subfields') as FormArray).removeAt(i);
		}

		fieldsGroup.removeAt(i);
	}
Example #4
Source File: custom-inputs-fields-form.component.ts    From fyle-mobile-app with MIT License 6 votes vote down vote up
generateCustomForm() {
    const customFieldsFormArray = this.customFieldsForm?.controls?.fields as FormArray;
    customFieldsFormArray.clear();
    for (const customField of this.customInputs) {
      customFieldsFormArray.push(
        this.formBuilder.group({
          name: [customField.name],
          value: [customField.value],
        })
      );
    }
    customFieldsFormArray.updateValueAndValidity();
    this.customFields = this.customInputs.map((customField, i) => ({
      ...customField,
      control: customFieldsFormArray.at(i),
    }));
  }
Example #5
Source File: entity-type-form.component.ts    From radiopanel with GNU General Public License v3.0 6 votes vote down vote up
public pushFieldToArray(field, subfieldIndex?: number): void {
		const config = (field.config || []).reduce((acc, fieldConfig) => ({
			...acc,
			[fieldConfig.identifier]: ['']
		}), {});

		const fieldForm = this.formBuilder.group({
			name: [field.name],
			slug: [''],
			fieldType: [field.identifier],
			multiLanguage: [false],
			showOnOverview: [false],
			config: this.formBuilder.group(config),
			subfields: this.formBuilder.array([])
		});

		fieldForm.get('name').valueChanges
			.pipe(
				takeUntil(this.componentDestroyed$)
			).subscribe((value) => fieldForm.patchValue({
				slug: camelCase(value)
			}));

		if (subfieldIndex !== undefined) {
			return ((this.form.get('fields') as FormArray).at(subfieldIndex).get('subfields') as FormArray).push(fieldForm);
		}

		(this.form.get('fields') as FormArray).push(fieldForm);
	}
Example #6
Source File: forms-typed.ts    From forms-typed with MIT License 6 votes vote down vote up
/**
 * A helper function to create a `TypedFormArray`. It only calls the constructor of FormArray, but **strongly types** the result.
 * @param v the value to initialize our `TypedFormArray` with - same as in `new TypedFormArray(v, validators, asyncValidators)`
 * @param validators validators - same as in new `TypedFormArray(v, validators, asyncValidators)`
 * @param asyncValidators async validators - same as in `new TypedFormArray(v, validators, asyncValidators)`
 *
 * @example
 * const c = typedFormArray<string>([typedFormControl('of type string')]): TypedFormArray<string[], string>;
 * c.valueChanges // Observable<string[]>
 * c.patchValue(['s']) // expects string[]
 * c.patchValue(1) //  COMPILE TIME! type error!
 */
export function typedFormArray<T = any, K extends Array<T> = T[]>(
  controls: Array<TypedFormControl<T>>,
  validatorOrOptions?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
  asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null
): TypedFormArray<K, T> {
  return new FormArray(controls, validatorOrOptions, asyncValidators) as any;
}
Example #7
Source File: entity-type-form.component.ts    From radiopanel with GNU General Public License v3.0 6 votes vote down vote up
public ngOnChanges(changes: any) {
		if (!changes.entityType) {
			return;
		}

		const entityType = changes.entityType.currentValue;
		this.form.patchValue({
			...entityType,
			workflow: pathOr('', ['workflow', 'uuid'])(entityType)
		});

		const fieldsGroup = this.form.get('fields') as FormArray;
		this.buildFieldsArray((propOr([], 'fields')(entityType) as any[])).map((formGroup) => {
			fieldsGroup.push(formGroup);
		});
	}
Example #8
Source File: form-factory.service.ts    From open-source with MIT License 6 votes vote down vote up
/**
   * Append a control to a given parent in the specified name.
   */
  append(parent: AbstractControl, name: string, control: AbstractControl): void {
    // only FormGroup can be extended
    if (parent instanceof FormGroup) {
      parent.addControl(name, control);
    } else if (parent instanceof FormArray) {
      parent.push(control);
    }
  }
Example #9
Source File: entity-type-form.component.ts    From radiopanel with GNU General Public License v3.0 6 votes vote down vote up
public pushFieldToArray(field, subfieldIndex?: number): void {
		const config = (field.config || []).reduce((acc, fieldConfig) => ({
			...acc,
			[fieldConfig.identifier]: ['']
		}), {});

		const fieldForm = this.formBuilder.group({
			name: [field.name],
			slug: [''],
			fieldType: [field.identifier],
			multiLanguage: [false],
			showOnOverview: [false],
			config: this.formBuilder.group(config),
			subfields: this.formBuilder.array([])
		});

		fieldForm.get('name').valueChanges
			.pipe(
				takeUntil(this.componentDestroyed$)
			).subscribe((value) => fieldForm.patchValue({
				slug: camelCase(value)
			}));

		if (subfieldIndex !== undefined) {
			return ((this.form.get('fields') as FormArray).at(subfieldIndex).get('subfields') as FormArray).push(fieldForm);
		}

		(this.form.get('fields') as FormArray).push(fieldForm);
	}
Example #10
Source File: option-value-unique.validator.ts    From digital-bank-ui with Mozilla Public License 2.0 6 votes vote down vote up
export function optionValueUnique(array: FormArray): ValidationErrors | null {
  const options: FormGroup[] = array.controls as FormGroup[];

  const values = options.map(optionGroup => parseInt(optionGroup.get('value').value, 10));

  const set = new Set();

  values.forEach(number => set.add(number));

  if (set.size !== values.length) {
    return {
      optionValueUnique: true,
    };
  }

  return null;
}
Example #11
Source File: entity-type-form.component.ts    From radiopanel with GNU General Public License v3.0 6 votes vote down vote up
public ngOnChanges(changes: any) {
		if (!changes.entityType) {
			return;
		}

		const entityType = changes.entityType.currentValue;
		this.form.patchValue({
			...entityType,
			workflow: pathOr('', ['workflow', 'uuid'])(entityType)
		});

		const fieldsGroup = this.form.get('fields') as FormArray;
		this.buildFieldsArray((propOr([], 'fields')(entityType) as any[])).map((formGroup) => {
			fieldsGroup.push(formGroup);
		});
	}
Example #12
Source File: register-intention.component.ts    From scion-microfrontend-platform with Eclipse Public License 2.0 6 votes vote down vote up
public onRegister(): void {
    this.registerResponse = undefined;
    this.registerError = undefined;

    const intention: Intention = {
      type: this.registerForm.get(TYPE).value,
      qualifier: SciParamsEnterComponent.toParamsDictionary(this.registerForm.get(QUALIFIER) as FormArray),
    };

    Beans.get(ManifestService).registerIntention(intention)
      .then(id => {
        this.registerResponse = id;
      })
      .catch(error => {
        this.registerError = error;
      })
      .finally(() => {
        this.registerForm.reset();
        this.registerForm.setControl(QUALIFIER, new FormArray([]));
      });
  }
Example #13
Source File: commands-module.component.ts    From 6PG-Dashboard with MIT License 6 votes vote down vote up
async buildForm({ commands }: any) { 
    const formGroup = new FormGroup({
      configs: new FormArray([])
    });

    for (let i = 0; i < this.commands.length; i++) {
      const command = commands[i];
      (formGroup.get('configs') as FormArray)
        .setControl(i, new FormGroup({
          name: new FormControl(this.commands[i].name ?? ''),
          enabled: new FormControl(command?.enabled ?? true)
        }));
    }
    return formGroup;
  }
Example #14
Source File: publish-message.component.ts    From scion-microfrontend-platform with Eclipse Public License 2.0 6 votes vote down vote up
private publishMessage(): void {
    const topic = this.form.get(DESTINATION).get(TOPIC).value;
    const message = this.form.get(MESSAGE).value === '' ? undefined : this.form.get(MESSAGE).value;
    const requestReply = this.form.get(REQUEST_REPLY).value;
    const headers = SciParamsEnterComponent.toParamsMap(this.form.get(HEADERS) as FormArray);

    this.markPublishing(true);
    this.publishError = null;
    try {
      if (requestReply) {
        this._requestResponseSubscription = this._messageClient.request$(topic, message, {headers: headers})
          .pipe(finalize(() => this.markPublishing(false)))
          .subscribe({
            next: reply => this.replies.push(reply),
            error: error => this.publishError = error,
          });
      }
      else {
        this._messageClient.publish(topic, message, {retain: this.form.get(RETAIN).value, headers: headers})
          .catch(error => {
            this.publishError = error;
          })
          .finally(() => {
            this.markPublishing(false);
          });
      }
    }
    catch (error) {
      this.markPublishing(false);
      this.publishError = error;
    }
  }
Example #15
Source File: add-edit-advance-request.page.ts    From fyle-mobile-app with MIT License 6 votes vote down vote up
ngOnInit() {
    this.id = this.activatedRoute.snapshot.params.id;
    this.from = this.activatedRoute.snapshot.params.from;
    this.fg = this.formBuilder.group({
      currencyObj: [, this.currencyObjValidator],
      purpose: [, Validators.required],
      notes: [],
      project: [],
      custom_field_values: new FormArray([]),
    });

    if (!this.id) {
      this.advanceActions = {
        can_save: true,
        can_submit: true,
      };
    }

    this.expenseFields$ = this.offlineService.getExpenseFieldsMap();
  }
Example #16
Source File: lookup-capability.component.ts    From scion-microfrontend-platform with Eclipse Public License 2.0 6 votes vote down vote up
public onLookup(): void {
    const nilQualifierIfEmpty = this.form.get(NILQUALIFIER_IF_EMPTY).value;
    const qualifier = SciParamsEnterComponent.toParamsDictionary(this.form.get(QUALIFIER) as FormArray, false);
    const nilQualifierOrUndefined = nilQualifierIfEmpty ? {} : undefined;

    const filter: ManifestObjectFilter = {
      id: this.form.get(ID).value || undefined,
      type: this.form.get(TYPE).value || undefined,
      qualifier: Object.keys(qualifier).length ? qualifier : nilQualifierOrUndefined,
      appSymbolicName: this.form.get(APP_SYMBOLIC_NAME).value || undefined,
    };
    this.capabilities$ = Beans.get(ManifestService).lookupCapabilities$(filter)
      .pipe(finalize(() => this.capabilities$ = null));
  }
Example #17
Source File: cycle-item.component.spec.ts    From HeartBeat with MIT License 6 votes vote down vote up
describe('CycleColumnComponent', () => {
  let component: CycleItemComponent;
  let fixture: ComponentFixture<CycleItemComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [MatSelectModule, BrowserAnimationsModule],
      declarations: [CycleItemComponent, MatError],
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(CycleItemComponent);
    component = fixture.componentInstance;
    component.metricsForm = new FormGroup({
      cycleTime: new FormGroup({
        jiraColumns: new FormArray([
          new FormGroup({
            key: new FormArray([new FormControl('')]),
          }),
        ]),
      }),
    });
    component.groupName = '0';
    component.columnItemKey = 'key';
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
Example #18
Source File: leveling-module.component.ts    From 6PG-Dashboard with MIT License 6 votes vote down vote up
private buildLevelRolesFormArray(formGroup: FormGroup, leveling: any) {
    for (const i of this.levelRoleIndices)
      (formGroup.get('levelRoleNames') as FormArray)
        .setControl(i,
          (new FormGroup({
          level: new FormControl(leveling.levelRoleNames[i]?.level ?? 0, Validators.min(0)),
          roleName: new FormControl(leveling.levelRoleNames[i]?.roleName ?? '')
        })));
  }
Example #19
Source File: pipeline-item.component.spec.ts    From HeartBeat with MIT License 6 votes vote down vote up
describe('PipelineItemComponent', () => {
  let component: PipelineItemComponent;
  let fixture: ComponentFixture<PipelineItemComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule, MatSnackBarModule, MatSelectModule, BrowserAnimationsModule],
      declarations: [PipelineItemComponent],
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(PipelineItemComponent);
    component = fixture.componentInstance;
    component.metricsForm = new FormGroup({
      test: new FormArray([]),
    });
    component.formArrayName = 'test';
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
Example #20
Source File: leveling-module.component.ts    From 6PG-Dashboard with MIT License 6 votes vote down vote up
buildForm({ leveling }: any) {
    const formGroup = new FormGroup({
      ignoredRoleNames: new FormControl(leveling.ignoredRoleNames ?? []),
      levelRoleNames: new FormArray([]),
      maxMessagesPerMinute: new FormControl(leveling.maxMessagesPerMinute ?? 3,
        [ Validators.min(1), Validators.max(30) ]),
      xpPerMessage: new FormControl(leveling.xpPerMessage ?? 50,
        [ Validators.min(0), Validators.max(10000) ])
    });
    this.buildLevelRolesFormArray(formGroup, leveling);
    return formGroup;
  }
Example #21
Source File: register-capability.component.ts    From scion-microfrontend-platform with Eclipse Public License 2.0 6 votes vote down vote up
public onUnregister(): void {
    this.unregisterResponse = undefined;
    this.unregisterError = undefined;

    const nilQualifierIfEmpty = this.unregisterForm.get(NILQUALIFIER_IF_EMPTY).value;
    const qualifier = SciParamsEnterComponent.toParamsDictionary(this.unregisterForm.get(QUALIFIER) as FormArray, false);
    const nilQualifierOrUndefined = nilQualifierIfEmpty ? {} : undefined;

    const filter: ManifestObjectFilter = {
      id: this.unregisterForm.get(ID).value || undefined,
      type: this.unregisterForm.get(TYPE).value || undefined,
      qualifier: Object.keys(qualifier).length ? qualifier : nilQualifierOrUndefined,
      appSymbolicName: this.unregisterForm.get(APP_SYMBOLIC_NAME).value || undefined,
    };

    Beans.get(ManifestService).unregisterCapabilities(filter)
      .then(() => {
        this.unregisterResponse = 'OK';
      })
      .catch(error => {
        this.unregisterError = error;
      })
      .finally(() => {
        this.unregisterForm.reset();
        this.unregisterForm.setControl(QUALIFIER, new FormArray([]));
      });
  }
Example #22
Source File: entity-type-form.component.ts    From radiopanel with GNU General Public License v3.0 5 votes vote down vote up
public rebuildFieldsArray(formArray: FormArray, newStructure: any[]) {
		formArray.clear();

		const newFormArray = this.buildFieldsArray(newStructure);
		newFormArray.map((formGroup) => {
			formArray.push(formGroup);
		});
	}
Example #23
Source File: cycle-time.component.ts    From HeartBeat with MIT License 5 votes vote down vote up
validatorFn(): ValidatorFn {
    return (group: FormArray): ValidationErrors | null => {
      const selectedDones = group.value.filter((item) => Object.values(item)[0] === this.doneValue);
      this.isValid = selectedDones.length <= 1;
      return this.isValid ? null : { formValid: false };
    };
  }
Example #24
Source File: slot-fields.page.ts    From radiopanel with GNU General Public License v3.0 5 votes vote down vote up
public handleFieldsUpdate(newFieldsOrder: any[], subfieldIndex?: number) {
		if (subfieldIndex !== undefined) {
			return this.rebuildFieldsArray((this.form.get('fields') as FormArray).at(0).get('subfields') as FormArray, newFieldsOrder);
		}

		this.rebuildFieldsArray(this.form.get('fields') as FormArray, newFieldsOrder);
	}
Example #25
Source File: metric-pipeline.component.ts    From HeartBeat with MIT License 5 votes vote down vote up
validatorFn(): ValidatorFn {
    return (group: FormArray): ValidationErrors | null => {
      const isDuplicated = this.validateArray(group.value);
      return !isDuplicated ? null : { formValid: false };
    };
  }
Example #26
Source File: form.component.ts    From digital-bank-ui with Mozilla Public License 2.0 5 votes vote down vote up
addCommand(value?: TaskDefinitionCommand): void {
    const commands: FormArray = this.form.get('commands') as FormArray;
    commands.push(this.initCommand(value));
  }
Example #27
Source File: entity-type-form.component.ts    From radiopanel with GNU General Public License v3.0 5 votes vote down vote up
public handleFieldsUpdate(newFieldsOrder: any[], subfieldIndex?: number) {
		if (subfieldIndex !== undefined) {
			return this.rebuildFieldsArray((this.form.get('fields') as FormArray).at(0).get('subfields') as FormArray, newFieldsOrder);
		}

		this.rebuildFieldsArray(this.form.get('fields') as FormArray, newFieldsOrder);
	}
Example #28
Source File: add.component.ts    From spurtcommerce with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public sizeFormArray: FormArray;
Example #29
Source File: announce-module.component.spec.ts    From 6PG-Dashboard with MIT License 5 votes vote down vote up
describe('AnnounceModuleComponent', () => {
  let component: AnnounceModuleComponent;
  let fixture: ComponentFixture<AnnounceModuleComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ AnnounceModuleComponent ],
      imports: [ 
        HttpClientModule,
        MatSnackBarModule, 
        AppRoutingModule,
        ReactiveFormsModule
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AnnounceModuleComponent);
    component = fixture.componentInstance;
    component.guildId = environment.test.guildId;
    fixture.detectChanges();

    component.init = async() => {};
    component.savedBot = { announce: { events: {}}};
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('saved guild overwrites default input values', () => {
    const events = [
    {
      event: EventType.MemberJoin,
      channel: '123',
      message: 'a'
    } as AnnounceEvent ];
    component.savedBot = { announce: { events }};
    component.guildId = '123';

    const result = (component.form.get('events') as FormArray).get('0').value;

    expect(result).toEqual(events[0]);
  });

  it('submitting removes enabled property', () => {
    component = new AnnounceModuleComponent({} as any, {} as any, {} as any);
    const events = [
    {
      event: EventType.MemberJoin,
      channel: '123',
      enabled: false,
      message: 'a'
    } as AnnounceEvent ];

    component.form.setValue({ events });
    component.submit();

    const result = component.form.get('events').get('0').value.enabled;

    expect(result).toBeUndefined();
  });
});