New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NgbTypeahead: Open Function #2318
Comments
Yep, the initial impl was done so people are not blocked and can handle the "open on focus" use-case. But I agree that we could make it more convenient for users. Marking as a feature request. This will need design / API idea(s), though. |
@f-aubert I was thinking a bit about design for the
To better illustrate those 2 approaches with our simple state-search example, the difference between (1) and (2) would be: Option (1) - open with results
This would immediately open a typeahead window and display passed-in results (and replace displayed results if a window is already opened). Option (2) - open with a search term
This would trigger the existing search machinery and eventually open a window with results matching the term. I still need to go over all the pros, cons and consequences of each approach but I wanted to reach out and check what would make most sense in your usage scenario(s). |
For me, as I'm mainly concerned with showing all possible choices on focus, option 2 is what I need! Option 1 could be nice to have but could be simulated more easily. Usually you want to show everything when no text is in the input. |
Hi, do you see a conceptual or technical problem with option 2? Is there anything I can do to help brainstorming, or implementing? All my best. |
@f-aubert yeh, actually I've got a conceptual problem with the option (2). Let me try to explain it. If we assume that option (2) should behave like if a user typed something into an input field that the argument supplied to the
The only idea I've got right now is to change typeahead implementation and move both If you've got different ideas / suggestions / impl proposals I would love to hear from you! We want to make it "right" for our users but it is not obvious for me what this "right" should be... |
You are absolutely right, I now don't see how option 2 could be implemented without the suggested breaking change. So maybe until you allow a breaking-change to take place option 1 would help as well. On the side note, I think pretty much everyone should be using debounce and distinctUntilChanged, which make the most sense. Angular own material-ui probably does something similar. So I guess such change wouldn't be counter-intuitive. As reference, here is my typical usage at the beginning of the typeahead Function, which filter the second Array Observable with the value of the first which might translate to something like this (out of memory as I don't have my dev env with me) In this case option 1 (named 'show') could be more easily implemented now, leaving option 2 (named 'trigger') for a time where you would allow yourself a breaking change (in version 3.0?). What are your thoughts? |
I have solved the issue for myself by creating an additional directive that triggers import { Directive, HostListener } from '@angular/core'
import { NgbTypeahead } from '@ng-bootstrap/ng-bootstrap';
@Directive({
selector: 'input[ngbtypeaheadpopup]'
})
export class TypeaheadPopupDirective {
@HostListener('focus', ['$event.target'])
@HostListener('click', ['$event.target'])
onClick(t) { if (!this.typeahead.isPopupOpen()) t.dispatchEvent(new Event('input')) }
constructor(private typeahead: NgbTypeahead) {
}
} The drawback of this method is that the popup waits for the debounce time, while the example in the documentation skips debounce time for clicks and focus. Thus, I only use debounce time if the term length is >0 in my search by using a conditional search = (text$: Observable<string>):Observable<string[]> => {
return text$.pipe(
debounce(t => timer(t.length > 0 ? 200:0)),
distinctUntilChanged(),
map(term => term === '' ? states
: states.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0,20))
)}; When the field is not empty on focus or click, the 200ms delay remains. To me that is a trivial drawback I'll live with. |
Hello @Rhobal, Have you tried your directive with a reactive form, the parameter "Editable" set to false, and a object as a value?
In that configuration, if I populate my control with a value, the value appear correctly, but the focus event from the directive clear the model. I'll add a working example if needed but you may have an idea to fix that? |
No, my configuration works well enough that I don't worry about it anymore. Judging by the thumbs, it also works from ome others... |
As many others here, I have the "List all options on focus" Use Case. I just attempted to use the focus trick with a new rxjs Subject, as explained in the documentation, and I don't think it's convenient at all. One should not have to use extra rxjs Subjects to handle this Use Case, and it makes it particularly annoying when we generate many such Typeahead Fields in a ngFor loop, for example a list of states, as for now we would need to generate one such rxjs Subject for each loop iteration.
Would it be possible to implement open (close, toggle) methods in the same way as what was already done for the NgbDatePicker? So we could simply decide when to call them (for example referring the element, and calling open in the focus event handler).
Thanks a lot for considering this.
Version of Angular, ng-bootstrap, and Bootstrap:
Angular: 5.2.x
ng-bootstrap: 1.0.x
Bootstrap: 4.0.x
The text was updated successfully, but these errors were encountered: