I use angular 10 with angular material to build my website.
I want to add input suggestions to matInput
but in a different way that matAutocomplete
does..
i don't want to show a list, I want to show one suggestion to a word that the user is already typing inside the input as gray letters after the last character that is typed and if presses tab it will autocomplete the word.
example..
lets say I want to write the word beverage and I started typing only 'beve'
so the input will show beve|rage
the |
character is the position of the cursor, and it will show rage in gray and the user can't really move forward cause it's not really part of the input, but if he clicks type it actually added the missing laters to the word and moves the cursor after the position of the full word.
I don't even know how to to start searching for how to implement such a thing, because whenever i search the terms autocomplete
or suggestion
it all goes show tutorials on autocomplete list which is not what I want.
I tried to play with matInput
and mat-form-field
a bit and like a good solution would be if I could show the placeholder even after the user typed something cause it looks like it has the same effect more or less of what I need.
so if I create this:
<mat-form-field>
<mat-label>hello</mat-label>
<mat-hint>test</mat-hint>
<input matInput placeholder="foooooooo"/>
</mat-form-field>
so when I focus on the input element, i see foooooooo
in gray but when I start typing the placeholder is gone. if the placeholder could still be shown then I could manipulate the placeholder dynamically, I could change on keypress
even when the user clicks tab in order to complete the actual word in the input and move the cursor forward.
still don't know how to leave the placeholder! so if anyone got any idea how to do that.. or any other method to support what I need it would be great. thanks
Edit:
A relatively easier solution would be to have two input
elements overlapping each other, i.e they should be placed at the same position, having same width, height. And then make the backgroud-color
transparent for both or the top element and set z-index
of the actual input element to some large value -
// actual input element
<input type="text" [(ngModel)]="value" (input)="inputChange()" (keydown.tab)="tabKeyPressed()"/>
// below one is used to fake a placeholder
// placeholderValue = value + suggestion (calculated using inputChange() method
<input type="text" class="autocomplete" disabled [(ngModel)]="placeholderValue" />
Please checkout this StackBlitz sample.
Solution 2
You can take help of this answer which suggests having a wrapper div
and manipulate the data-placeholder
attribute.
Solution 3 -
input
element (call it B).input
element (call it A) starting right after the entered text in A.div
(call it C) which contains exact value present in input
element A.keyup
event, find the suggestions based on the input and replace the placeholder property in B.tab
event, replaced the input value in A if a suggestion exists.Below is how the html should look -
<div id="app">
// A
<input type="text" name="email" class="custom-input" (blur)="clearPlaceholder()" [(ngModel)]="textInput" (keyup)="autoSuggest()" (keydown.tab)="fillAutocomplete()" />
<div class="clearit virtual-text" >
// C
<div class='hidden-text'>{{ textInput }}</div>
// B
<input type="text" class="autocomplete" [placeholder]="autoCompPlaceholder"/>
</div>
{{autoCompPlaceholder}}
</div>
Please take a look at this working StackBlitz example and also check out this article from where it's borrowed.