How to change style of MatChipList and MatAutoComplete input? - html

I'm trying to create something similar to the picture below :
the problem is I can't change the height or the width of the input form. I've looked for similar questions but none of them answer my questions.
here is my html code :
<mat-form-field class="example-chip-list" appearance="fill">
<mat-label>Favorite Fruits</mat-label>
<mat-chip-list #chipList aria-label="Fruit selection">
<mat-chip
*ngFor="let fruit of fruits"
(removed)="remove(fruit)">
{{fruit}}
<button matChipRemove>
<mat-icon>cancel</mat-icon>
</button>
</mat-chip>
<input
placeholder="New fruit..."
#fruitInput
[formControl]="fruitCtrl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="add($event)">
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let fruit of filteredFruits | async" [value]="fruit">
{{fruit}}
</mat-option>
</mat-autocomplete>
</mat-form-field>

Related

Angular displaying a different placeholder in an input dependant on a mat select

I'm trying to display different placeholder text in a mat-input dependant on what I select in my mat-select, and I cant seem to find a way to bind it to my selected option.
<mat-form-field appearance="outline" class="search-field" style="width:40vw">
<input matInput type="text" class="input" placeholder="Enter a Plant No" formControlName="searchQuery">
<mat-select name="ampm" class="ampm" style="width:10vw;" [value]="selected">
<mat-option value="PLANT_NO">PLANT_NO</mat-option>
<mat-option value="EQUIP_NO" disabled>EQUIP_NO</mat-option>
<mat-option value="LOCN_DESC" disabled>LOCN_DESC</mat-option>
<mat-option value="EQUIP_GRP_ID" disabled>EQUIP_GRP_ID</mat-option>
<mat-option value="EQUIP_CLS" disabled>EQUIP_CLS</mat-option>
<mat-option value="MAINT_ZONE_NAM" disabled>MAINT_ZONE_NAM</mat-option>
<mat-option value="PRNT_PLNT_NO" disabled>PRNT_PLNT_NO</mat-option>
<mat-option value="SUBSTATION" disabled>SUBSTATION</mat-option>
<mat-option value="IP_PLNT_NO" disabled>IP_PLNT_NO</mat-option>
</mat-select>
<button mat-icon-button title="Search">
<mat-icon>search</mat-icon>
</button>
</mat-form-field>
you can use [placeholder] property binding, and mat select change event you can update as per your requirement.
ts
inputPlaceholderUpdate = "Enter a Plant No";
selectChange(event){
const value = event.value;
this.inputPlaceholderUpdate = value == 'PLANT_NO' ? 'Enter a Plant No' : value == 'EQUIP_NO' ? 'Enter a Equip No' : 'Enter a Locn Desc';
}
html
<input matInput type="text" class="input" [placeholder]="inputPlaceholderUpdate" formControlName="searchQuery">
<mat-select name="ampm" class="ampm" style="width:10vw;" [value]="selected" (selectionChange)= "selectChange($event)">
......
......
</select>

how to add mat select in Angular input

I'm finding away to add mat select on my input field but some reason when I click on the arrow, it's not working and not showing me all the list.
I have autocomplete and usually when a user start typing it show all the list to select but I'm trying add mat-select also so that user can just click on the arrow and select from the list without having to type something first.
I've followed below stackblitz example ( checkbox is not needed for mine) but mine is little bit different and I also have text input and auto complete so I'm not sure why I can't type anymore in my input with current code and also the drop down list are not showing when I click the arrow.
any suggestion or help will be really apprecaited.
https://stackblitz.com/edit/angular-material-v9-mat-select-with-mat-chip-list?file=src%2Fapp%2Fselect-multiple-example.html
<mat-form-field class="form" appearance="fill">
<mat-label>Search or Select a Super Tag</mat-label>
<mat-select [formControl]="superTags" multiple>
<mat-select-trigger>
<mat-chip-list #chipList>
<div>
<mat-chip *ngFor="let superTag of superTags" [selectable]="selectable" [removable]="removable"
(removed)="remove(superTag)">
<img class="super-icon" src="/assets/images/icons/super-tag-icon.svg">
{{superTag.tag}}
<mat-icon matChipRemove *ngIf="removable" matTooltip="Remove a super tag">cancel</mat-icon>
</mat-chip>
</div>
<div>
<input matInput #input [(ngModel)]="tagIn" [formControl]="tagCtrl" [matAutocomplete]="auto" [matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" (matChipInputTokenEnd)="addTag()">
</div>
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngIf="isLoading" class="is-Loading">
<mat-spinner diameter="20"></mat-spinner>
</mat-option>
<ng-container *ngIf="!isLoading">
<mat-option *ngFor="let tag of filteredSuperTags | async" [value]="tag">
{{tag}}
</mat-option>
</ng-container>
</mat-autocomplete>
</mat-select-trigger>
</mat-select>
</mat-form-field>
In this case I would not use the combination of chip list and autocomplete.
I think, what you really need, is the autocomplete with options which contain checkboxes for the multiselect. Try to do, somethihg like this.
<mat-form-field class="example-full-width">
<input type="text" placeholder="Select Users" aria-label="Select Users" matInput [matAutocomplete]="auto" [formControl]="userControl">
<mat-hint>Enter text to find users by name</mat-hint>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let user of filteredUsers | async" [value]="selectedUsers">
<div (click)="optionClicked($event, user)">
<mat-checkbox [checked]="user.selected" (change)="toggleSelection(user)" (click)="$event.stopPropagation()">
{{ user.firstname }} {{ user.lastname }}
</mat-checkbox>
</div>
</mat-option>
</mat-autocomplete>
Full example:
https://stackblitz.com/edit/angular-sx79hu?embed=1&file=app/multiselect-autocomplete-example.html

how to place text input beside of chips in Angular

