简体   繁体   中英

Typeahead Value in Bootstrap UI

I'm working on an app using AngularJS and Bootstrap UI. I've been fumbling my way through using the Typeahead control in Bootstrap UI.

Here's my Plunker

My challenge is I want the user to have the option of choosing an item, but not required to do so. For instance, right now, if you type Test in the text field and press "Enter", Test will be replaced with Alpha . However, I really want to use Test . The only time I want the text to be replaced is when someone chooses the item from the drop down list. My markup looks like the following:

<input type="text" class="form-control" placeholder="Search..."
       ng-model="query"  
       typeahead="result as result.name for result in getResults($viewValue)"
       typeahead-template-url="result.html" />

How do I give the user the option of choosing an item, but allow them to still enter their own text?

The issue is that both Enter and Tab confirm the selection of the currently highlighted item and Typeahead automatically selects an item as soon as you start to type.

If you want, you can click off the control to lose focus or hit Esc to exit out of typeahead, but those might be difficult to communicate to your users.

There's an open request in Bootstrap Ui to not auto select / highlight the first item

One solution is to populate the first item with the contents of the query thus far , so tabbing or entering will only confirm selection of the current query:

JavaScript :

angular.module('plunker', ['ui.bootstrap'])
    .filter('concat', function() {
        return function(input, viewValue) {
        if (input && input.length) {
            if (input.indexOf(viewValue) === -1) {
                input.unshift(viewValue);
            }
            return input;
         } else {
            return [];
    }};})

HTML :

<input type="text" 
     ng-model="selected" 
     typeahead="state for state in states | filter:$viewValue | limitTo:8 | concat:$viewValue"
     class="form-control">

Demo in Plunker

I came across this same situation and found no good answers so I implemented it myself in ui-bootstrap Here is the relevant answer. This is probably not the best route to take, but it does get the job done. It makes the first result in the typeahead to be what you're currently typing, so if you tab or enter off of it, it's selected -- you must arrow-down or select another option to get it.

Here is the modified ui-bootstrap-tpls.js file

I added a mustMouseDownToMatch property/attribute to the directive, like:

<input type="text" ng-model="selected" typeahead="item for item in typeaheadOptions | filter:$viewValue" typeahead-arrow-down-to-match="true">

And the javascript:

var mustArrowDownToMatch = originalScope.$eval(attrs.typeaheadArrowDownToMatch) ? originalScope.$eval(attrs.typeaheadArrowDownToMatch) : false;

I also added this function which will put the current text into the first item of the typeahead list, and make it the selected item:

var setFirstResultToViewValue = function (inputValue) {
        scope.matches.splice(0, 0, {
        id: 0,
        label: inputValue,
        model: inputValue
    });
}

And that is called in the getMatchesAsync call in the typeahead directive:

var getMatchesAsync = function(inputValue) {
// do stuff
    $q.when(parserResult.source(originalScope, locals)).then(function(matches) {
        // do stuff
        if (matches.length > 0) {
             // do stuff
        }
        if (mustArrowDownToMatch) {
            setFirstResultToViewValue(inputValue);
            scope.activeIdx = 0;
            setTypeaheadPosition();
        }
        // do stuff
  };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM