Andrey
Andrey

Reputation: 76

Angular mat-select: two letters of company name duplicates is selected company

I have this Angular component with Material mat-select. I need to have a prefix next to each value, which is represented by a circle displaying two letters of the company name.

 <mat-form-field appearance="outline" class="input-density w-60">
        @if (selectedLocation) {
            <div
                class="bg-ds-bright-500 my-1.5 ml-2 mr-1 flex h-9 w-9 items-center justify-center rounded-full text-lg text-white"
                [ngStyle]="{ 'background-color': selectedLocation.contactColor }"
                matPrefix
            >
                <p class="uppercase">{{ selectedLocation.companyName[0] }}{{ selectedLocation.companyName[1] }}</p>
            </div>
        }
        <mat-select [value]="locationId" (valueChange)="onValueChange($event)" class="my-1.5">
            @for (location of locations; track location.locationId) {
                <mat-option [value]="location.locationId">
                    <div class="flex flex-row items-center">
                        <div
                            class="bg-ds-bright-500 mr-2 flex h-9 min-h-9 w-9 min-w-9 items-center justify-center rounded-full text-lg text-white"
                            [ngStyle]="{ 'background-color': location.contactColor }"
                        >
                            <span class="uppercase">{{ location.companyName[0] }}{{ location.companyName[1] }}</span>
                        </div>
                        <span>{{ location.companyName }}</span>
                    </div>
                </mat-option>
            }
        </mat-select>
    </mat-form-field>

Problem: I faced a problem where, if the company name is "PropTech", it displays as "PrPropTech" instead of just "PropTech".

I noticed that Angular takes {{ location.companyName[0] }}{{ location.companyName[1] }} from mat-option and uses it for selected company.

Letters duplication in mat-select:

Upvotes: 1

Views: 42

Answers (2)

Andrey
Andrey

Reputation: 76

I fixed it this way:

<mat-form-field appearance="outline" class="input-density w-60">
    <mat-select [value]="locationId" (valueChange)="onValueChange($event)" class="my-1.5">
        <mat-select-trigger>
            @if (selectedLocation) {
                <div class="flex flex-row items-center">
                    <div
                        class="bg-ds-bright-500 mr-2 flex h-9 min-h-9 w-9 min-w-9 items-center justify-center rounded-full text-lg text-white"
                        [ngStyle]="{ 'background-color': selectedLocation.contactColor }"
                    >
                        <span class="uppercase"> {{ selectedLocation.companyName[0] }}{{ selectedLocation.companyName[1] }} </span>
                    </div>
                    <span>{{ selectedLocation.companyName }}</span>
                </div>
            }
        </mat-select-trigger>
        @for (location of locations; track location.locationId) {
            <mat-option [value]="location.locationId">
                <div class="flex flex-row items-center">
                    <div
                        class="bg-ds-bright-500 mr-2 flex h-9 min-h-9 w-9 min-w-9 items-center justify-center rounded-full text-lg text-white"
                        [ngStyle]="{ 'background-color': location.contactColor }"
                    >
                        <span class="uppercase">{{ location.companyName[0] }}{{ location.companyName[1] }}</span>
                    </div>
                    <span>{{ location.companyName }}</span>
                </div>
            </mat-option>
        }
    </mat-select>
</mat-form-field>

Upvotes: 1

Naren Murali
Naren Murali

Reputation: 56054

Basically when you select an option with HTML, angular material just takes the text inside the custom HTML you inserted and displays as selected, in JS, we can use .textContent to get only the text of an HTML.


You should use mat-select-trigger to set the output that you want to show, when the item is selected, here you can exclude the two letter label.

            <mat-select-trigger>    <!-- changed here! -->
              {{selectedLocation.companyName}}     <!-- changed here! -->
            </mat-select-trigger>     <!-- changed here! -->

Code:

 <mat-form-field appearance="outline" class="input-density w-60">
        @if (selectedLocation) {
            <div
                class="bg-ds-bright-500 my-1.5 ml-2 mr-1 flex h-9 w-9 items-center justify-center rounded-full text-lg text-white"
                [ngStyle]="{ 'background-color': selectedLocation.contactColor }"
                matPrefix
            >
                <p class="uppercase">{{ selectedLocation.companyName[0] }}{{ selectedLocation.companyName[1] }}</p>
            </div>
        }
        <mat-select [value]="locationId" (valueChange)="onValueChange($event)" class="my-1.5">
            <mat-select-trigger>    <!-- changed here! -->
              {{selectedLocation.companyName}}     <!-- changed here! -->
            </mat-select-trigger>     <!-- changed here! -->
            @for (location of locations; track location.locationId) {
                <mat-option [value]="location.locationId">
                    <div class="flex flex-row items-center">
                        <div
                            class="bg-ds-bright-500 mr-2 flex h-9 min-h-9 w-9 min-w-9 items-center justify-center rounded-full text-lg text-white"
                            [ngStyle]="{ 'background-color': location.contactColor }"
                        >
                            <span class="uppercase">{{ location.companyName[0] }}{{ location.companyName[1] }}</span>
                        </div>
                        <span>{{ location.companyName }}</span>
                    </div>
                </mat-option>
            }
        </mat-select>
    </mat-form-field>

Reference Stackblitz

Upvotes: 1

Related Questions