Передать параметр в Bloodhound из Typeahead?

Я настраиваю форму с помощью Typeahead. У меня есть два поля ввода рядом друг с другом, и мне нужно автозаполнение для каждого из них. Мой HTML выглядит так:

<select id="numerator">
    <option value="presentation">presentation</option>
    <option value="chemical">chemical</option>
</select>
<input id="numeratorId" class="typeahead" type="text" />
<br/>
<select id="denominator">
    <option value="presentation">presentation</option>
    <option value="chemical">chemical</option>
</select>
<input id="denominatorId" class="typeahead" type="text" />

Каждое из input полей будет автоматически заполняться при просмотре конечной точки API. Это должно быть в форме /api/1.0/code?type=presentation&code=123 или /api/1.0/code?type=chemical&code=123.

Значение параметра type в вызове API должно зависеть от значения элемента <select> рядом с каждым полем ввода.

Проблема, с которой я столкнулся, заключается в том, что я не знаю, как сообщить Bloodhound, каким должен быть параметр type.

В идеале я хотел бы передать его Bloodhound, но я не знаю, как это сделать. Это мой JavaScript:

var bnfMatches = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  remote: {
      url: '/api/1.0/code?',
      replace: function(url, uriEncodedQuery) {
        url = url + 'code=' + uriEncodedQuery;
        // How to change this to denominator for denominator queries?
        val = $('#numerator').val(); 
        if (!val) return url;
        return url + '&code_type=' + encodeURIComponent(val)
      }
  }
});

$('.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 2
},
{
    name: 'states',
    displayKey: 'id',
    source: bnfMatches.ttAdapter()
});

Буду очень благодарен за любые предложения.


person Richard    schedule 14.04.2015    source источник
comment
Кажется, что оба элемента input имеют одинаковые id? numeratorId ?   -  person guest271314    schedule 14.04.2015
comment
Извините, это ошибка. Исправлена.   -  person Richard    schedule 14.04.2015
comment
Смотрите пост. Скорректированы id из input элементов, добавлены bnfMatches.initialize() , выбран select элемент, имеющий id начало с выделенным input элементом id.   -  person guest271314    schedule 14.04.2015


Ответы (2)


Пытаться

HTML

Обратите внимание, удалены дубликаты id numeratorId в input элементах; заменены numeratorId , denominatorId соответственно. Это также позволяет выбрать элемент select в функции replace.

<select id="numerator">
    <option value="presentation">presentation</option>
    <option value="chemical">chemical</option>
</select>
<input id="numeratorId" class="typeahead" type="text" />
<br/>
<select id="denominator">
    <option value="presentation">presentation</option>
    <option value="chemical">chemical</option>
</select>
<input id="denominatorId" class="typeahead" type="text" />

js

Обратите внимание, bnfMatches не выглядит инициализированным. Добавлено bnfMatches.initialize(); после Bloodhound настроек.

var bnfMatches = new Bloodhound({
      datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      remote: {
          url: '/api/1.0/code?',
          replace: function(url, uriEncodedQuery) {
            var val = $(".typeahead").filter(":focus")
                     .attr("id").slice(0, -2);
            var res = (url + "type=" + $("#" + val).val() + "&code=" 
                      + encodeURIComponent(uriEncodedQuery));
            console.log(res);
            return res
          }
      }
    });

    bnfMatches.initialize();

    $('.typeahead').typeahead({
        hint: true,
        highlight: true,
        minLength: 2
    },
    {
        name: 'states',
        displayKey: 'id',
        source: bnfMatches.ttAdapter()
    });

var bnfMatches = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  remote: {
      url: '/api/1.0/code?',
      replace: function(url, uriEncodedQuery) {
        var val = $(".typeahead").filter(":focus")
                 .attr("id").slice(0, -2);
        var res = (url 
                  + "type=" + $("#" + val).val() + "&code=" 
                  + encodeURIComponent(uriEncodedQuery));
        console.log(res);
        return res
      }
  }
});

bnfMatches.initialize();

$('.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 2
},
{
    name: 'states',
    displayKey: 'id',
    source: bnfMatches.ttAdapter()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script src="http://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>

<select id="numerator">
    <option value="presentation">presentation</option>
    <option value="chemical">chemical</option>
</select>
<input id="numeratorId" class="typeahead" type="text" />
<br/>
<select id="denominator">
    <option value="presentation">presentation</option>
    <option value="chemical">chemical</option>
</select>
<input id="denominatorId" class="typeahead" type="text" />

person guest271314    schedule 14.04.2015
comment
Спасибо. Это один из способов сделать это, и он работает. Было бы лучше передать значение, если это возможно, но если это невозможно, то это невозможно! - person Richard; 14.04.2015
comment
Не за что :) Не уверена интерпретация Было бы лучше передать значение, если это возможно правильно ? replace функция не реализует желаемый шаблон? Возвращает ожидаемые результаты? - person guest271314; 15.04.2015
comment
Я просто имею в виду, что значение второго параметра в функции replace привязано к определенному элементу в DOM с определенным идентификатором. Это то, чего мы обычно стараемся избегать в JS, потому что привязка фрагментов JS напрямую к HTML делает вещи хрупкими. - person Richard; 16.04.2015

replace Bloodhound можно использовать так

replace: function (url, query) {
   if(_el.val() === "users"){
     return url + '/users?q=' + query;
   }else{
     return url + '/repositories?q=' + query;
   }
}

Вот полный пример. В примере я использовал общедоступный API github. Выпадающий список выбора используется для переключения между пользователями и репозиториями.

var make_dataset = function (el) {
    var _el = el; // nearest select for input
    var bloodhound = new Bloodhound({
        datumTokenizer: function (datum) {
            return Bloodhound.tokenizers.whitespace(datum.value);
        },
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
            url: 'https://api.github.com/search',
            filter: function (users) {
                return $.map(users.items, function (user) {
                    return {
                        value: user.url
                    };
                });
            },
            replace: function (url, query) {
                if (_el.val() === "users") {
                    return url + '/users?q=' + query;
                } else {
                    return url + '/repositories?q=' + query;
                }
            }
        }
    });
    bloodhound.initialize();

    var dataset = {
        source: bloodhound.ttAdapter(),
    }

    return dataset;
}

/* initial setup */
$('.typeahead').each(function () { // each input
    var select = $(this).siblings('select'); // select near each input
    $(this).typeahead({
        hint: true,
        highlight: true,
        minLength: 2
    }, make_dataset(select)); // make_dataset initializes a bloodhound instance
});

Вот полная DEMO

Надеюсь это поможет

person Dhiraj    schedule 15.04.2015