I'm trying to make the mat form field that can show tags, input and drop down like the design below but I'm not sure how to achieves that so can anybody help me out. I've tried different methods for a few hour now but still can't find a way to make it work. will be really appreciated if somebody can give me suggestion or help.
I'm just trying to place the text input to be always beside of Chips (maybe expand like what I have right now if user put a lot of chips) and also have drop down options (icon) on the side like the design below.
<mat-chip-list *ngIf="editMode">
<mat-form-field class="form" appearance="fill">
<!--show Tags-->
<ng-container *ngFor="let chip of chips" class="add-tag-chip" (click)="displayTagInput()">
<mat-chip [selectable]="selectable" [removable]="removable" (removed)="removeTags(chip)">
{{chip.tag}}
<mat-icon matChipRemove *ngIf="chip.pending !== true && removable" matTooltip="Remove a tag">cancel</mat-icon>
<mat-spinner *ngIf="chip.pending === true" [diameter]="16" mode="indeterminate"></mat-spinner>
</mat-chip>
</ng-container>
<!--Text Input (supposed to be on the side of Tags)-->
<input matInput [(ngModel)]="tagIn" [matAutocomplete]="auto" placeholder="New Tag" (keyup.enter)="addTag()" />
<!--For Drop Down List-->
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let tag of filteredTags | async" [value]="tag">
{{tag}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</mat-chip-list>
This is the design I'm trying to do
This is what I have right now
Why don't you use it as it is represented in the documentation ? I also found this stackblitz that is exactly what you want. Here is the html code :
<mat-form-field class="demo-chip-list">
<mat-chip-list #chipList>
<mat-chip
*ngFor="let fruit of fruits"
[selectable]="selectable"
[removable]="removable"
(removed)="remove(fruit)">
{{fruit}}
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
<input
placeholder="New fruit..."
#fruitInput
[formControl]="fruitCtrl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)"
/>
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let fruit of filteredFruits | async" [value]="fruit">
{{ fruit }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
Note that there is no ng-container ( they don't seems mandatory in your code) and the mat-form-field tag wrap the whole thing. In your code you have it as a child of mat-chip-list.
[Edit]: I got it. Here is the code :
.css :
/* ::ng-deep needed to only target your component (it's deprecated but have not replacement for the moment) */
.your-component ::ng-deep .mat-form-field-infix {
display: flex !important
}
/* Change the placeholder to stick to the same position as if your input is focused, not really good */
.your-component ::ng-deep.mat-form-field-label {
transform: translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.001px) !important;
}
.html:
<mat-chip-list>
<mat-form-field>
<!-- ng-container is now a span -->
<span *ngFor="let fruit of fruits" (click)="displayTagInput()">
<mat-chip [selectable]="selectable" [removable]="removable" (removed)="removeTags(chip)">
{{fruit}}
<mat-icon matChipRemove matTooltip="Remove a tag">cancel
</mat-icon>
</mat-chip>
</span>
<input matInput [(ngModel)]="tagIn" [matAutocomplete]="auto2" placeholder="New Tag..." (keyup.enter)="addTag()" />
<mat-autocomplete #auto2="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let fruit of filteredFruits | async" [value]="fruit">
{{ fruit }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</mat-chip-list>
Here is the demo ons tackblitz. Note that it does not work perfectly. I had to force the shrink effect of the placeholder with the css (I think it's because mat-form-field is inside mat-chip-list).
Also, since i removed some come to make it clearer, you will have to test it with your own code, chip remove methods etc.
Hope it helps :)

Angular autocomplete returns an empty field when clicked searched option

The problem is that when i search a list of users by typing characters into the input field and mat-autocomplete finds the searched user, after i click on it to select that user the input field becomes empty instead of showing the selected user.
Here is my HTML code:
<div class="material-input">
<mat-form-field class="form-group">
<input id="userNameInput" matInput placeholder="Search user name" formControlName="userName" for="search-box"
#searchBox id="search-box" (input)="search(searchBox.value)" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let username of mockLdap | async" [value]="username">
{{username.userName}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
You have to set the [value]="username.userName" of your option accordingly.
<div class="material-input">
<mat-form-field class="form-group">
<input id="userNameInput" matInput placeholder="Search user name" formControlName="userName" for="search-box"
#searchBox id="search-box" (input)="search(searchBox.value)" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let username of mockLdap | async" [value]="username.userName"> <!--- Here you have to set username.UserName -->
{{username.userName}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>

Read the value of <mat-option> angular

HTML:
<mat-icon class="fab fa-raspberry-pi"></mat-icon>
<mat-form-field>
<mat-select placeholder="Rpi">
<mat-option>Choose</mat-option>
<mat-option *ngFor='let pi of myRpis' [(ngModel)]="RpiIp" ngDefaultControl [value]="pi.RPI_IP"
(click)="getPins()">
{{pi.LABEL}}
</mat-option>
</mat-select>
</mat-form-field>
Typescript:
I have:
RpiIp = '';
and
getPins() {
console.log(this.RpiIp);
this.doneFetching = true;
}
The console prints an empty value (the value do not change). Where is the error? why the value is not changing?
You need to place the ngModel on the mat-select, not on the mat-option
mat-select will be containing the mat-option, so you have to use ngModel on mat-select.
Consider the below code:
<select . . . name="duration" [(ngModel)]="exercisePlan.duration">
<option *ngFor="let duration of durations" [value]="duration.value">{{duration.title}}</option>
<mat-form-field>
<mat-select placeholder="Rpi" [(value)]="RpiIp">
<mat-option>Choose</mat-option>
<mat-option *ngFor='let pi of myRpis' ngDefaultControl [value]="pi.RPI_IP"
(click)="getPins()">
{{pi.LABEL}}
</mat-option>
</mat-select>
</mat-form-field>
https://stackblitz.com/angular/dybkbybngme?file=app%2Fselect-value-binding-example.ts
Based on this answer the correct answer looks like this:
<mat-icon class="fab fa-raspberry-pi"></mat-icon>
<mat-form-field>
<mat-select placeholder="Rpi" [(value)]="RpiIp">
<mat-option>Choose</mat-option>
<mat-option *ngFor='let pi of myRpis' ngDefaultControl [value]="pi.RPI_IP" (click)="getPins()">
{{pi.LABEL}}
</mat-option>
</mat-select>
</mat-form-field>
Thanks :D
<mat-icon class="fab fa-raspberry-pi"></mat-icon>
<mat-form-field>
<mat-select placeholder="Rpi" >
<mat-option>Choose</mat-option>
<mat-option *ngFor='let pi of myRpis' ngDefaultControl [value]="pi.RPI_IP" (click)="getPins()">
{{pi.LABEL}}
</mat-option>
</mat-select>
</mat-form-field>