twitter bootstrap typeahead пример ajax

Я пытаюсь найти рабочий пример элемента twitter bootstrap typeahead, который вызовет ajax-вызов заполните его раскрывающийся список.

У меня есть существующий рабочий пример автозаполнения jquery, который определяет URL-адрес ajax и способ обработки ответа

<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
    var options = { minChars:3, max:20 };
    $("#runnerquery").autocomplete('./index/runnerfilter/format/html',options).result(
            function(event, data, formatted)
                {
                    window.location = "./runner/index/id/"+data[1];
                }
            );
       ..

Что мне нужно изменить, чтобы преобразовать это в пример typeahead?

<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
    var options = { source:'/index/runnerfilter/format/html', items:5 };
    $("#runnerquery").typeahead(options).result(
            function(event, data, formatted)
                {
                    window.location = "./runner/index/id/"+data[1];
                }
            );
       ..

Я собираюсь дождаться решения проблемы «Добавить поддержку удаленных источников для typeahead».


person emeraldjava    schedule 10.02.2012    source источник
comment
Чтобы быть более конкретным, мне интересно, как параметры автозаполнения и функция обработки результатов сопоставляются с параметрами textahead? Есть ли набор определенных функций обработки результатов textalert, которые можно переопределить, или метод с именем унаследован от базового jquery api.   -  person emeraldjava    schedule 11.02.2012
comment
Не могли бы вы сейчас отметить ответ Стейна Ван Баэля как правильный? Ответ Богерта работает только для устаревших версий Bootstrap.   -  person Giles Roberts    schedule 15.06.2013


Ответы (15)


Изменить: typeahead больше не входит в состав Bootstrap 3. Проверьте:

Начиная с Bootstrap 2.1.0 и до 2.3.2, вы можете сделать это:

$('.typeahead').typeahead({
    source: function (query, process) {
        return $.get('/typeahead', { query: query }, function (data) {
            return process(data.options);
        });
    }
});

Чтобы использовать данные JSON следующим образом:

{
    "options": [
        "Option 1",
        "Option 2",
        "Option 3",
        "Option 4",
        "Option 5"
    ]
}

Обратите внимание, что данные JSON должны иметь правильный тип mime (application / json), поэтому jQuery распознает их как JSON.

person Stijn Van Bael    schedule 23.08.2012
comment
Спасибо, что упомянули об этом. Я пытаюсь найти пример именно этому. Значит, данные, возвращаемые через $ .get, должны быть JSON, верно? - person Houman; 04.09.2012
comment
Как и в вилке Typeahead, данные должны быть массивом строк JSON, а тип содержимого должен быть application / json. - person Stijn Van Bael; 05.09.2012
comment
может ли 2.1 использовать json, который не является просто массивом строк? Мне нужно указать значение для пользователя и использовать идентификатор для дальнейшей обработки. Возможно ли это, если не взять кастомную вилку? - person Anton; 10.09.2012
comment
@Anton: вы можете выполнить обработку в анонимной функции перед вызовом процесса (...) - person Stijn Van Bael; 21.09.2012
comment
@Stijin Есть ли примеры того, как эта анонимная функция будет использоваться здесь для обработки идентификатора отображаемой опции? Спасибо! - person Acyra; 03.02.2013
comment
Я хотел бы отметить, что использование этого метода приводит к тому, что вызываемый AJAX создается для каждого нажатия клавиши при вводе. Если сервер возвращает по существу статические данные (т.е. на самом деле ничего не делает с запросом), это может быть довольно расточительным. - person Dologan; 08.02.2013
comment
Мое решение состояло в том, чтобы заставить его возвращать ранее объявленную глобальную переменную, которая заполняется при первом вызове: var opt_arr; $('.typeahead').typeahead({ source: function (useless, callback) { if (opt_arr) { return opt_arr; } else { $.getJSON('/static_json', function(data) { opt_arr = data; callback(opt_arr); }); } } }); - person Dologan; 08.02.2013
comment
Единственное, что меня сбило с толку, - это оставить атрибут data-provide = typeahead в элементе ‹input›. Вызов AJAX не будет выполняться с установленным атрибутом. Я забыл удалить его после тестирования более простого примера. - person yukondude; 25.03.2013
comment
зачем использовать get вместо getJSON? Кажется более подходящим. - person greg0ire; 21.05.2013
comment
@StijnVanBael, извините ... как вы сказали, bootrap 3 больше не поддерживает это, так что по вашей идее, что лучше для этого в сети? - person neda Derakhshesh; 10.07.2016
comment
Использование typeahead.js было бы подходящим вариантом - person Stijn Van Bael; 11.07.2016
comment
Я успешно использовал это решение даже с Bootstrap 3. Структура функции такова: source : function(q, pr) {return $.get(searchUrl, {query:q}, function(resp) {return pr(resp);}); } - person twigmac; 10.03.2017
comment
Обновление моего комментария: я использовал для этого Bootstrap-3-Typeahead. - person twigmac; 10.03.2017

Вы можете использовать вилку BS Typeahead, которая поддерживает вызовы ajax. Тогда вы сможете написать:

$('.typeahead').typeahead({
    source: function (typeahead, query) {
        return $.get('/typeahead', { query: query }, function (data) {
            return typeahead.process(data);
        });
    }
});
person bogert    schedule 24.02.2012
comment
Интеллектуальное предположение jQuery для типа возврата данных POST не работало, когда я возвращал, например, ["aardvark", "apple"]. Мне пришлось явно установить параметр dataType в вызове $.post. См. jQuery.post (). - person Rusty Fausak; 20.03.2012
comment
@rfausak В качестве альтернативы установите заголовок Content-type на application/json - person Rusty Fausak; 20.03.2012
comment
Я получаю Uncaught TypeError: невозможно вызвать метод toLowerCase из undefined - person Krishna Prasad Varma; 04.06.2012
comment
В присланной вами ссылке я даже не могу выполнить функцию source. - person James; 13.06.2012
comment
Я решил проблему. Невозможно вызвать метод toLowerCase из undefined, поигравшись с порядком загрузки js-скриптов (jquery, bootstrap, typeahead). - person javanna; 13.07.2012
comment
Я думаю, что асинхронный вызов должен быть $ .getJSON - person Tony; 02.08.2012
comment
Хороший ответ! Вместо этого я бы использовал запрос GET, просто чтобы соответствовать стандартам REST. - person Mauro; 31.08.2012
comment
привет, я обнаружил, что это решение анализирует ошибку, и решение stackoverflow.com/questions/11178512/, чтобы быть полезным - person devmonster; 02.12.2012
comment
простой пример создания умного автозаполнения с напечатанным текстом twitter bootstrap. Мне это нужно для проекта. Наслаждаться. gist.github.com/mrgcohen/5062352 - person mc.; 01.03.2013

Начиная с Bootstrap 2.1.0:

HTML:

<input type='text' class='ajax-typeahead' data-link='your-json-link' />

Javascript:

$('.ajax-typeahead').typeahead({
    source: function(query, process) {
        return $.ajax({
            url: $(this)[0].$element[0].dataset.link,
            type: 'get',
            data: {query: query},
            dataType: 'json',
            success: function(json) {
                return typeof json.options == 'undefined' ? false : process(json.options);
            }
        });
    }
});

Теперь вы можете сделать единый код, разместив в своем HTML-коде ссылки «json-запрос».

person Thantifaxath    schedule 31.10.2012
comment
Но я бы изменил его на $(this)[0].$element.data('link'). - person Andrew Ellis; 02.02.2013

Все ответы относятся к типу BootStrap 2 typeahead, которого больше нет в BootStrap 3.

Для всех, кто направлен сюда и ищет пример AJAX с использованием нового пост-Bootstrap Twitter typeahead.js, вот рабочий пример. . Синтаксис немного другой:

$('#mytextquery').typeahead({
  hint: true,
  highlight: true,
  minLength: 1
},
{
  limit: 12,
  async: true,
  source: function (query, processSync, processAsync) {
    processSync(['This suggestion appears immediately', 'This one too']);
    return $.ajax({
      url: "/ajax/myfilter.php", 
      type: 'GET',
      data: {query: query},
      dataType: 'json',
      success: function (json) {
        // in this example, json is simply an array of strings
        return processAsync(json);
      }
    });
  }
});

В этом примере используются как синхронное (вызов processSync), так и асинхронное предложение, поэтому вы увидите, что некоторые параметры появляются сразу, а затем добавляются другие. Вы можете просто использовать одно или другое.

Существует множество привязываемых событий и несколько очень мощных опций, в том числе работа с объектами, а не со строками, и в этом случае вы должны использовать собственную настраиваемую функцию display для визуализации элементов в виде текста.

person Jonathan Lidbeck    schedule 20.05.2015
comment
Спасибо. Еще один вопрос: с processAsync я получаю TypeError: offers.slice не является функцией. Как должен выглядеть возвращенный JSON? Вот мое лучшее предположение: {: questions = ›[Thing 1, Thing 2, Thing 3]} - person user1515295; 26.11.2015
comment
Убедитесь, что вы вернули допустимую строку JSON. Ваша функция предложения AJAX должна возвращать массив строк, например ["Thing 1","Thing 2"] или с помощью настраиваемой функции отображения - массив объектов в соответствии с вашими потребностями, например [{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}] - person Jonathan Lidbeck; 27.11.2015
comment
Я возвращаю [{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}], теперь я хочу показать два столбца в раскрывающемся списке с идентификатором и меткой. Как я могу это сделать? - person Vishal; 26.02.2017
comment
О ГОСПОДИ!!! Я искал последние 3 дня, никто не упомянул об этом. До сих пор я тестировал функцию синхронизации. СПАСИБО ЧУВАК!! - person Gilson PJ; 24.01.2018
comment
Спасибо ! Отлично работает с bootstrap 4.3 и jquery 3.4. Но перечисленные параметры не выделяются при наведении на них указателя мыши. Я думал, что это должно было быть частью самого Typeahead. - person Binita Bharati; 10.10.2019

Я дополнил оригинальный плагин Bootstrap typeahead возможностями ajax. Очень просто использовать:

$("#ajax-typeahead").typeahead({
     ajax: "/path/to/source"
});

Вот репозиторий github: Ajax-Typeahead

person Paul Warelis    schedule 05.05.2012
comment
Я посмотрел код Гудбергура; честно говоря, мне больше всего понравился этот. Это немного более дружелюбно и предлагает больше функциональных возможностей. Хорошая работа, Пол! Единственное, что я бы посоветовал, - это напомнить пользователю в README, что им нужно проанализировать свои данные JSON в JS, чтобы ваш код мог правильно их использовать. Я предположил, что вы разбираете его для меня, поэтому я ненадолго повесил трубку. В остальном очень приятно, спасибо! :) - person Bane; 10.05.2012
comment
Ваш сервер возвращает строку вместо объекта JSON. $ .ajax () jQuery используется для выполнения вызова и выполняет синтаксический анализ. - person Paul Warelis; 12.05.2012
comment
абсолютно правильно, спасибо за улов! :) Этот плагин работает очень хорошо. - person Bane; 14.05.2012
comment
Здравствуйте, как должна выглядеть JSON сторона сервера? Я получаю Uncaught TypeError: Cannot read property 'length' of undefined . Я использую json_encode($array) и отправляю правильные заголовки ('Content-Type: application/json; charset=utf-8'). версия jquery jQuery v1.9.1 - person Kyslik; 10.07.2013

Я внес некоторые изменения в jquery-ui.min.js:

