John Aho
John Aho

Reputation: 31

Formatting jQuery Autocomplete to extend past browser/window edge like drop downs do

I'm trying to get auto complete to extend past the browsers bottom edge like drop downs do.

An example of what I'm talking about is here: http://jsfiddle.net/3gre9q1f/5/ (updated to remove html tags in css per Twisty)

var aTags = [  "ActionScript",
  "AppleScript" ...... ];
 $( "#tags" ).autocomplete({
        source: aTags
    });

This is a naive example of invoking the auto complete but demonstrates the behavior.

The use case for this is that I have modal windows that the auto complete currently extends past the bottom of the window like the jsfiddle example does and makes it hard to select/see the auto complete options.

Drop Down extending past browser bottom frame

Edit: I do have ajax data that I'm working with to populate the auto complete and I am limiting the return results.

Upvotes: 0

Views: 274

Answers (1)

John Aho
John Aho

Reputation: 31

The answer turned out to be to use a HTML5 Datalist instead of a jQuery autocomplete. Datalists render natively and pop out past browser windows. In my particular case it was a pop-up modal window where auto-complete was getting cut off.

Here's an example of DataList behavior that works like I want http://jsfiddle.net/3gre9q1f/7/


The big downside is that this approach doesn't currently work for Safari or the Native IOS browsers and the implementation is a bit clunky. You have to adjust the width of the datalist as well as sticking the value of the option in a javascript dictionary for future lookup because some browsers search against the option text and other browsers search against the option values thus breaking autocomplete.


So what I did was add a couple global variables:

var searchResultsDictionary = {};
var maxListLength = 200;

Then created an empty datalist in my form/page

<input type="text" list="searchList" id="search" placeholder="Search" required />
<datalist id="searchList" style="width:auto; position:relative;"   ></datalist>  

Then I populated it with an ajax call tied to input change on the text box

    $("#search").on('input propertychange paste', function () {

    var searchval = $("#search").val();
    if (searchval != null && searchval.length > 1) { 
        LoadsearchResults(searchval); 
    }

});
function LoadsearchResults(searchFor) {
    var url = "this.website.some.made.up";

    $.ajax({
        url: url,
        data:
            {
                values: searchFor
            },
        dataType: 'json',

        success: function (data) {
                $("#searchList").empty();
                 var charwidth = 5.6;

            $.map(data, function (item) {

                // Add the <option> element to the <datalist>.

                    var innerOption = item.FirstElement + ' 1st ' + item.SecondElement + ' - 2nd# ';
                    var option = "<option data-value='" + item.SearchItemID + "'>" + innerOption + "</option>";
                    $("#searchList").append(option);
                    resultsDict[innerOption] = item.SearchItemID;
                    if (innerOption.length * charwidth > maxListLength) { maxListLength = innerOption.length * charwidth; }


            });

            if (maxListLength > 495) { maxListLength = 495; }
            $("#search").css("width", (maxListLength + 5));
            $("#search").focus();
            $("#search").css("width", (maxListLength + 5));

        },

        error: function (xhr, textStatus, errorThrown) {

            alert('Error: ' + xhr.responseText);
        }
    });
    }

Then in the save/create/next step function I compared the text box value against the dictionary to come up with the ID of the item to do work against.

           var searchId = ""; // search item to create
            var labelLookfor = $("#search").val();
            searchId = searchResultsDictionary[labelLookfor];  

            if (searchId != null && searchId.length > 0) {
                //Here's where the Save/Next step would be called

            }else{
                alert("Search Lookup Not Found");               
            }

Upvotes: 1

Related Questions