28

I am referring specifically to the jQuery Autocomplete v1.1 plugin by Jörn Zaefferer [source: http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/] as there seems to be quite a few variations of this plugin.

I'm trying to pass additional parameters to the server when the user starts typing because I have multiple fields that I want autocomplete to provide suggestions for.

In addition to the query, I want to send the input name attribute to the server but I can't seem to use $(this).attr('name') within the extraParams.

My jQuery:

   $('.ajax-auto input').autocomplete('search.php', {
     extraParams: {
      search_type: function(){
       return $(this).attr('name');
      }
     }
   })

This is my HTML.

 <form method="post" action="#" id="update-form" autocomplete="off">
  <ol>
         <li class="ajax-auto">
             <label for="form-initials">Initials</label>
                <input type="text" id="form-initials" name="initials" />
            </li>
         <li class="ajax-auto">
             <label for="form-company">Company</label>
                <input type="text" id="form-company" name="company" />
            </li>
  </ol>
 </form>

Any suggestions?

paperclip
  • 2,280
  • 6
  • 28
  • 39

13 Answers13

47

I am using the autocomplete function that is now part of jQuery UI. Passing an 'extraParams' field does not work but you can just append the values in the request query string.

$(document).ready(function() {
    src = 'http://example.com/index.php';

    // Load the cities straight from the server, passing the country as an extra param
    $("#city_id").autocomplete({
        source: function(request, response) {
            $.ajax({
                url: src,
                dataType: "json",
                data: {
                    term : request.term,
                    country_id : $("#country_id").val()
                },
                success: function(data) {
                    response(data);
                }
            });
        },
        min_length: 3,
        delay: 300
    });
});
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
ramonhimera
  • 506
  • 5
  • 4
  • 4
    Important to note that this is the correct answer for the currently suggested way of using an Autocomplete extender built into the jQuery UI. It gets confusing for new users because there was so *much* blogged and written about the 'Jörn Zaefferer' version which was the predecessor to the built in version. http://www.learningjquery.com/2010/06/autocomplete-migration-guide – atconway Sep 13 '11 at 19:41
  • When u have multiple autocomplete fields u can use this.element to access the actual one – Elia Weiss Dec 28 '13 at 11:08
4

Try this:

$('.ajax-auto input').setOptions({
  extraParams: {
    search_type: function(){
      return $(this).attr('name');
    }
  }
})

See also here

takrl
  • 6,356
  • 3
  • 60
  • 69
Nam Le
  • 1,126
  • 7
  • 7
2

You can use the built in jquery ui autocomplete like so:

          $(function() {
         $("#BurroughName").autocomplete({
                minLength: 0,
                source: function( request, response) {
                            $.ajax({
                                        url: "/JsonData/GetBurroughFromSearchTermJson",
                                        dataType: "json",
                                        data: {
                                                    term: request.term,
                                                    CityId: $("#CityId").val()
                                        },
                                        success: function( data ) {
                                                    response( data );
                                        }
                            });
                },                  
                select: function( event, ui) {
                    $("#BurroughId").val(ui.item.id);

                    if (ui.item.id != null) {
                         var cityId = $('#CityId').val();
                        $.getJSON("/AdSales/City.mvc/GetCityJSONListFromBrand", { burroughId: ui.item.id }, function(data) {
                             $("#CityId").fillSelect(data);
                             var foo = $("#CityId option[value=" + cityId + "]");
                             if(($("#CityId option[value=" + cityId + "]").length > 0) && cityId != "")
                             {
                                 $("#CityId").val(cityId);
                             }
                        });
                    }
                    $('#burroughSpinner').fadeOut('slow', function(){});
                }
         });
     });

Here's their jsonp example: http://jqueryui.com/demos/autocomplete/#remote-jsonp

Dan Csharpster
  • 2,662
  • 1
  • 26
  • 50
2

I had a similar Problem... don't know if it will work for you ....

I Tried

 $("#awbCusName").autocomplete("getOracleCus.php?",{
  extraParams: {
  ZONE: function() { return $("#awbZone").val(); }, 
  SE: function() { return $("#awbSE").val(); }, 
  WSC: function() { return $("#awbWSC").val(); } 
 },
delay:200,
selectOnly:true,
cacheLength:0,
autoFill:true,
matchSubset:true,
minChars:1
});

CACHELENGTH:0 did the trick

Thanks

farness
  • 369
  • 2
  • 11
