How to validate that 2 folders on the same level cannot have the same name in a recursive...

Discussão em 'Angular' iniciado por binga58, Janeiro 5, 2025.

  1. binga58

    binga58 Guest

    I'm not sure if my question title is clear enough but i will try to give more details. I try to create a folder hierarchy form using angular forms. The form can have unlimited nesting. My problem is that now I can add 2 folders with the same name on a certain level but this should not be possible and should warn the user. This is logical because in a normal file system 2 folders cannot have same name

    I present a simplified version here for clarity. still a bit long to read but here is reproducible demo in stackblitz with same code

    form component

    @Component({
    selector: 'my-form',
    templateUrl: './form.component.html',
    styleUrls: ['./form.component.css'],
    })
    export class FormComponent implements OnInit {
    myForm!: FormGroup;
    isHierarchyVisible: boolean = false;

    constructor(private formBuilder: FormBuilder) {}

    ngOnInit() {
    this.myForm = this.formBuilder.group({
    folderHierarchy: this.formBuilder.array([]),
    });
    if (this.folderHierarchy.length === 0) this.isHierarchyVisible = false;
    }

    removeFolder(index: number): void {
    this.folderHierarchy.removeAt(index);
    if (this.folderHierarchy.length === 0) this.isHierarchyVisible = false;
    }

    addFolder(): void {
    this.folderHierarchy.push(
    this.formBuilder.group({
    name: [null, [Validators.required]],
    subFolders: this.formBuilder.array([]),
    level: 0,
    })
    );
    this.isHierarchyVisible = true;
    }

    getForm(control: AbstractControl): FormGroup {
    return control as FormGroup;
    }

    get folderHierarchy(): FormArray {
    return this.myForm.get('folderHierarchy') as FormArray;
    }
    }


    <p>folder form. type in form name and press enter</p>
    <form [formGroup]="myForm">
    <div formArrayName="folderHierarchy">
    <label for="folderHierarchy">create folder</label>
    <div>
    <button type="button" class="btn btn-custom rounded-corners btn-circle mb-2" (click)="addFolder()" [disabled]="!folderHierarchy.valid">
    Add
    </button>
    <span class="pl-1">new folder</span>
    </div>
    <div>
    <div *ngIf="!folderHierarchy.valid" class="folder-hierarchy-error">invalid folder hierarchy</div>
    <div class="folderContainer">
    <div>
    <div *ngFor="let folder of folderHierarchy.controls; let i = index" [formGroupName]="i">
    <folder-hierarchy (remove)="removeFolder(i)" [folder]="getForm(folder)" [index]="i"></folder-hierarchy>
    </div>
    </div>
    </div>
    </div>
    </div>
    </form>


    form hierarchy component

    @Component({
    selector: 'folder-hierarchy',
    templateUrl: './folder-hierarchy.component.html',
    styleUrls: ['./folder-hierarchy.component.css'],
    })
    export class FolderHierarchyComponent implements OnInit {
    constructor(private formBuilder: FormBuilder) {}
    @Output() remove = new EventEmitter();
    @Input() folder!: FormGroup;
    @Input() index!: number;
    tempName: string = '';

    ngOnInit() {}

    addSubFolder(folder: FormGroup): void {
    (folder.get('subFolders') as FormArray).push(
    this.formBuilder.group({
    name: [null, [Validators.required]],
    subFolders: this.formBuilder.array([]),
    level: folder.value.level + 1,
    })
    );
    }

    getControls(folder: FormGroup): FormGroup[] {
    return (folder.get('subFolders') as FormArray).controls as FormGroup[];
    }

    removeSubFolder(folder: FormGroup, index: number): void {
    (folder.get('subFolders') as FormArray).removeAt(index);
    }

    removeFolder(folder: { value: { subFolders: string | any[] } }): void {
    this.remove.emit(folder);
    }

    disableAdd(folder: { invalid: any }): void {
    return this.folder.invalid || folder.invalid;
    }
    onKeyup(event: KeyboardEvent): void {
    this.tempName = (event.target as HTMLInputElement).value;
    }
    updateName(folder: FormGroup, name: string): void {
    folder.get('name')?.setValue(name);
    if (this.isInvalid(folder)) {
    folder.get('name')?.updateValueAndValidity();
    return;
    }
    }

    isInvalid(folder: FormGroup): boolean {
    return !folder.get('name')?.valid;
    }
    }


    <div *ngIf="folder" #folderRow class="folder-row">
    <div class="folder-header">
    <div class="folder-name-container">
    <label for="folderName" class="folder-name-label">Name:</label>
    <input #folderName id="folderName" [ngClass]="isInvalid(folder) ? 'invalid-input' : ''" class="folder-name-input" placeholder="Folder Name" type="text" (keyup)="onKeyup($event)" maxlength="50" (keyup.enter)="updateName(folder, $any($event.target).value)" [value]="folder.value.name" autocomplete="off" />
    </div>
    <button type="button" class="btn-remove-folder" (click)="removeFolder(folder)">Remove</button>
    <button type="button" class="btn-add-subfolder" [disabled]="disableAdd(folder)" (click)="addSubFolder(folder)">Add Subfolder</button>
    </div>
    <div *ngIf="folder && folder.value.subFolders.length > 0" class="subfolder-container">
    <div *ngFor="let subFolder of getControls(folder); let i = index" class="subfolder-item">
    <folder-hierarchy (remove)="removeSubFolder(folder, i)" [folder]="subFolder"></folder-hierarchy>
    </div>
    </div>
    </div>

    Continue reading...

Compartilhe esta Página