Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

339
Visualizações
Check if there is a duplicate item in FormGroups field in Angular reactive form

While saving all my grid rows, I need to check whether there is a duplicate for a specific column field

 (this.formGroups.get('items') as FormArray).controls.forEach((item) => {
    console.log(item.value.attributeDisplayName);       
  });

I need to stop the form from submission by showing an alert or something similar when there is a duplicate value for attributeDisplayName. How can I check that in the current forEach loop. Thanks

I am using kendo angular components in my HTML markup and I am not using form tag. Below is an example for column declaration

  <kendo-grid-column field="attributeDisplayName" title="CUSTOM FIELD LABEL" width="190">  
        <ng-template kendoGridEditTemplate let-column="column" let-formGroup="formGroup" >          
          <input ngDefaultControl  class="k-textbox" [formControl]="formGroup.get(column.field)">
          
          <div *ngIf="formGroup.get(column.field).errors && (formGroup.get(column.field).dirty || formGroup.get(column.field).touched)">
                <span style="color:red" class="k-icon k-i-warning"></span>
                <span style="color:red">CUSTOM FIELD LABEL is a required field</span>
                
          </div>

        </ng-template>
    </kendo-grid-column>

Below is FormGroup declartion in .ts file

    public formGroup: FormGroup;
    public formGroups: FormGroup = new FormGroup({ items: new FormArray([]) });
    
    public createFormGroup = (dataItem) =>
        new FormGroup({
            atrributeId: new FormControl(dataItem.atrributeId),
            objectType: new FormControl(dataItem.objectType, Validators.required),
            attributeDisplayName: new FormControl(dataItem.attributeDisplayName, Validators.required),     
            dataType: new FormControl(dataItem.dataType, Validators.required),
            inputValues: new FormControl(dataItem.inputValues, [Validators.required,  InputValuesValidator]),
            isGridEligible: new FormControl(dataItem.isGridEligible, Validators.required),
            isInvoiceEligible: new FormControl(dataItem.isInvoiceEligible, Validators.required),
        });

An example function where I use this FormGroup

    public editRows(grid) {      
      this.isEdited = true;
      let currentRow = 0;
      let rows: any = grid.data.data;
  
      for (let i = 0; i < rows.length; i++) {
        const formGroup = this.createFormGroup(rows[i]);          
        this.formGroup = formGroup;
        (this.formGroups.get('items') as FormArray).push(formGroup);        
        grid.editRow(currentRow, formGroup, {skipFocus: true});
        currentRow++;
      }      
    }
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Instead of checking it while submitting, just check it while filling form only and show the error immediately if user has filled duplicate value.

Working demo here.

use this function to check duplicacy -

checkDuplicacy(event, field: FormControl) {
    let length = this.formGroups.value.items.length;
    let count = 0;
    let controls = (<FormArray>this.formGroups.controls.items).controls;
    for (let i = 0; i < length; i++) {
      if (
        this.formGroups.value.items[i].attributeDisplayName.toLowerCase() ==
        event.target.value.toLowerCase()
      ) {
        count++;
      }
      if (count > 1) {
        field.markAsTouched();
        field.setValidators((f) => <any>{ duplicateName: true });
        field.updateValueAndValidity();
      } else {
        field.clearValidators();
        field.setValidators([Validators.required]);
        field.updateValueAndValidity();
      }
    }
  }

And Updated HTML -

    <kendo-grid-column field="attributeDisplayName" title="CUSTOM FIELD LABEL" width="190">  
<ng-template kendoGridEditTemplate let-column="column" let-formGroup="formGroup" >          
  <input ngDefaultControl  class="k-textbox" [formControl]="formGroup.get(column.field)" (blur)="checkDuplicacy($event, formGroup.get(column.field))">
  

      <div *ngIf="formGroup.get(column.field).errors && (formGroup.get(column.field).dirty || formGroup.get(column.field).touched)">
            <span style="color:red" class="k-icon k-i-warning"></span>
            <span style="color:red">CUSTOM FIELD LABEL is a required field</span>
            
      </div>
    
      <span *ngIf="formGroup.get(column.field).errors?.duplicateName" style="color:red">
      Duplicate field.</span>
    
    </ng-template>
    </kendo-grid-column>
over 4 years ago · Santiago Trujillo Relatório

0

Of course you can use a validator to check the duplicates. The validator is like

  validateUniq(index) {
    return (control: AbstractControl) => {
      if (control.value) {

        //search the "formArray"
        const formArray = control.parent
          ? (control.parent.parent as FormArray)
          : null;

        if (formArray) {
          //we create an array with the attributeDisplayNames
          const attributes = formArray.value.map((x) => x.attributeDisplayName);
      
          //only give error if there're duplicate before our
          //control
      
          return attributes.indexOf(control.value)>=0 && 
                 attributes.indexOf(control.value)<index
            ? { duplicateName: true }
            : null;
        }
      }
    };
  }

You create the formGroup like -see how you pass the "index"

  initFormField() {
    const index = this.items ? this.items.length : 0;
    return this.fb.group({
      attributeDisplayName: [
        '',
        [Validators.required, this.validateUniq(index)],
      ],
    });
  }

The problem when we use a Validator over a control is that only is checked when the control changes, so we need make a function checkDuplicacy like @Shyam say -but in this case is more simple:

  checkDuplicacy(index) {
    this.items.controls.forEach((x,i)=>{
      if (index!=i)
        (x as FormGroup).get('attributeDisplayName').updateValueAndValidity()
    })
  }

The last piece to completate the jigsaw is a function to get the control

  getAtributeDisplayNameAt(index: number) {
    return this.items
      ? (this.items.at(index).get('attributeDisplayName') as FormControl)
      : null;
  }

And an html like

<form [formGroup]="formGroups" novalidate autocomplete="off">
  <div formArrayName="items">
    <div
      *ngFor="let item of items.controls; let index = index"
      [formGroupName]="index"
    >
      <div class="form-control">
        <input
          placeholder="Enter here"
          formControlName="attributeDisplayName" 
          (input)="checkDuplicacy(index)"
        />
        <span
          *ngIf="getAtributeDisplayNameAt(index)?.errors?.duplicateName"
          class="error"
        >
          Duplicate field.</span
        >
      </div>
    </div>
  </div>
  <button (click)="addFormField()">Add More</button>
</form>

See how we call to the function checkDuplicacy in the event input -you can subscribe also to the valueChange of the control

The stackblitz

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda