angular-ui / bootstrap

PLEASE READ THE PROJECT STATUS BELOW. Native AngularJS (Angular) directives for Bootstrap. Smaller footprint (20kB gzipped), no 3rd party JS dependencies (jQuery, bootstrap JS) required. Please read the README.md file before submitting an issue!
http://angular-ui.github.io/bootstrap/
MIT License
14.27k stars 6.73k forks source link

Proposition for typeahead : Open suggestion view on focus #764

Closed jdecool closed 9 years ago

jdecool commented 11 years ago

It could be interresting to automatically open the suggestion view when the input field has focus.

It will allow user to see choices it can make when a filter is used and the list is not editable.

What do you think about ?

pkozlowski-opensource commented 11 years ago

So, I think that there was a brief discussion about something similar. The problem is that semantic of such thing gets very tricky very fast.

One of the main design assumptions of the current typeahead directive is that it should work seamlessly with promises (with any typeahead suggestions to be retrieved asynchronously, usually from a server side). Now if we take this into account the question is - what should be shown in the opened popup? If the input is empty what should we send as a query to the server?

I guess this is not super-common use case for the typeahead directive and as such I would prefer no to add more code / complexity to the directive itself. What I would rather look at is a way of making sure that such functionality can be pluggable. I'm starting to think about refactoring the current directive to use an internal controller so people can plug into the directive.

If I'm not mistaken it should be possible even today to write a simple directive that would listen to the focus event and write a value to the $viewValue - this would trigger the popup window opening.

@jdecool Could you give a separate directive a try? I would be keen to refactor the existing typeahead directive so custom / additional behavior is easy to plug.

sanfords commented 11 years ago

I'd like to second the suggestion to show the popup on focus if typeahead-min-length == 0. I've read some of the discussions. Popping up on focus will allow the user to see what kinds of choices are available before they type. Right now there is no way to do this. Adding this capability makes the popup a little more like a traditional <select> popup menu, but not too much. :-) Alternatively, showing the popup on keyboard-arrow-down would also be good, and would be consistent with combo-boxes on PCs.

With your $viewValue idea to show the popup on focus from a directive, what value should be written? Just an empty string? (I'm a little new to all of this.)

(Thank you for your efforts on this and other parts of ui-bootstrap!)

jdecool commented 11 years ago

It's a very interresting idea to allow user to plug an internal controller into the directive to extends functionnalities !

I also agree with @sanfords that displaying suggestion view on focus, is similar to have a typeahead-min-length=0.

Right now, I'm going to try to add a directive to catch the "focus" event.

sanfords commented 11 years ago

jdecool, thanks for working on that directive!

I put together two sample apps on another platform to see how a typeahead would "feel" with showing popups on focus. One popped up on focus, and the other popped up on "keyboard down-arrow". I preferred "down-arrow". I guess this could be easily done with the same directive, right?

The select2 control also uses down-arrow to show choices. Has down-arrow become a standard for showing options in typeahead-like controls? At some point this may be what the users expect.

jdecool commented 11 years ago

I have tried to use select2 in my app. The disavantage of the library is that user have to do an action to view type of result. So I try to make an UI which can be use only with keyboard et the most intuitive as possible.

Basic users don't know that they have to press the "down-arrow" to show suggestions. By opening the list on focus, user is guided.

sanfords commented 11 years ago

So I think there's a case to be made for both. First is showing the popup on focus: This would be good for, say, a country popup where a one-time user will need to see the choices immediately. Second is the user who doesn't need to see all the options immediately because they have experience with the form, or the typeahead field is one of 10 fields on the page and don't want the popup flashing in front of them as they tab around.

bkc commented 11 years ago

hello, has there been any more thought/work towards opening the pop-up when minlength=0 and focus event is fired? I really need this.

thanks

cindoum commented 11 years ago

To open suggestions on keydown 40

(version 0.6) You can try this workaround : first instruction in link function replaced by var minSearch = originalScope.$eval(attrs.typeaheadMinLength || '1');

And in the keydown event, add this test before the first one (become if / else if) : if (scope.matches.length === 0 && evt.which === 40) { modelCtrl.$setViewValue(modelCtrl.$viewValue); }

In unshift function, first test become : if ((inputValue && inputValue.length >= minSearch) || (minSearch === 0))

It wont break anything and will open the suggestion popup when you hit down arrow on an empty input

sanfords commented 11 years ago

cindoum, wonderful. This should be in 0.7.

cindoum commented 11 years ago

Glad it can help you. I am actually working on adding a few behaviors and fixing some glitchs. If any of them could help people, i might start a branch.

New feature :

Fix done :

cindoum commented 11 years ago

To open it on focus, with the fixed described in my previous post, it should not be harder than adding a directive on the input (like typeahead-open-on-focus) and in the link function bind on element focus and then set modelCtrl.$setViewValue(''); (need require: NgModel).

This directive is describe somewhere else in an issue. (not tested)

sanfords commented 11 years ago

When investigating typeaheads a few months ago I realized that everybody has a different opinion what a typeahead should be. :-)

