Typeahead.js - показать, что есть больше результатов

Я использую typeahead.js, и все работает отлично для меня, кроме одного:

Я покажу только 5 записей в раскрывающемся списке предложений, но если есть больше результатов, я хотел бы показать пользователю, что есть больше результатов (но не самих результатов, просто информация, что есть больше результатов) так что он продолжает печатать.

  • Мне не нужна панель прокрутки
  • Я не хочу показывать другие результаты.
  • Просто информация, что есть больше результатов

См. прикрепленный экран.

enter image description here

Ответ 1

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

    var addresses = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('number'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        limit: 20,
        remote: {
            url: 'url?q=%QUERY',
            filter: function(list) {
                $('#search-total').html(list.length);
                return list;
            }
        }
    });

Ответ 2

Я искал точно то же самое и думаю, что это то, что вам нужно (см. комментарий от jharding от 4 февраля 2014 года): https://github.com/twitter/typeahead.js/issues/642#issuecomment-34025203

Пример в ссылке также работает для шаблона footer, как показано ниже.

Вы можете сохранить количество результатов где-то в DOM из функции filter Bloodhound (где у вас есть доступ к результату вашего запроса AJAX), например:

var bloodHound = new Bloodhound({
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  limit: 5,
  remote: {
      url: url+'%QUERY',
      filter: function (srcs) {
        // store field JSON response to the DOM
        $('#num-results').html(srcs.numResults);
        ...
      }
    }
});
bloodHound.initialize();

Теперь ключевой момент из ссылки выше: Вы можете обернуть шаблон Handlebars (который фактически является функцией) и расширить/заменить контекст Handlebars, переданный шаблону следующим образом:

var footerTmpl = Handlebars.compile('{{numResults}} results for {{query}}');

var footer = function(context) {
  var numResults = $('#num-results').html();
  var data = { 'numResults': numResults, 'query': context.query };
  return footerTmpl(data);
}

// ...
templates: {
  footer: footer
}
// ...

Ответ 3

Проблема может быть от bloodhound в строке 596

enter image description here

Ответ 4

Typeahead.js имеет шаблон нижнего колонтитула. В документации для этого указано:

footer - отображается внизу базы данных. Может быть либо HTML строка или предварительно скомпилированный шаблон. Если это предварительно скомпилированный шаблон, в контексте будет содержать запрос и isEmpty.

Следовательно, это не позволит вам отправлять объект предложения в качестве контекста, который вы могли бы использовать для отправки отчета по счету поиска (т.е. сообщение "23 результата" в вашем примере). Он использует только запрос и isEmpty, например.

footer: Handlebars.compile("<b>Searched for '{{query}}'</b>")

Пример typeahead.js с помощью механизма шаблонов Handlebars можно найти здесь:

http://jsfiddle.net/Fresh/d7jdp03d/

Ответ 5

Я искал то же самое и наткнулся на ваш вопрос. Я, наконец, понял это для меня, надеюсь, это поможет. Для контекста это приложение Backbone/Marionette, поэтому мое решение может немного отличаться от его настройки. Счет результатов отображается в шаблоне header, определенном jQuery#typeahead(options, [*datasets]), который вызывается в моем элементе ввода (где пользователь вводит в свой поисковый запрос).

Внутри инициализации new Bloodhound, которая происходит в функции source, я устанавливаю счет результатов в пределах параметра фильтра. Я сохраняю его в переменной ItemView. Я вроде взломал this (Marionette.ItemView), сохранив его в переменной self в начале. Обязательно return results.

source: function () {
  var self = this;
   return new Bloodhound({
   datumTokenizer: Bloodhound.tokenizers.whitespace,
   queryTokenizer: Bloodhound.tokenizers.whitespace,
   remote: {
    url: 'my/search/endpoint',
    filter: function (results) {
      self.resultsCount = results.length;
      return results;
    }
  }
 })
}

Эта функция source вызывается внутри вызова typeahead:

$('.typeahead').typeahead({
  minLength: 3,
  highlight: true
},
{
  name: 'my-dataset',
  source: this.source(),
  templates: {
    header: require('my/header_template'),
    empty: require('my/empty_template'),
    suggestion: require('my/suggestion_template')
  }
});

Это происходит в onRender Marionette.ItemView, где я могу вставить значение this.resultsCount в элемент DOM, который находится в шаблоне заголовка. Вы можете использовать событие typeahead:render. Здесь я в основном проверяю, что мой элемент DOM, который собирается хранить счет, есть, и я показываю общее количество минус количество элементов, отображаемых в tt-menu (я просто подсчитаю, сколько tt-suggestion находится на странице). Я скрываю ссылку "больше", пока не будет показано больше, нажав.

$('.search-input').on('typeahead:render', function (ev, suggestions, flag, dataset) {
  if ($('.num-results').length) {
    var moreCount = this.resultsCount - $('.tt-suggestion').length;

    $('.num-results').text(moreCount);
    if (moreCount > 0) {
      $('.more').removeClass('hidden');
    } else {
      $('.more').addClass('hidden');
    }
  }
}.bind(this))

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

Ответ 6

Его старый вопрос, но мне потребовалось много времени, чтобы понять простую вещь. вот моя попытка

инициализировать глобальную переменную

var totalSearchResults;

а затем добавьте глобальную переменную фильтра и обновления.

   var engine = new Bloodhound({
    remote: {
        url: '/search?q=%QUERY%',
        wildcard: '%QUERY%',
        filter: function (list) {
            window.totalSearchResults = list.length;
            return list;
        }
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title'),
});

init typhead

$('#demo-input').typeahead({
    hint: true,
    highlight: true,
    minLength: 1,
    limit: 6,
}, {
    templates: {
        suggestion: suggestion_template,
        footer: footer_template,
    }
});

показывать результаты в шаблоне нижнего колонтитула, подобном этому

   var footer_template = function (context) {
    return '<div class="suggestion-footer"><a href="/search?q=' + context.query + '">View All ('+window.totalSearchResults+') Results </a></div>';
};