//Line 319 ORIG:
this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(...
// NEW:
this.menu=d("<ul></ul>").addClass("ui-autocomplete").addClass("typeahead").addClass("dropdown-menu").appendTo(d(...

// Line 328 ORIG:
this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr...
// NEW:this.element.attr....

// Line 329 ORIG:
this.active=a.eq(0).children("a")
this.active.children("a")
// NEW:
this.active=a.eq(0).addClass("active").children("a")
this.active.removeClass("active").children("a")`

и добавьте следующий css

.dropdown-menu {
    max-width: 920px;
}
.ui-menu-item {
    cursor: pointer;        
}

Отлично работает.

person bmoers    schedule 12.02.2012
comment
какую версию jquery ui min вы используете? - person emeraldjava; 14.02.2012
comment
Если вам это нужно для jQuery 1.7.1 и jQuery UI 1.8.16, я создал GIST на основе вышеуказанного исправления, которое показывает, где изменить файл пользовательского интерфейса jQuery. gist.github.com/1884819 - строки комментируются с помощью // изменено - person RidingTheRails; 22.02.2012
comment
Это довольно старый вопрос / ответ, но я просто хочу сказать, что всегда плохая практика изменять код сторонних компонентов. Вам придется пересматривать все изменения каждый раз, когда вы их обновляете. В этом конкретном случае виджеты jQuery могут быть унаследованы, что является гораздо более безопасным способом их настройки. Итак, по сути, создайте свой собственный виджет, наследуйте его от основного (в данном случае автозаполнение) и дайте волю своему воображению! :) - person AlexCode; 22.04.2014

Я использую этот метод

$('.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 1
},
    {
    name: 'options',
    displayKey: 'value',
    source: function (query, process) {
        return $.get('/weather/searchCity/?q=%QUERY', { query: query }, function (data) {
            var matches = [];
            $.each(data, function(i, str) {
                matches.push({ value: str });
            });
            return process(matches);

        },'json');
    }
});
person Krava    schedule 22.12.2014
comment
Было бы неплохо, если бы вы могли добавить к своему ответу пояснения. Например, чем ваше решение отличается от решений, представленных в уже существующих ответах? - person honk; 22.12.2014

Звонить можно с помощью Bootstrap. В текущей версии нет проблем с обновлением исходного кода. Проблемы с обновлением типа Bootstrap. источник данных с ответом на публикацию, т.е. после обновления источник начальной загрузки может быть снова изменен.

См. Пример ниже:

jQuery('#help').typeahead({
    source : function(query, process) {
        jQuery.ajax({
            url : "urltobefetched",
            type : 'GET',
            data : {
                "query" : query
            },
            dataType : 'json',
            success : function(json) {
                process(json);
            }
        });
    },
    minLength : 1,
});
person neoeahit    schedule 07.05.2013

Тем, кто ищет версию принятого ответа на кофе:

$(".typeahead").typeahead source: (query, process) ->
  $.get "/typeahead",
    query: query
  , (data) ->
    process data.options
person Hendrik    schedule 24.06.2013

Я просмотрел этот пост, и все не хотело работать правильно, и в конечном итоге я собрал биты вместе из нескольких ответов, поэтому у меня есть 100% рабочая демонстрация, и я вставлю ее сюда для справки - вставьте это в файл php и убедитесь, что включает в себя в нужном месте.

<?php if (isset($_GET['typeahead'])){
    die(json_encode(array('options' => array('like','spike','dike','ikelalcdass'))));
}
?>
<link href="bootstrap.css" rel="stylesheet">
<input type="text" class='typeahead'>
<script src="jquery-1.10.2.js"></script>
<script src="bootstrap.min.js"></script>
<script>
$('.typeahead').typeahead({
    source: function (query, process) {
        return $.get('index.php?typeahead', { query: query }, function (data) {
            return process(JSON.parse(data).options);
        });
    }
});
</script>
person l0ft13    schedule 04.07.2013

Попробуйте это, если ваша служба не возвращает правильный заголовок типа содержимого application / json:

$('.typeahead').typeahead({
    source: function (query, process) {
        return $.get('/typeahead', { query: query }, function (data) {
            var json = JSON.parse(data); // string to json
            return process(json.options);
        });
    }
});
person Andres    schedule 16.09.2015

ОБНОВЛЕНИЕ: я изменил свой код, используя эту вилку

также вместо использования $ .each я изменил на $ .map, как предложил Томислав Марковский

$('#manufacturer').typeahead({
    source: function(typeahead, query){
        $.ajax({
            url: window.location.origin+"/bows/get_manufacturers.json",
            type: "POST",
            data: "",
            dataType: "JSON",
            async: false,
            success: function(results){
                var manufacturers = new Array;
                $.map(results.data.manufacturers, function(data, item){
                    var group;
                    group = {
                        manufacturer_id: data.Manufacturer.id,
                        manufacturer: data.Manufacturer.manufacturer
                    };
                    manufacturers.push(group);
                });
                typeahead.process(manufacturers);
            }
        });
    },
    property: 'name',
    items:11,
    onselect: function (obj) {

    }
});

Однако я столкнулся с некоторыми проблемами, получив

Uncaught TypeError: невозможно вызвать метод toLowerCase из undefined

как вы можете видеть в новом сообщении, я пытаюсь выяснить здесь

надеюсь, что это обновление вам поможет ...

person mmoscosa    schedule 21.06.2012
comment
Не связано с OP: я бы использовал Array.map вместо $.each и заменил бы содержимое всей вашей success функции обратного вызова на var manufacturers = results.data.manufacturers.map(function (item) { return { id: item.Manufacturer.id, manufacturer: item.Manufacturer.manufacturer } }); - person Tomislav Markovski; 27.06.2012
comment
спасибо @TomislavMarkovski Я изменил свой код, как вы предлагаете. - person mmoscosa; 28.06.2012
comment
В последней версии используйте отображение вместо свойства. - person Dhara; 05.01.2021

У меня нет ни рабочего примера, ни очень чистого решения, но позвольте мне рассказать вам, что я нашел.

Если вы посмотрите на код javascript для TypeAhead, он выглядит так:

items = $.grep(this.source, function (item) {
    if (that.matcher(item)) return item
  })

Этот код использует метод jQuery «grep» для сопоставления элемента в исходном массиве. Я не видел никаких мест, где можно было бы перехватить вызов AJAX, так что "чистого" решения здесь нет.

Однако есть один довольно хитрый способ сделать это - воспользоваться тем, как метод grep работает в jQuery. Первый аргумент grep - это исходный массив, а второй аргумент - это функция, которая используется для сопоставления исходного массива (обратите внимание, что Bootstrap вызывает «сопоставитель», который вы указали при его инициализации). Что вы можете сделать, так это установить источник в фиктивный одноэлементный массив и определить сопоставитель как функцию с вызовом AJAX в нем. Таким образом, вызов AJAX будет выполнен только один раз (поскольку исходный массив содержит только один элемент).

Это решение не только хакерское, но и страдает от проблем с производительностью, поскольку код TypeAhead предназначен для поиска при каждом нажатии клавиши (вызовы AJAX действительно должны происходить только при каждом нажатии нескольких клавиш или после определенного времени простоя). Мой совет - попробовать, но придерживайтесь либо другой библиотеки автозаполнения, либо используйте ее только в ситуациях, отличных от AJAX, если у вас возникнут какие-либо проблемы.

person Aamer Abbas    schedule 13.02.2012

при использовании ajax попробуйте $.getJSON() вместо $.get(), если у вас возникли проблемы с правильным отображением результатов.

В моем случае, когда я использовал $.get(), я получал только первый символ каждого результата, хотя я использовал json_encode() на стороне сервера.

person larsbo    schedule 16.05.2013

я использую $().one() для решения этой проблемы; Когда страница загружена, я отправляю ajax на сервер и жду завершения. Затем передайте результат в функцию .$().one() важно. Потому что заставьте typehead.js присоединиться к input один раз. извините за плохое письмо.

(($) => {
    
    var substringMatcher = function(strs) {
        return function findMatches(q, cb) {
          var matches, substringRegex;
          // an array that will be populated with substring matches
          matches = [];
      
          // regex used to determine if a string contains the substring `q`
          substrRegex = new RegExp(q, 'i');
      
          // iterate through the pool of strings and for any string that
          // contains the substring `q`, add it to the `matches` array
          $.each(strs, function(i, str) {
            if (substrRegex.test(str)) {
              matches.push(str);
            }
          });
          cb(matches);
        };
      };
      
      var states = [];
      $.ajax({
          url: 'https://baconipsum.com/api/?type=meat-and-filler',
          type: 'get'
      }).done(function(data) {
        $('.typeahead').one().typeahead({
            hint: true,
            highlight: true,
            minLength: 1
          },
          {
            name: 'states',
            source: substringMatcher(data)
          });
      })
      

})(jQuery);
.tt-query, /* UPDATE: newer versions use tt-input instead of tt-query */
.tt-hint {
    width: 396px;
    height: 30px;
    padding: 8px 12px;
    font-size: 24px;
    line-height: 30px;
    border: 2px solid #ccc;
    border-radius: 8px;
    outline: none;
}

.tt-query { /* UPDATE: newer versions use tt-input instead of tt-query */
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}

.tt-hint {
    color: #999;
}

.tt-menu { /* UPDATE: newer versions use tt-menu instead of tt-dropdown-menu */
    width: 422px;
    margin-top: 12px;
    padding: 8px 0;
    background-color: #fff;
    border: 1px solid #ccc;
    border: 1px solid rgba(0, 0, 0, 0.2);
    border-radius: 8px;
    box-shadow: 0 5px 10px rgba(0,0,0,.2);
}

.tt-suggestion {
    padding: 3px 20px;
    font-size: 18px;
    line-height: 24px;
    cursor: pointer;
}

.tt-suggestion:hover {
    color: #f0f0f0;
    background-color: #0097cf;
}

.tt-suggestion p {
    margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>

<input class="typeahead" type="text" placeholder="where ?">

person ali karimi    schedule 05.05.2018