So here's what I personally need from a typeahead:

  1. Show choices on keyboard-down-arrow. (great work!)
  2. Associate an id with each item, and bind the id.
  3. Allow creation of new items if they don't exist.
  4. A button to show the choices.
  5. For the popup to go away when the user tabs/shift-tabs/clicks away.
  6. To make sure the CSS hooks are there so the choices list doesn't fall off the bottom of the window. Some of my typeaheads have hundreds of choices.

I believe 1, 3, 4 are in your list.

cindoum commented 11 years ago

Typeahead seam to go in a way : advanced input, for me it is more an advanced select...

Most of what your asking is already possbile.

  1. need a fix, but easily fixable.
  2. this is done with your 'options' kind of -> item.Id as item.Name for item in items
  3. This is more or less what editable is doing, but return a string instead of an object ...
  4. This is a bit harder, need to play with dissmissClickHandler and events... I have a few more tweaks to have it stable, but then i can send you my code if you want.
  5. Tab, enter, esc already close the popup, you can easily add more. Add keyCode to HOT_KEYS line 4 (not tested). Input blur also close the suggestions popup.
  6. Not sure to understand... But if you have hundreds of suggestions, why dont you use a filter limitTo:x ? I think this is a strange behavior to show hundreds of suggestions in one block...

The 3 is not a behavior i will be working on as it seem ok to me. If editable = false, it return the match or null, that is what i expect and if editable = true, it return the match object or the string typed in the input if cannot fit it to matches.

sanfords commented 11 years ago

This is great news. There are so many typeheads out there I just wanted to enumerate what I'd like. I think they've all blended together in my mind.

6 is actually important. Users with large screens can easily see > 30 items in the dropdown. And they'll often want to scroll through the choices before typing. It's especially important combined with #1 and empty input, I think.

cindoum commented 11 years ago
  1. A button to show the choices.

I have it working but this is not a clean way to do it, but i need the typeahead working as we expected for yesterday so ill keep this.

Here is what i've done (if it can help people while a cleaner way is found):

  1. Add a parameter to typeahead (toggle in my case) -> typeahead-toggle="show"
  2. Add a button to your html -> (ng-click is the important piece)
  3. In the typeahead directive add this -> scope.$watch('show', function (n, o) { if (n != o) { if (scope.matches.length == 0) { element[0].focus(); element[0].select(); getMatchesAsync(element[0].value); } else { scope.select(scope.activeIdx); resetMatches(); } } });
  4. Change the dissmiss click handler function to -> var dismissClickHandler = function(evt) { if (element[0] !== evt.target) { if (isInternalClick(evt.target) !== true) { resetMatches(); scope.$digest(); } } };
  5. Add this function ->

                   var elem = angular.element(target);
    
           if (elem.hasClass('dropdown') == true || elem.parent().hasClass('dropdown') == true) {
               return true;
           }
    
           return false;
       }```
    
    
    change the 'dropdown' class to any class name you assign to your element (button).

As i said, this is more of a hack than a new feature. I didnt want to make the toggle button part of the typeahead, so everything is left outside.

EDIT: Sorry for indentation, cannot find proper tag to show code :/

cindoum commented 11 years ago

If you dont want to use a limitTo filter, you could also (or both) set a maxHeight with a overflow-y: auto to wrap the suggestion popup with a scroll bar...

I am not sure to understand how you would like it to be? Showing 30+ suggestions, if no maxHeight or any kind of pagination / filtering will alway go down to the page bottom...

braco commented 11 years ago

@cindoum,

minLength = 0 working (done)

would be great to have; it looks like this is requested pretty often, and I'm trying to hack my way through it right now. Do you have this up anywhere?

sanfords commented 11 years ago

Thank you for your efforts with this. I think these are great additions to typeahead.

trpriel commented 11 years ago

I think so also minLength=0 has a lot of added value

sanfords commented 11 years ago

Regarding large lists, I don't think it's too much to present hundreds of items to users. It seems kind of the norm, actually. Having hundreds of bound choices though will slow down rendering if there are just a few typeaheads on-screen. Is there a way to either not-bind (or cleverly bind) the list choices or use something like angular-virtual-scroll?

JohnYoungers commented 10 years ago

I also agree this would be very beneficial functionality.

I have several scenarios where the list of options gets filtered by other inputs, and so it would be helpful to set that minLength property to 0, and allow the user to view the entire list when they get to the input opposed to being required to guess at which of the few values are still applicable.

It sounded like there was a concern with sending off a query of nothing, but I would imagine you'd want the server method call to be limited in how much data it will return in general.

ada-lovecraft commented 10 years ago

+1

raykin commented 10 years ago

useful when the options were not huge, so show options when input was focus can save user memory and user can type adhoc strings too.

swayf commented 10 years ago

+1 is any plans to include the feature? :)

xtiam57 commented 10 years ago

I just added this in the link function and worked just fine: element.bind('focus', function(ev) { modelCtrl.$setViewValue(' '); });

paddymul commented 10 years ago

I would like typeahead to show all possible completions on click. This is similar to ui-select2. I have some code that accomplishes this, but it needs to be cleaned up.

sanfords commented 10 years ago

I agree with paddymul. My only concern is that if all elements in the drop down are bound, performance will be really really bad. (Since this ui element is all angular, I believe.) Maybe the drop down could use https://github.com/stackfull/angular-virtual-scroll. Or the derivative that's coming in the new ng-grid 3.

adrianboimvaser commented 10 years ago

+1 Is there any workaround/hack for this?

sclarson commented 10 years ago

+1 I'd also find this highly useful. The min-length="0" seems like a great way to have it be opt-in since the default is 1. (this is actually what I assumed min-length="0" would do).

kdekooter commented 10 years ago

:thumbsup:

barnash commented 10 years ago

+1

PontusIvarsson commented 10 years ago

+1

HollandRisley commented 10 years ago

+1

HollandRisley commented 10 years ago

I really need to be able to click a button and open an input automatically focussed with the full typeahead list already opened. This is essential for good user experience in the case of my app. Any movement on this? Any workarounds?

HollandRisley commented 10 years ago

I now have a working solution - typeahead dropdown is shown immediately on focus:

http://plnkr.co/edit/bZMEOx0Qwo6VzW7oSuEE?p=preview

The answer was give to me here:

http://stackoverflow.com/questions/24764802/angular-js-automatically-focus-input-and-show-typeahead-dropdown-ui-bootstra/24767467#24767467

ahneo commented 10 years ago

Hi

I got a working solution by changing some code in ui-bootstrap-tpls-0.10.0.js. So there are no differences in the typeahead html markup. You can have a look here at http://plnkr.co/edit/LXHDpL?p=preview

To use this fix, use the ui-bootstrap-tpls-0.10.0.js from the Plunk. To see my changes, open ui-bootstrap-tpls-0.10.0.js from the Plunk and search for 'ahneo'.

Hope this helps

vannitotaro commented 10 years ago

+1

Manduro commented 10 years ago

+1

geekuillaume commented 10 years ago

+1 Any news ?

HollandRisley commented 10 years ago

I got this working by using solutions here:

http://stackoverflow.com/questions/24764802/angular-js-automatically-focus-input-and-show-typeahead-dropdown-ui-bootstra

On 18 Aug 2014, at 14:09, Guilaume Besson notifications@github.com wrote:

+1 Any news ?

— Reply to this email directly or view it on GitHub.

stevecances commented 10 years ago

this is actually what I assumed typeahead-min-length="0" would do

+1

jalaniz1 commented 10 years ago

+1

bayy commented 10 years ago

any update/plan/news on this feature? This is a great feature to have.

javiermarinros commented 10 years ago

+1

Kerumen commented 10 years ago

:thumbsup:

tchukuchuk commented 10 years ago

+1

bsiddiqui commented 10 years ago

+1

piernik commented 10 years ago

+1

chinaowl commented 9 years ago

+1

Hotell commented 9 years ago

I've created this custom combobox directive as a workaround. check it out. works with latest ui-bootstrap 0.12 and angular 1.3.x http://embed.plnkr.co/ZtuoTVgPLuMWDT2ejULW/preview