Значение опережающего ввода в пользовательском интерфейсе Bootstrap

Я работаю над приложением, использующим AngularJS и Bootstrap UI. Я возился с использованием элемента управления Typeahead в пользовательском интерфейсе Bootstrap.

Вот мой плункер

Моя проблема заключается в том, что я хочу, чтобы у пользователя была возможность выбрать элемент, но он не обязан это делать. Например, прямо сейчас, если вы наберете Test в текстовом поле и нажмете «Ввод», Test будет заменено на Alpha. Однако я действительно хочу использовать Test. Единственный раз, когда я хочу, чтобы текст был заменен, - это когда кто-то выбирает элемент из раскрывающегося списка. Моя разметка выглядит следующим образом:

<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" />

Как дать пользователю возможность выбрать элемент, но при этом разрешить ему вводить собственный текст?


person user3284007    schedule 10.09.2014    source источник


Ответы (2)


Я столкнулся с такой же ситуацией и не нашел хороших ответов, поэтому я реализовал ее самостоятельно в ui-bootstrap Вот соответствующий ответ. Это, вероятно, не лучший путь, но он выполняет свою работу. Это делает первым результатом в шапке то, что вы сейчас печатаете, поэтому, если вы нажмете табуляцию или введете вне него, он будет выбран — вы должны нажать стрелку вниз или выбрать другой вариант, чтобы получить его.

Вот измененный файл ui-bootstrap-tpls.js

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

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

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

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

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

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

И это вызывается в вызове 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 (mustArrowDownToMatch) {
            setFirstResultToViewValue(inputValue);
            scope.activeIdx = 0;
            setTypeaheadPosition();
        }
        // do stuff
  };
person Tom    schedule 10.09.2014

Проблема в том, что и Enter, и Tab подтверждают выбор выделенного в данный момент элемента, а Typeahead автоматически выбирает элемент, как только вы начинаете печатать .

Если вы хотите, вы можете щелкнуть элемент управления, чтобы потерять фокус, или нажать Esc, чтобы выйти из режима ввода, но это может быть сложно сообщить вашим пользователям.

В Bootstrap Ui есть открытый запрос на не автоматически выбирать/выделять первый элемент

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

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">

Демонстрация в Plunker

person KyleMit    schedule 10.09.2014