datnguyen94
datnguyen94

Reputation: 319

How I can add dropdown arrow within input in mat-autocomplete

I use mat-autocomplete to filter my data. Everything is work but I want to have a dropdown arrow to show all option within the input. In md-autocomplete , we can use dropdown-arrow="true" but in mat-autocomplete is not support it. So how I can add a dropdown arrow in mat-autocomplete? This is my component.ts

<form class="example-form">
    <mat-form-field class="example-full-width">  

    <input type="text" aria-label="Number" matInput 
    [formControl]="myControl" [matAutocomplete]="auto4"
    [hidden]="loadWithFilters&&loadWithFilters.field==='IP'">  

    <mat-autocomplete #auto4="matAutocomplete" dropdown-arrow="true" 
    (optionSelected)="onFilterOptionSelected($event,'IP')" >  

    <mat-option *ngFor="let option of filteredIP | async" 
    [value]="option.key">
        {{option.value}}
    </mat-option>
   </mat-autocomplete>  
   </mat-form-field>
</form>

Upvotes: 11

Views: 20512

Answers (5)

Alejandro Lasebnik
Alejandro Lasebnik

Reputation: 874

I prefer the solution I provided for my company since it provides the look and feel of other mat-select controls that might be included in the same page/form.

        <mat-icon class="aggregator-arrow-selector" matSuffix>
          <div class="mat-select-arrow-wrapper" (click)="openFullAggregatorsList()">
            <div class="mat-select-arrow">
            </div>
          </div>
        </mat-icon>

The secret was adding the same div content used in the mat-select materials control (including the material classes for the arrow selection) inside the mat-icon. I needed to change the height of the mat-icon in my css class .aggregator-arrow-selector {height: 8px}

          <mat-form-field class="col">
        <mat-label>Select Aggregator</mat-label>
        <input type="text"
               placeholder="Type to Search"
               aria-label="Aggregator Name"
               [title]="displayAggregatorTitle(null)"
               matInput
               (click)="setDefaultAggregatorPipe()"
               formControlName="aggregatorControl"
               [matAutocomplete]="auto">
        <mat-icon class="aggregator-arrow-selector" matSuffix>
          <div class="mat-select-arrow-wrapper" (click)="openFullAggregatorsList()">
            <div class="mat-select-arrow">
            </div>
          </div>
        </mat-icon>
        <mat-autocomplete #auto="matAutocomplete" placeholder="Aggregator"
                          [displayWith]="displayAggregatorFn"
                          (optionSelected)="onSelectedAggregator($event)">
          <mat-option *ngFor="let aggregator of aggregatorsFilteredList | async" [value]="aggregator">
            <div class="aggregator-item" [title]="displayAggregatorTitle(aggregator)">
              <div class="aggregator-part">{{ aggregator['name'] }}</div>
              <span class="separator">|</span>
              <div class="aggregator-part">{{ aggregator['externalId'] }}</div>
            </div>
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>

Dropdown arrow in mat-autocomplete

Upvotes: 1

Pavan Jadda
Pavan Jadda

Reputation: 4871

Just improving on Nakul's answer. Create mat-icon or span with matSuffix after input and bind autocomplete events to hide/show drop-down arrow

<mat-form-field class="example-full-width">
       
  <!-- Input -->
  <mat-label>Assignee</mat-label>
  <input
    type="text"
    matInput
    [formControl]="myControl"
    [matAutocomplete]="auto"/>

  <!-- Mat-Icon or Span -->
  <mat-icon matSuffix>
    <button style="padding: 0; margin: 0; border: 0; background-color: transparent;">
      <span class="material-icons" matTooltip="Click to select an User">
        {{arrowIcon}}
      </span>
    </button>
  </mat-icon>

  <!-- Auto Complete -->        
  <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn"
    (opened)="arrowIcon='arrow_drop_up'"
    (closed)="arrowIcon='arrow_drop_down'"
    (optionSelected)="arrowIcon='arrow_drop_down'">
    <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
      {{option.name}}
  </mat-option>
  </mat-autocomplete>
</mat-form-field>
  1. Declare variable arrowIcon in TypeScript file that stores the current icon name

  2. Create button inside mat-icon to show user hand instead of pointer when user hovers mouse on arrow icon

  3. Make use of (opened), (closed) and (optionSelected) events to change drop-down icon name

Here is the working StackBlitz demo

Upvotes: 2

AsGoodAsItGets
AsGoodAsItGets

Reputation: 3181

Using FontAwesome (or any other icon library, as long as you know the code the for the caret down icon), I did it with the following CSS:

input + mat-autocomplete:after {
    content: "\f0d7";
    font-family: "FontAwesome";
    right: 0;
    bottom: 4px;
    position: absolute;
    color: dimgrey;
    pointer-events: none;
}

For added effect you can add the following rule to switch the arrow up when the drop-down is expanded:

input[aria-expanded="true"] + mat-autocomplete:after {
    content: "\f0d8";
}

If you don't want to use an icon library you could use the Unicode black down-pointing triangle.

Oh, and your target browsers need to support sibling CSS operators.

Upvotes: 3

Tilak Dewangan
Tilak Dewangan

Reputation: 361

You can add mat-icon just after <input> control and give some style to position this and make sure to use position: absolute

<form class="example-form">
    <mat-form-field class="example-full-width">  

        <input type="text" aria-label="Number" matInput 
        [formControl]="myControl" [matAutocomplete]="auto4"
        [hidden]="loadWithFilters&&loadWithFilters.field==='IP'"> 

        <i class="material-icons align-arrow-right">arrow_drop_down</i>

        <mat-autocomplete #auto4="matAutocomplete" dropdown-arrow="true" 
        (optionSelected)="onFilterOptionSelected($event,'IP')" >  

        <mat-option *ngFor="let option of filteredIP | async" 
        [value]="option.key">
            {{option.value}}
        </mat-option>
       </mat-autocomplete>  
   </mat-form-field>
</form>

In CSS file

.align-arrow-right {
    position: absolute;
    right: 0; //change as per requirement
    top: 0; //change as per requirement
}

Upvotes: 3

Nakul Sharma
Nakul Sharma

Reputation: 534

essentially you are attaching an mat-autocomplete with an matInput, so you can style the form-field separately and then attach the mat-autocomplete to it.

please refer this stackblitz for full code demo.

form-field icons can be added like this.

Your code should look like this -

<form class="example-form">
    <mat-form-field class="example-full-width">
        <input type="text" matInput [formControl]="myControl" [matAutocomplete]="auto4"/>
        <mat-icon matSuffix>keyboard_arrow_down</mat-icon>

        <mat-autocomplete autoActiveFirstOption #auto4="matAutocomplete" (optionSelected)="onFilterOptionSelected($event)" >
          <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
            {{option}}
          </mat-option>
        </mat-autocomplete>
    </mat-form-field>
</form>

Upvotes: 9

Related Questions