1
jQuery( "#jac" ).autocomplete({
    source: autocompleteURL,
    minLength: 2,
    search: function( event, ui ) { 

        // update source url by adding new GET params
        $(this).autocomplete( 'option', 'source', autocompleteURL + 'var1=aaa&var2=bbb' );
    }
})

Works for me with jquery.ui.autocomplete 1.8.17

jszoja
  • 339
  • 3
  • 7
1

Using the autocomplete in JQuery 1.7.something...

Using an aspx data grid: I needed autocomplete to fire for any record choosen but with different seed data based on the value entered. I also needed two other fields that are being displayed in the record on the data grid to get my data for the autocomplete. The fields I need to reference all have their own class name.

    $(".AutoSearch").autocomplete({
            DateTime: "",
            Maker: "",
            search: function (event, ui) {
                DateTime = $(this).parent().parent().parent().find(".DateTime").text();
                Maker = $(this).parent().parent().parent().find(".Maker").text();
            },
            source: function (request, response) {
                $.ajax({
                    type: "POST",
                    dataType: "json",
                    url: "AutoList.aspx/GetListOfAutos",
                    data: "{ " +
                        "'DateTime': '" + DateTime + "', " +
                        "'Maker': '" + Maker + "', " +
                        "'SearchSeed': '" + request.term + "', " +
                        "'NumberToRetrieve': '" + 100 + "'" +
                    " }",
                    contentType: "application/json; charset=utf-8",
                    success: function (data) {
                        response($.map(data.d, function (item) {
                            return {
                                label: item.Description,
                                value: item.Number
                            }
                        }));
                    },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                        alert("There was an error retrieving the Data.");
                    }
                });
            },
            change: function (event, ui) {
                $(this).parent().parent().parent().parent().parent().parent().css("background-color", "#EEC900");
                $(this).parent().parent().parent().parent().parent().parent().find(".chkReadyExport").find("input:checkbox").prop("checked", false);
            },
            select: function (event, ui) {
                this.value = ui.item.value;
                return false;
            },
            minlength: 6,
            open: function () {
                $(this).removeClass("ui-corner-all").addClass("ui-corner-top");
            },
            close: function () {
                $(this).removeClass("ui-corner-top").addClass("ui-corner-all");
            }
        });
    }

I added two properties; DateTime and Maker and then using search: which is fired before the autocomplete fires source: I was able to get the data I needed from the row that I was on. This provided me a nice way to keep all my searching and extra data items all in one place.

The .parent().parent() and so on is because I have multi-line tables to display my data in the gridview and I need to traverse up the tree and then find the text box or label I'm looking for and change the background color of the row with the changed data. I am not proficient at finding items with jQuery yet thus the parent.parent... thing.

1

With regards to the most voted answer, I think there is a much simpler syntax by just appending the extra request value into the source url.

This:

$("#city_id").autocomplete({
    source: src+"?country_id="+$("#country_id").val().
    min_length: 3,
    delay: 300
});

does the same as:

$("#city_id").autocomplete({
    source: function(request, response) {
        $.ajax({
            url: src,
            dataType: "json",
            data: {
                term : request.term,
                country_id : $("#country_id").val()
            },
            success: function(data) {
                response(data);
            }
        });
    },
    min_length: 3,
    delay: 300
});

given that src is an url string.

mpaf
  • 6,597
  • 6
  • 38
  • 42
  • 1
    @mpag, Though it seems same but there is difference between two. The later one loads the value of country_id from DOM each time search request is sent dynamically. But the your approach builds a static route with static parameter value of country_id. The value of country_id will be set at DOM load with value $("#country_id") and will never change, though element $("#country_id") might change. Basically the original and longer version should be preferred to be used. – Harsh Trivedi Apr 02 '15 at 15:10
  • And that is exactly what happened when I tried both versions. – eaglei22 Dec 11 '15 at 19:37
1

While less than ideal, I've hacked/modified the plugin to get it to work for me.

Simply, I've altered the AJAX jQuery function within the plugin.

Around line 363 you'll see:

        $.ajax({
            // try to leverage ajaxQueue plugin to abort previous requests
            mode: "abort",
            // limit abortion to this input
            port: "autocomplete" + input.name,
            dataType: options.dataType,
            url: options.url,
            data: $.extend({
                q: lastWord(term),
                search_type: $(input).attr('name'), // my mod to pickup multiple fields
                limit: options.max
            }, extraParams),
            success: function(data) {
                var parsed = options.parse && options.parse(data) || parse(data);
                cache.add(term, parsed);
                success(term, parsed);
            }
        });

