Angular : Select Drop-Down (Mat-Select) with search-in and fill with DB. Problem with initial...

Discussão em 'Angular' iniciado por xNiux, Novembro 25, 2024.

  1. xNiux

    xNiux Guest

    I'm currently create a request form in Angular to search in a database SQL. I fill a Mat-Select with values in DB, and set the initial value at "Toutes". But since the Search in implementation, the Mat-Select is blank at page loading...

    I tried to initialize the value in the HTML file with [(value)] set to a string in TS file. it's work only without the search'in filter.

    I'm initializing the array of options values in the constructor with db request, at the end of request, I call the initializing filter select.

    See the HTML code :

    <form [formGroup]="requestRessourcesForm" (ngSubmit)="onSubmit(f)" #f="ngForm">

    <div class="container-fluid">

    <div class="row d-flex align-items-center justify-content-center">

    <!-- RESSOURCE -->
    <div class="col-12 sub-section" name="ressource">

    <label class="border-lable-flt">

    <div class="container panel-style">

    <mat-form-field class="general-margin border-lable-flt">

    <mat-label class="label-section"></mat-label>

    <mat-select [(value)]="optionRessourceToutes" [placeholder]="dbRessources" [formControl]="ressourceCtrl" #ressourceSelector>

    <mat-option>
    <ngx-mat-select-search [formControl]="ressourceFilterCtrl" [placeholderLabel]="'Rechercher...'"
    [noEntriesFoundLabel]="'Aucune'"></ngx-mat-select-search>
    </mat-option>

    <mat-option *ngFor="let ressource of filteredRessources | async" [value]="ressource.Name">
    {{ressource.Name}}
    </mat-option>

    </mat-select>

    </mat-form-field>
    <p>
    Selected Ressource : {{ressourceCtrl.value?.Name}}
    </p>
    </div>

    <span>Ressource</span>

    </label>

    </div>

    </div>

    </form>


    And the TS Code :

    import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
    import { NgForm, FormBuilder, FormGroup, FormControl, FormArray } from '@angular/forms';
    import { MatSelect } from '@angular/material/select';
    import { HttpClient } from '@angular/common/http';
    import { ReplaySubject, Subject } from 'rxjs';
    import { take, takeUntil } from 'rxjs/operators';


    import { Ressource } from '../models/ressource.model';
    import { environment } from '../../environments/environment';



    @Component({
    selector: 'app-ressourcesplanetairesforms',
    templateUrl: './ressourcesplanetairesforms.component.html',
    styleUrls: ['./ressourcesplanetairesforms.component.scss']
    })


    export class RessourcesplanetairesformsComponent implements OnInit, AfterViewInit, OnDestroy {

    /*########### SQL Data ###########*/
    dbRessources: Ressource[] = [];
    public optionRessourceToutes = 'Toutes';

    requestRessourcesForm: FormGroup;

    /** control for the selected ressource */
    public ressourceCtrl: FormControl = new FormControl();

    /** control for the MatSelect filter keyword */
    public ressourceFilterCtrl: FormControl = new FormControl();

    /** list of ressources filtered by search keyword */
    public filteredRessources: ReplaySubject<Ressource[]> = new ReplaySubject<Ressource[]>(1);

    @ViewChild('ressourceSelector', { static: true }) ressourceSelect: MatSelect;

    /** Subject that emits when the component has been destroyed. */
    protected _onDestroy = new Subject<void>();


    constructor(private http: HttpClient, private formBuilder: FormBuilder) {


    var dbUrlPath = "./assets/db_management/";
    var dbUrlFile_Ressource;

    if (environment.production == false) {
    dbUrlFile_Ressource = "ressources_list.json";
    }
    else {
    dbUrlFile_Ressource = "ressources_list.php";
    }

    // PHP/SQL Requester : Ressource
    this.dbRessources.push(new Ressource("Toutes", null));

    this.http.get<any[]>(dbUrlPath + dbUrlFile_Ressource).subscribe(data => {
    data.forEach(element => {
    this.dbRessources.push(new Ressource(element["Name"], null));
    });

    this.InitializeRessourceSelector();
    }, error => console.error(error));

    }

    ngOnInit(): void {
    }

    ngAfterViewInit() {
    }

    ngOnDestroy() {
    this._onDestroy.next();
    this._onDestroy.complete();
    }

    onSubmit(form: NgForm) {
    console.log(form.value);

    }


    // Initialize MatSelect form
    InitializeRessourceSelector(): void {
    // Set the filters
    // set initial selection
    this.ressourceCtrl.setValue(this.dbRessources[0]);

    // load the initial ressource list
    this.filteredRessources.next(this.dbRessources.slice());

    // listen for search field value changes
    this.ressourceFilterCtrl.valueChanges
    .pipe(takeUntil(this._onDestroy))
    .subscribe(() => {
    this.filterRessources();
    });


    this.setInitialValue();
    }

    /**
    * Sets the initial value after the filteredRessources are loaded initially
    */
    protected setInitialValue() {
    this.filteredRessources
    .pipe(take(1), takeUntil(this._onDestroy))
    .subscribe(() => {
    // setting the compareWith property to a comparison function
    // triggers initializing the selection according to the initial value of
    // the form control (i.e. _initializeSelection())
    // this needs to be done after the filteredRessources are loaded initially
    // and after the mat-option elements are available
    this.ressourceSelect.compareWith = (a: Ressource, b: Ressource) => a && b && a.Name === b.Name;
    });
    }

    protected filterRessources() {
    if (!this.dbRessources) {
    return;
    }

    // get the search keyword
    let search = this.ressourceFilterCtrl.value;

    if (!search) {
    this.filteredRessources.next(this.dbRessources.slice());
    return;
    }
    else {
    search = search.toLowerCase();
    }
    // filter the Ressources
    this.filteredRessources.next(
    this.dbRessources.filter(res => res.Name.toLowerCase().indexOf(search) > -1)
    );
    }
    }


    Where is my mistake ?

    Continue reading...

Compartilhe esta Página