Tab-off ui-bootstrap typeahead только тогда, когда строка выбрана явно

Я создал этот jsBin, чтобы продемонстрировать проблему, с которой я столкнулся. Если вы пойдете сюда, попробуйте набрать «Пять» и двигаться дальше. Вашей естественной реакцией было бы ввести «Пять», а затем нажать клавишу Tab, и если бы вы хотели «Пятьсот», вы бы один раз прокрутили стрелку вниз; однако в этом случае вам нужно ввести «Пять», а затем либо нажать клавишу ESC, либо физически вывести мышь из поля, не нажимая ни на какие другие параметры.

Итак, в основном, когда вы используете typeahead, если есть хотя бы один результат, соответствующий вашим текущим критериям, нажатие Tab выберет его. Мое ожидаемое поведение заключается в том, что при вводе текущая выбранная опция — это именно то, что вы вводите, и если вы хотите получить один из других результатов, вы должны нажать стрелку вниз один или несколько раз.

Вот код, который находится в jsBin:

<div ng-controller="TestController">
  <div>
    {{selected}}
  </div>
  <input type="text" ng-model="selected" typeahead="item for item in typeaheadOptions | filter:$viewValue">
</div>

И JavaScript:

var app = angular.module('app', ['ui.bootstrap'])

.controller('TestController', function($scope) {
  $scope.typeaheadOptions = [
    'One','Two','Three','Four','Five-Hundred','Fifteen','Fourteen','Fifty','Six','Seven','Eight','Nine','Ten'
  ]
});

person Tom    schedule 16.05.2014    source источник


Ответы (2)


В итоге я изменил ui-bootstrap, чтобы он работал так, как я хочу.

Я добавил в директиву свойство/атрибут mustMouseDownToMatch, например:

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

И джаваскрипт:

var mustMouseDownToMatch = originalScope.$eval(attrs.typeaheadMouseDownToMatch) ? originalScope.$eval(attrs.typeaheadMouseDownToMatch) : false;

Я также добавил эту функцию, которая поместит текущий текст в первый элемент списка ввода и сделает его выбранным элементом:

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

    // set the selected item to the first item in the list, which is this guy
    scope.activeIdx = 0;
}

И это вызывается в вызове getMatchesAsync в директиве typeahead:

var getMatchesAsync = function(inputValue) {
// do stuff
    $q.when(parserResult.source(originalScope, locals)).then(function(matches) {
        // do stuff
        if (matches.length > 0) {
             // do stuff
        }
        if (mustMouseDownToMatch) {
            setFirstResultToViewValue(inputValue);
        }
        // do stuff
  };
person Tom    schedule 16.05.2014

Более свежий способ сделать это, так как я столкнулся с той же проблемой и, возможно, тогда не был доступен. введите здесь описание изображения

Вы можете добавить это сейчас как атрибут

typeahead-should-select="$ctrl.typeaheadShouldSelect($event)"

В вашем контроллере или пользовательском компоненте добавьте следующее, что позволит вам перейти на вкладку сейчас, а также, если вы нажмете на элемент, вы можете нажать клавишу ввода, чтобы выбрать его.

 self.typeaheadShouldSelect = function($event) {
                if ($event.key === 'Tab') {
                    var e = $.Event('keydown');
                    e.which = 40;
                    $($event.currentTarget).trigger(e);
                }
                if ($event.key === 'Enter') {
                    return true;
                }
            }
person Jeff S    schedule 26.10.2020