I'm still looking for an elegant solution to this so feel free to keep suggestions coming.

paperclip
  • 2,280
  • 6
  • 28
  • 39
0

Try with

$( "#ricerca" ).autocomplete({
                source: "response.php?param=param",
                minLength: 2
});
Pranav Singh
  • 17,079
  • 30
  • 77
  • 104
0

I am not sure why it is not working.

But you can first check/debug for value of $(this).attr('name').

Also one more thing as here explained [in options tab], you can check with Firebug to see ajax post request(for url and it's data) which will help you to resolve the problem.

Krunal
  • 3,443
  • 3
  • 23
  • 27
0

I understand that its been answered already. but I hope this will help someone in future and saves so much time and pain.

(you can replace 'CRM.$' with '$' or 'jQuery' depending on your jQuery version)

complete code is below: This one I did for a textbox to make it Autocomplete in CiviCRM. Hope it helps someone

CRM.$( 'input[id^=custom_78]' ).autocomplete({
            autoFill: true,
            select: function (event, ui) {
                    var label = ui.item.label;
                    var value = ui.item.value;
                    // Update subject field to add book year and book product
                    var book_year_value = CRM.$('select[id^=custom_77]  option:selected').text().replace('Book Year ','');
                    //book_year_value.replace('Book Year ','');
                    var subject_value = book_year_value + '/' + ui.item.label;
                    CRM.$('#subject').val(subject_value);
                    CRM.$( 'input[name=product_select_id]' ).val(ui.item.value);
                    CRM.$('input[id^=custom_78]').val(ui.item.label);
                    return false;
            },
            source: function(request, response) {
                CRM.$.ajax({
                    url: productUrl,
                        data: {
                                        'subCategory' : cj('select[id^=custom_77]').val(),
                                        's': request.term,
                                    },
                    beforeSend: function( xhr ) {
                        xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
                    },

                    success: function(result){
                                result = jQuery.parseJSON( result);
                                //console.log(result);
                                response(CRM.$.map(result, function (val,key) {
                                                         //console.log(key);
                                                         //console.log(val);
                                                         return {
                                                                 label: val,
                                                                 value: key
                                                         };
                                                 }));
                    }
                })
                .done(function( data ) {
                    if ( console && console.log ) {
                     // console.log( "Sample of dataas:", data.slice( 0, 100 ) );
                    }
                });
            }
  });

PHP code on how I'm returning data to this jquery ajax call in autocomplete:

/**
 * This class contains all product related functions that are called using AJAX (jQuery)
 */
class CRM_Civicrmactivitiesproductlink_Page_AJAX {
  static function getProductList() {
        $name   = CRM_Utils_Array::value( 's', $_GET );
    $name   = CRM_Utils_Type::escape( $name, 'String' );
    $limit  = '10';

        $strSearch = "description LIKE '%$name%'";

        $subCategory   = CRM_Utils_Array::value( 'subCategory', $_GET );
    $subCategory   = CRM_Utils_Type::escape( $subCategory, 'String' );

        if (!empty($subCategory))
        {
                $strSearch .= " AND sub_category = ".$subCategory;
        }

        $query = "SELECT id , description as data FROM abc_books WHERE $strSearch";
        $resultArray = array();
        $dao = CRM_Core_DAO::executeQuery( $query );
        while ( $dao->fetch( ) ) {
            $resultArray[$dao->id] = $dao->data;//creating the array to send id as key and data as value
        }
        echo json_encode($resultArray);
    CRM_Utils_System::civiExit();
  }
}
Developer
  • 3,857
  • 4
  • 37
  • 47
0

use a .each first, then you can use $(this) and set whatever you need into a variable. the resulting variable can be used in the autocomplete

$(".autosuggest").each(function (index, object) {
    var autosuggestType = $(this).attr("autoSuggestType");
    $(this).autocomplete("url",
            {                    
                extraParams: {
                    autoSuggestType: autosuggestType
                },
MichaelD
  • 8,377
  • 10
  • 42
  • 47
0

I had the same problem, but oddly enough, only with the minified version of the autocomplete plugin. When I used the non-minified version, it works. I haven't looked at the minified version yet to see what the difference might be.

kinakuta
  • 9,029
  • 1
  • 39
  • 48