简体   繁体   中英

How to implement jQuery UI Autocomplete 'autoFill' and/or 'selectFirst' features?

First, Let me start by saying thatI am aware of other similar questions, like this one here:

How to implement "mustMatch" and "selectFirst" in jQuery UI Autocomplete?

but it doesnt really do what I would expect. I'll explain why below. I am also aware of this simple guide posted by the original developer of the plugin:

http://www.learningjquery.com/2010/06/autocomplete-migration-guide

and I have done many implementations of the former plugin and a few fairly customized implementations of the UI plugin.

Having said that, here is my issue and why the first solution does not work for me. The soruce comes from a DB in the form of JSON objects. I use a custom function to set the options, see below:

source: function (request, response) {
   var sourceData = $.parseJSON(result); //result is an array coming in via ajax
   response($.map(sourceData, function (item) {
      return { label: item.PortName, value: item.PortName, source: item };
      //item has about 12 properties that could be used for other forms.
   }))
}

Then I also have a custom change() event that grabs the source above, and does a few things like store the item itself in the data() object of the element, as well as parse some of the data from the item object to be used in other form fields, etc.

The solution above only sets the value of the input to the first autocomplete option, but it does not replicate the select or change event of the autocomplete. So in reality is not a true selectFirst or autoFill replica.

The change function looks like this:

change: function (event, ui) {
            if (ui.item) {
                $('input:[name="another_form_field"]').val(ui.item.source.PortId);
            }
            else {
                $(this).val('');
                $('input:[name="release_port_id"]').val('');
            }
        }

which is a quick, simple, implementation of the mustMatch feature for now. This will most likely change once I have these 2 features implemented.

Ok, with all that said, any suggestions on how to implement either or both of these features? I have tried attaching a blur event as suggested in the question above, but that wont work.

thanks in advance.

EDIT : This is what I have tried so far. Binding a blur event to the autocomplete element. The commented-out line uses the value of the first element in the dropdown and sets the text of the input. This would work if thats all I would need, but i need to replicate the select event, which means that i need more data (not just the text).

.live('blur', function (e) {
        if ($('.ui-autocomplete li').length > 0) {            
            //$(this).val($(".ui-autocomplete li:visible:first").text());
            $(".ui-autocomplete li:visible:first").click();
        }
        else {
            $(this).val('');
            $('input:[name="release_port_id"]').val('');
        }
    });

The other problem with this solution, is that it actually overrides the change event in the autocomplete and it does not execute as expected. Which is why I included the else section. This is not quite what it will look like, but a proof of concept.

I was going to post a bounty but finally figured it out.

Here is the solution I came up with. After playing around with this, I figured out that the plugin uses .data() to store the option item data. So I was able to get the full object and parse out the data that I needed to fulfill other elements. Then the challenge was to recognize when a selection was valid even if the user didnt click or select an option. For that I check to see if any options match the value, if they do I replicate the select . Otherwise I clear the fields. Then I leveraged the .data() again to store whether the choice was valid or not, and if it was not I was able to clear the fields again. Below is my code.

Comments are welcome.

$('#autocomplete_input').autocomplete({
        source: function (request, response) {
            $.get("/DataHandler.ashx", { Type: "ExpectedType", Query: request.term }, function (result) {
                var sourceData = $.parseJSON(result);
                response($.map(sourceData, function (item) {
                    return { label: item.PortName, value: item.PortName, source: item };
                }))
            });
        },
        minLength: 3,
        change: function (event, ui) {
            if (ui.item) {
                $('#another_element"]').val(ui.item.source.PortId);
            }
            else {
                if (!$(this).data('valid')) {
                    $(this).val('');
                    $('#another_element').val('');                    
                }
            }
            $(this).data('valid', false);
        }
    }).live('blur', function (e) {
        if ($('.ui-autocomplete li:visible').length > 0) {
            item = $($(".ui-autocomplete li:visible:first").data()).attr('item.autocomplete');
            $(this).val(item.label);
            $('#another_element').val(item.source.PortId);
            $(this).data('valid', true);
        }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM