17

I cannot seem to get a remote query to use POST properly.

var creditors = new Bloodhound({
    datumTokenizer: function (d) {
        return Bloodhound.tokenizers.whitespace(d.value)
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    remote: {
        url: "../getCreditors",
        replace: function(url, query) {
            return url + "#" + query;
        },
        ajax : {
            type: "POST",
            data: $.param({q: queryInput.val()})
        }
    }
});

the queryInput.val() does not get the current value of the object only the value at the time bloodhound object is instantiated. How can I get the query string into the ajax data options?

Dhaulagiri
  • 3,281
  • 24
  • 26
Matt
  • 873
  • 1
  • 9
  • 24

3 Answers3

16

You can use beforeSend of $.ajax

var creditors = new Bloodhound({
    datumTokenizer: function (d) {
        return Bloodhound.tokenizers.whitespace(d.value)
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    remote: {
        url: "../getCreditors",

        replace: function(url, query) {
            return url + "#" + query;
        },
        ajax : {
            beforeSend: function(jqXhr, settings){
               settings.data = $.param({q: queryInput.val()})
            },
            type: "POST"

        }
    }
});
holylaw
  • 233
  • 2
  • 12
  • 1
    Although this code does call the Ajax method when it should, it doesn't set Content-Type correctly, so ASP.NET MVC, at least, doesn't parse the posted data. – RickNZ Apr 09 '14 at 03:30
  • 2
    This will send with a content-type of "text/plain; charset=UTF-8", if you want it to send as json (like me :D) you'll need to set the content type on the jqXhr object like so: jqXhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); – Nashenas Apr 24 '14 at 15:25
  • Since you're already calling replace, you can use that to store the query to a local variable that you use in beforeSend. It removes the coupling to queryInput. – Snekse Apr 28 '14 at 21:25
  • @Snekse Can you explain your comment a bit more? I tried adding a line in replace `this.q = query` and replacing `queryInput.val()` with `this.q` but `this.q` shows as `undefined` in debugger `beforeSend` function. – Adam Aug 06 '14 at 16:28
  • 1
    This [doesn't work anymore](https://github.com/twitter/typeahead.js/issues/1236). The code in @Atropo's answer does work. – ᴍᴇʜᴏᴠ Jan 07 '16 at 15:18
13

You can use the prepare property with remote or prefetch, mind that the function signature changes. An example with prefetch:

var Bloodhound = new Bloodhound({
                datumTokenizer: Bloodhound.tokenizers.whitespace,
                queryTokenizer: Bloodhound.tokenizers.whitespace,
                prefetch: {
                    url: remote,
                    prepare: function (settings) {
                        settings.type = "POST";
                        settings.contentType = "application/json; charset=UTF-8";
                        return settings;
                    },
                    remote: function (query, settings) {
                        settings.type = "POST";
                        settings.data = {q: query, foo: 'bar'}; // you can pass some data if you need to
                        return settings;
                    }
                }
            });

Remember that with remote the function signature changes with function(query, settings).

For reference: github.com/twitter/typeahead.js/issues/1236

ᴍᴇʜᴏᴠ
  • 4,804
  • 4
  • 44
  • 57
Atropo
  • 12,231
  • 6
  • 49
  • 62
  • You can pass your custom `data` if you need to (e.g. the current value of another field etc.). The current typed-in value will be in the `query` variable – ᴍᴇʜᴏᴠ Jan 07 '16 at 15:21
0

I found the ajax 'beforeSend' method holylaw mentioned worked the best.

It was important to alter the url as well though. Otherwise Typeahead didn't bother making another request. So I just added a bogus parameter at the end of the url. Like this

http://mylittleservice.com?blah=%QUERY

That way when the ajax data packaged changed I was assured a fresh request to the server.

JabberwockyDecompiler
  • 3,318
  • 2
  • 42
  • 54
Jamie Popkin
  • 139
  • 1
  • 4