Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material multi Select

I'm after a bit of advice with using Angular Material 7 multi selects. The documentation doesn't help that much with what I'm trying to do.

Bit of a background on what I'm trying to do.

So we are creating a record object and as part of that we need to know what Programme Funded them. The ProgrammeList is an array of Programme objects with {ProgrammeKey, Name, Description}. Previously we have used single selects and it works great. The issue is that each report can be funded by multiple Programmes so we need to use the multi Select.

Firstly, When it comes to the database. How will the multi select options be saved? The idea was that the multi-select would form its own array of selected objects and then pass them back to the back end to be saved in a Linking Table.

I have included the code below for the relevant areas

record.dto.ts

import {Programme} from "./programme.dto";

export class Record {
    Programme: Programme[];
    CcfLead: string;
    NihrRef: string;
    AddRef: string;
    AwardTitle: string;
    ProjectTitle: string;
    StartDate: Date;
    EndDate: Date;
}

general.component.ts ...

 programmes = new FormControl();
 programmeList: Programme[];

 createRecordFrm() {
        this.recordFrm = this.fb.group({
            Programme : [{}, Validators.required],
            NihrRef: ["", Validators.required],
            AddRef:[""],
            CCFLead: ["", Validators.required],
            AwardTitle: ["", Validators.required],
            ProjectTitle: ["", Validators.required],
            StartDate: Date,
            EndDate: [Date, Validators.required]
        });
    }

    updateRecordFrm(record: Record) {
        this.recordFrm.setValue({
            Programme: record.Programme,
            NihrRef: record.NihrRef,
            AddRef: record.AddRef,
            CCFLead: record.CcfLead,
            AwardTitle: record.AwardTitle,
            ProjectTitle: record.ProjectTitle,
            StartDate: record.StartDate,
            EndDate: record.EndDate
        });
    }

open(content: any, modal?: Record) {
        this.msg = null;
        this.modalMsg = null;

        if (modal != null) {
            this.updateRecordFrm(modal);
            // update recordFrm
        }

        this.activeModal = this.modalService.open(content, { ariaLabelledBy: 'modal-basic-title', backdrop: "static", keyboard: false });
    }

general.component.html

<ng-template #recordWizard let-c="close" let-d="dismiss" width="50%">
    <form novalidate (ngSubmit)="saveRecord(recordFrm.value)" [formGroup]="recordFrm">
        <div class="modal-header">
            <h4 class="modal-title" id="modal-basic-title">New Record</h4>
            <button type="button" class="close" (click)="d('Cross Click')">
                <span aria-hidden="true">&times;</span>
            </button>
        </div>
        <div class="modal-body">
            <div *ngIf="modalMsg" role="alert" class="alert alert-info alert-dismissible">
                <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <mat-icon>report_problem</mat-icon>
                <span class="sr-only">Error:</span>
                {{modalMsg}}
            </div>

            <div>
                <mat-tab-group>
                    <mat-tab label="First">
                        <div class="form-group">
                            <span>NIHR Reference*</span>
                            <input type="text" class="form-control" readonly formControlName="NihrRef" />
                        </div>
                        <div class="form-group">
                            <span>Additional Reference</span>
                            <input type="text" class="form-control" readonly formControlName="AddRef" />
                        </div>
                        <div class="form-group">
                            <span>Funding Programme:*</span>
                            <mat-select class="form-control" placeholder="Funding Programmes" formControl="programme" multiple [compareWith]="compare">
                                <mat-option *ngFor="let programme of programmeList" [value]="programmeList">{{programme.Description}}</mat-option>
                            </mat-select>
                        </div>
                    </mat-tab>
                    <mat-tab label="Second">
                        Content 2
                    </mat-tab>
                    <mat-tab label="Third">
                        Content 3
                    </mat-tab>
                    <mat-tab label="Fourth">
                        Content 4
                    </mat-tab>
                    <mat-tab label="Fifth">
                        Content 5
                    </mat-tab>
                    <mat-tab label="Sixth">
                        Content 6
                    </mat-tab>
                </mat-tab-group>
            </div>
        </div>
        <div class="modal-footer">
            <div>
                <button type="submit" (click)="c" [disabled]="newRecordFrm.invalid" class="btn btn-primary">Save</button>
                <button type="button" class="btn btn-outline-dark" (click)="c('Save click')">Cancel</button>
            </div>

        </div>
    </form>
</ng-template>

And finally the error console error

UPDATE

The main issue I had was that the dto was incorrect and needed some more values.

There is a new issue where the dropdown is not brought to the front of the view. and instead behind the active model. Is there any css i can apply to resolve this? enter image description here

Many thanks in advance for your help

Lewis

like image 588
Lewis Avatar asked Oct 19 '25 08:10

Lewis


1 Answers

For our application, we use ngModel instead of formControl. We do it like this:

Filter.html

<mat-form-field class="ca80">
  <mat-select [(ngModel)]="type_list" multiple name="type_list">
     <mat-option *ngFor="let type of alteration_types" [value]="type.id_type"> {{type.desc}}</mat-option>
  </mat-select>
</mat-form-field>

and in filter.component.ts

type_list: string[];
auxT: any[] = [];
/**...**/

  if (this.type_list != null) {
      for (let t of this.type_list) {
        auxT.push(t);
      }
    }

We don't know if this is the best option, but it works fine

like image 110
Aw3same Avatar answered Oct 21 '25 21:10

Aw3same



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!