0

I am trying to use Twitter Bootstrap typeahead (v2.3.2) with jQuery v1.8.3 to search one subscriber user from big DB table with 20k users, and using many join and union with two or one more DBs.

I know sugests work fine but i want to limit ajax requests to server only by pressing submit button or enter.

My questions is how to start suggestions and search requests only when submit button or Enter is pressed.

My code:

$('input[name="searchSubs"]').typeahead({
    minLength: 2,
    highlight: true,
    hint: true,
    source: function (query, process) {
        var postData = {'query': query};
        $.extend( postData, {'search_field': '2'} );

        return $.post('search/ajax_search/', postData,
            function (response) {
                var data = new Array();
                $.each(response, function(i, item) {
                    data.push(item.subs_id +'_'+ item.firstname + ' ' + item.lastname);
                });
                return process(data);
            },
            'JSON'
        );
      }
    , highlighter: function(item) {
          item = item.replace(new RegExp('(' + this.query + ')', 'ig'), function ($1, match) {
            return '<strong>' + match + '</strong>'
          })
          var parts = item.split('_');
          var subs_id = parts.shift();
          var itm = ''
              + "<div class='typeahead_wrapper'>"
              + "<div class='typeahead_primary'>" + parts.join('_') + "</div>"
              + "<div class='typeahead_secondary'>ID: " + subs_id + "</div>"
              + "</div>";
        return itm;
      }
    , updater: function(item) {
        var parts = item.split('_');
        var subs_id = parts.shift();
        window.location.href = 'home/?subs_id='+subs_id;
        return parts.join('_');
    }
    , matcher: function (item) {
        return ~item.toLowerCase().indexOf(this.query.toLowerCase())
    }
  }
);
Victor Orletchi
  • 469
  • 1
  • 5
  • 15

1 Answers1

0

I needed to grab users input (address line), query google geocoding API (get matching results), and deploy the results using typehead. The described solution worked for me:

1) The typeahead itself ignores the event keycode 13 (the Enter button) so we need to attach a listener to the input field so that on each keypress with code 13 the typeahead 'source' method will get triggered. In order to trigger the typeahead search (as suggested in this answer), we need to clean up the contents of the input field and fill it back again.

$('input[name="searchSubs"]').on('keypress', function(e) {
    if (e.which !== 13) return;

    var $this = $(this),
        val = $this.val();

    $this.typeahead('val', '').focus().typeahead('val', val).focus();
});

2) Now the actual 'source' method will get called with every Enter button hit. OK, but we want this method to ignore the other buttons, right? A call to window.event will reveal the event that caused the call to the 'source'. I will only adjust your 'source' method here:

...
source: function (query, process) {
    // get the current event
    var e = window.event;

    // if the query (basically, input field) is empty 
    // .. or its not the Enter button has caused this call
    if (!query.toString().length || e.which !== 13)
        return;

    var postData = {'query': query};
    $.extend( postData, {'search_field': '2'} );
    ...
}
...

However, as per the typeahead documentation, the 'source' method has a signature of (query, syncResults, asyncResults) so I am not sure whether your example with

...
source: function (query, process)
...

will work properly. In my project I used something along the lines of

...
source: function (query, foo, process)
...

.. and just ignore the foo argument. Calling to the asyncResults (having it as 3rd argument in 'source') actually works for me as expected.

Community
  • 1
  • 1
Ievgen Baziak
  • 93
  • 1
  • 7