Reputation: 171
I am using Angular Material to create chips entered in the input field. So, the current default behaviour as given in documentation examples is to display chips inside the input box. I don't want to show those chips inside my input field what I wanna do is when user enters anything, the chip should be created under the input field(not inside the input field). You can just help me with any example link.
Upvotes: 4
Views: 13647
Reputation: 171
I used an input component that would take inputs and then add it to any array. Then I passed this array to chips component that would display chips.
Template that calls keyDown and blur to add chips on these two events. Called another component that displays chips passing the array of chips.
<form [formGroup]="form">
<mat-form-field appearance="outline">
<mat-label>Key Skills</mat-label>
<input matInput placeholder="Skills" (keydown)="onAddSkills($event)" (blur)="onBlurMethod()" formControlName="keySkills" name="keySkills">
</mat-form-field>
<div class="chip-list">
<chip-list [skills]="skills"></chip-list>
</div>
</form>
The component for this template
import {Component} from '@angular/core';
import { FormGroup, FormControl, FormBuilder } from '@angular/forms';
export interface Skills {
name: string;
}
@Component({
selector: 'key-skills',
templateUrl: 'key-skills.component.html',
styleUrls: ['key-skills.component.scss'],
})
export class KeySkillsComponent {
skills: Skills[] = [];
private form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
"keySkills": new FormControl()
});
}
onAddSkills(event) {
if (event.key === "Enter" || event.key===",") {
this.addSkillsToArray(this.form.value['keySkills']);
}
}
onBlurMethod() {
this.addSkillsToArray(this.form.value['keySkills'])
}
addSkillsToArray(skill) {
if ((skill || '').trim()) {
this.skills.push({name: skill.trim()});
}
this.form.reset();
event.preventDefault();
}
}
Chip List template
<mat-chip-list>
<mat-chip *ngFor="let skill of skills">
{{skill.name}}
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
</mat-chip-list>
and Component
import {Component, Input} from '@angular/core';
@Component({
selector: 'chip-list',
templateUrl: 'chip-list.component.html',
styleUrls: ['chip-list.component.scss'],
})
export class ChipListComponent {
@Input() skills;
}
Upvotes: 2
Reputation: 2018
If you look at the Angular Material Chip example you can pull the input out of mat-form-field
Update: If you reorder the input element in the example from the docs then the chips appear below the input (where the user enters text) but still part of the component:
<mat-form-field class="example-chip-list">
<input placeholder="New fruit..."
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)">
<mat-chip-list #chipList>
<mat-chip *ngFor="let fruit of fruits" [selectable]="selectable"
[removable]="removable" (removed)="remove(fruit)">
{{fruit.name}}
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
</mat-chip-list>
</mat-form-field>
That might not get you exactly where you envisioned but I think it gets at the spirit of the solution you're looking for.
See this StackBlitz I tweaked from the example.
Upvotes: 6
Reputation: 31
The easiest way to implement that is playing with CSS position property.
But it's actually better to use flexbox: https://codepen.io/avreddy/pen/ppzraz
.md-chips {
display: flex;
flex-wrap: wrap;
}
.md-chips md-chip{
order: 2;
}
.md-chips .md-chip-input-container {
order: 1;
width: 100%;
}
Upvotes: 1