пример начальной загрузки Twitter aaax

258

Я пытаюсь найти рабочий пример элемента 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];
                }
            );
       ..

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

<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 '.

  • 0
    Чтобы быть более конкретным, мне интересно, как параметры автозаполнения и функции обработки результатов соответствуют параметрам textahead? Существует ли определенный набор функций обработки результатов текстовых уведомлений, которые можно переопределить, или метод с именем унаследован от базового API jquery.
  • 1
    Не могли бы вы отметить ответ Стейна Ван Баэля как правильный? Ответ Богерта работает только для устаревших версий Bootstrap.
Теги:
jquery-ui-autocomplete
typeahead.js
jquery-autocomplete

14 ответов

297
Лучший ответ

Изменить: 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.

  • 0
    Спасибо за упоминание этого. Я пытаюсь найти пример именно для этого. Таким образом, данные, возвращаемые через $ .get, должны быть JSON, верно?
  • 3
    Как и в форке Typeahead, данные должны быть массивом строк JSON, а тип контента должен быть application / json.
Показать ещё 11 комментариев
121

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

$('.typeahead').typeahead({
    source: function (typeahead, query) {
        return $.get('/typeahead', { query: query }, function (data) {
            return typeahead.process(data);
        });
    }
});
  • 1
    спасибо ... очень помогло ... красиво и просто ...
  • 1
    «Умное предположение» jQuery для типа возврата данных POST не работало, когда я вернулся, например, ["aardvark", "apple"] . Мне пришлось явно установить параметр dataType в вызове $.post . Смотрите jQuery.post () .
Показать ещё 8 комментариев
69

Начиная с 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);
            }
        });
    }
});

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

  • 8
    Это должно быть помечено как новый принятый ответ.
  • 11
    Но я бы изменил его на использование $(this)[0].$element.data('link') .
Показать ещё 1 комментарий
35

Все ответы относятся к 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, чтобы отображать ваши объекты в виде текста.

  • 0
    Спасибо. Еще один вопрос: с processAsync я получаю «TypeError: ideas.slice не является функцией». Как должен выглядеть возвращаемый JSON? Вот мое лучшее предположение: {: ideas => ["Thing 1", "Thing 2", "Thing 3"]}
  • 1
    Убедитесь, что вы возвращаете правильную строку JSON. Ваша функция предложения AJAX должна возвращать массив строк, например, ["Thing 1","Thing 2"] , или с пользовательской функцией отображения, массив объектов в соответствии с вашими потребностями, например, [{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}]
Показать ещё 3 комментария
25

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

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

Здесь github repo: Ajax-Typeahead

  • 0
    Я посмотрел код Gudbergur; честно говоря, мне больше всего понравился этот. Это немного более дружелюбно и предлагает больше функциональности. Хорошая работа, Пол! Единственное, что я хотел бы предложить, это в вашем README напомнить пользователю, что ему нужно проанализировать свои JSON-данные в JS, чтобы ваш код мог правильно их использовать. Я предполагал, что вы разбираете это для меня, так что повесил меня немного. В остальном, довольно мило, спасибо! :)
  • 3
    Ваш сервер возвращает строку вместо объекта JSON. jQuery $ .ajax () используется для выполнения вызова, и он заботится о разборе.
Показать ещё 2 комментария
5

Я сделал некоторые изменения на 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;        
}

Прекрасно работает.

  • 0
    какую версию jquery ui min вы используете?
  • 0
    Если вам это нужно для jQuery 1.7.1 и jQuery UI 1.8.16, то я создал GIST на основе вышеуказанного исправления, которое показывает, где изменить файл jQuery UI. gist.github.com/1884819 - строки закомментированы // изменено
Показать ещё 2 комментария
2

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

$('.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');
    }
});
  • 0
    Было бы хорошо, если бы вы могли добавить какое-то объяснение к вашему ответу. Например, в чем отличие вашего решения от решений, представленных в уже существующих ответах?
2

Я прошел этот пост, и все не работало правильно и в итоге собрало несколько бит из нескольких ответов, поэтому у меня есть 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>
2

Тем, кто ищет версию одобренного ответа coffeescript:

$(".typeahead").typeahead source: (query, process) ->
  $.get "/typeahead",
    query: query
  , (data) ->
    process data.options
2

Можно совершать вызовы с помощью 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,
});
1

Попробуйте, если ваша служба не возвращает правильный заголовок содержимого приложения /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);
        });
    }
});
1

UPDATE: я изменил свой код, используя this fork

также вместо использования $.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

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

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

  • 0
    Не имеет отношения к OP: я бы использовал Array.map вместо $.each и заменил бы содержимое всей функции обратного вызова success на var manufacturers = results.data.manufacturers.map(function (item) { return { id: item.Manufacturer.id, manufacturer: item.Manufacturer.manufacturer } });
  • 0
    спасибо @TomislavMarkovski Я изменил свой код, как вы предлагаете.
0

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

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

0

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

Если вы посмотрите на код 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, если у вас возникнут проблемы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню