19

Is there a way to set Jquery's Autocomplete HTTP submission method to POST instead of GET?

George Stocker
  • 57,289
  • 29
  • 176
  • 237
  • Also you can change MVC to allow GET. See http://stackoverflow.com/questions/2350921/asp-net-mvc-2-failed-with-jquery-ajax-response#2350957 – Daveo Apr 01 '11 at 05:42
  • @Daveo: That's true, but we must be cautious about disabling a feature that was intended to protect us from browser vulnerability exploits. – StriplingWarrior May 26 '11 at 17:38
  • 2
    Possibly of interest: A feature request (http://bugs.jqueryui.com/ticket/5353), and an explanation for why it was rejected (http://forum.jquery.com/topic/jqueryui-autocomplete-post-option-for-remote-request#14737000002084408). – StriplingWarrior May 26 '11 at 17:47

5 Answers5

51

Probably better to pass it in with the source parameter rather than setting it globally like this:

$("#input").autocomplete({
    source: function (request, response) {
        $.post("/AjaxPostURL", request, response);
    }
});
robbie
  • 1,103
  • 1
  • 10
  • 13
  • Here is a more complete version of $.post with additional data being passed: $(function() { var options = { url: "/web/ajax.php?a=query-save-projects&w=app", type: 'post', data: { "args":$().crypt({method:"b64enc",source:JSON.stringify(_system) }), "url":document.URL } }; $( "#query-save-project-name" ).autocomplete({ source: function (request, response) { $.post(options["url"], options["data"], response, "json") }, minLength: 2 }); }); – mshaffer May 28 '12 at 21:07
  • This breaks if one of the requests fails. In that case `response` is never called which breaks the autocomplete plugin. Otherwise this is the correct approach. – usr May 13 '16 at 17:10
13

You can use the

$.ajaxSetup( { type: "post" } );

before the call to autocomplete, and it will override the ajax call on the page.

George Stocker
  • 57,289
  • 29
  • 176
  • 237
Schotime
  • 15,707
  • 10
  • 46
  • 75
  • This modifies *all* AJAX calls made through jQuery. This interacts badly with other code running on the page. Highly dangerous. – usr May 13 '16 at 17:10
6

Unfortunately, there is no option to the autocompleter that will allow you to set that. There is, however, a single place in the plugin code where the $.ajax function is called. There is no type option specified, which means that it will default to a GET request. You could modify the $.ajax call (which starts on line 361 of the latest version) to include a type option and set its value to "post":

$.ajax({ //line 361
    type: "post",
    ...
karim79
  • 339,989
  • 67
  • 413
  • 406
  • Modifying the source means you'll have trouble upgrading to the next version. – usr May 13 '16 at 17:09
  • Also, the documentation says that `type: "POST"` is required. Probably, both are working but lowercase is bad style. – usr May 13 '16 at 17:31
1

It's a REALLY bad idea to edit the source code because you'll lose your changes on the next upgrade of the widget. It's better to set the global type to "post" or pass in a request/response object.

WebTigers
  • 297
  • 2
  • 8
  • Making a global POST setting modifies *all* AJAX calls made through jQuery. This interacts badly with other code running on the page. Highly dangerous. – usr May 13 '16 at 17:11
0

I overwrote that one function in our JavaScript file (loaded after jQuery UI) to make it accept GET/POST as another option.

$.ui.autocomplete.prototype._initSource = function() {
    var array, url,
        that = this;
    if ( $.isArray(this.options.source) ) {
        array = this.options.source;
        this.source = function( request, response ) {
            response( $.ui.autocomplete.filter( array, request.term ) );
        };
    } else if ( typeof this.options.source === "string" ) {
        url = this.options.source;
        /*added*/ var httpMethod = this.options.type ? this.options.type : 'GET';
        this.source = function( request, response ) {
            if ( that.xhr ) {
                that.xhr.abort();
            }
            that.xhr = $.ajax({
                url: url,
                data: request,
                dataType: "json",
                /*added*/ type: httpMethod,
                success: function( data ) {
                    response( data );
                },
                error: function() {
                    response( [] );
                }
            });
        };
    } else {
        this.source = this.options.source;
    }
};

I THINK it solves problems mentioned by other people above without breaking anything else:
- Editing the jQuery UI file directly would make upgrading jQuery UI a pain, and prevent you from using Google APIs to host your jQuery files
- $.ajaxSetup would affect every autocomplete or ajax call across our product
- Writing a $.post and passing it in as a function is cool, but a lot of typing if you use dozens of autocompletes across your site.

DrShaffopolis
  • 1,088
  • 1
  • 11
  • 14
  • 1
    Modifying the source means you'll have trouble upgrading to the next version. – usr May 13 '16 at 17:11
  • Fortunately, functions in JavaScript are mutable, so you don't have to. But any changes to that particular function would indeed be lost if a new version of jQuery changed it, though. Which is why you wouldn't want to use this strategy in more than the rarest of circumstances. – DrShaffopolis May 15 '16 at 15:36