jQuery UI autocomplete select event not working with mouse click
Asked Answered
T

10

24

I have a list of links, and I have this search box #reportname. When the user types in the search box, autocomplete will show the text of the links in a list.

<div class="inline">
<div class="span-10">
<label for="reportname">Report Name</label>
<input type="text" name="reportname" id="reportname" />
</div>
<div class="span-10 last">
<button type="button" id="reportfind">Select</button>
</div>
</div>

The user can then use the keyboard arrow to select one of the text, and when he press ENTER, browser will go to the address of the link. So far so good.

<script type="text/javascript">
    $(document).ready(function () {
        $("#reportname").autocomplete({
            source: $.map($("a.large"), function (a) { return a.text }),
            select: function () { $("#reportfind").click() }
        })
        $("#reportfind").click(function () {
            var reportname = $("#reportname")[0].value
            var thelinks = $('a.large:contains("' + reportname + '")').filter(
                function (i) { return (this.text === reportname) })
            window.location = thelinks[0].href
        })
    });
</script>

The issue is when the user types, autocomplete shows a list, and then the user use the mouse to click one of the result. With keyboard navigation, the content of the search box is changed, but if the user clicks one of the options, the search box is not modified and the select event is immediately triggered.

How can I make the script work with keyboard selection and mouse selection? How can I differentiate between select events that are triggered by keyboard with the ones triggered by mouse?

Truthfunction answered 6/9, 2011 at 6:8 Comment(0)
T
18

Thanks to @William Niu and firebug, I found that the select event parameter 'ui' contains the complete selected value: ui.item.value. So instead of depending on jquery UI to change the text of the textbox, which didn't happen if the user clicks with mouse, I just pick up the selected value from 'ui':

$("#reportname").autocomplete({
    select: function (event, ui) {
        var reportname = ui.item.value
        var thelinks = $('a.large:contains("' + reportname + '")').filter(
            function (i) { return (this.text === reportname) })
        window.location = thelinks[0].href
    };
})
Truthfunction answered 6/9, 2011 at 9:57 Comment(1)
To readers of this question: Check the answer of William Niu, is really awesome and powerful.Howie
F
19

To your 2nd question: "How can I differentiate between select events that are triggered by keyboard with the ones triggered by mouse?"

The event object in the jQuery UI events would include a .originalEvent, the original event it wrapped. It could have been wrapped multiple times though, such as in the case of Autocomplete widget. So, you need to trace up the tree to get the original event object, then you can check for the event type:

$("#reportname").autocomplete({
    select: function(event, ui) {
        var origEvent = event;
        while (origEvent.originalEvent !== undefined)
            origEvent = origEvent.originalEvent;
        if (origEvent.type == 'keydown')
            $("#reportfind").click();
    },
    ...
});
Fixative answered 6/9, 2011 at 8:35 Comment(1)
Thanks! Your answer led me to check event parameters, especially "ui". It turned out I can use ui.item.value to get the selected item!Truthfunction
T
18

Thanks to @William Niu and firebug, I found that the select event parameter 'ui' contains the complete selected value: ui.item.value. So instead of depending on jquery UI to change the text of the textbox, which didn't happen if the user clicks with mouse, I just pick up the selected value from 'ui':

$("#reportname").autocomplete({
    select: function (event, ui) {
        var reportname = ui.item.value
        var thelinks = $('a.large:contains("' + reportname + '")').filter(
            function (i) { return (this.text === reportname) })
        window.location = thelinks[0].href
    };
})
Truthfunction answered 6/9, 2011 at 9:57 Comment(1)
To readers of this question: Check the answer of William Niu, is really awesome and powerful.Howie
G
5

I tested it in all version of IE (inlcuding 9) and always ended up with an empty input-control after I selected the item using the mouse. This caused some headaches. I even went down to the source code of jQuery UI to see what happens there but didn’t find any hints either.

We can do this by setting a timeout, which internally queues an event in the javascript-engine of IE. Because it is guaranteed, that this timeout-event will be queued after the focus event (this has already been triggered before by IE itself).

select: function (event, ui) {
    var label = ui.item.label;
    var value = ui.item.value;
    $this = $(this);
    setTimeout(function () {
        $('#txtBoxRole').val(value);
    }, 1);
},
Georgetown answered 25/2, 2013 at 7:12 Comment(0)
T
2

Had the same issue / problem.

Jquery: 1.11.1 UI: 1.11.0

Question: Do you use bassistance jquery validte plugin simultanously?

If positive: update this to a newest version or just disable it for tests.

I updated from 1.5.5 to 1.13.0

Helped for me. Good luck!

Tertullian answered 17/7, 2014 at 8:24 Comment(0)
G
2

I recently encountered the exact same problem (autocomplete items not clickable, keyboard events working).

Turned out that in my case the answer was not at all JS related. The autocomplete UI was not clickable simply because it was lacking an appropriate value for the z-index CSS property.

.ui-autocomplete {
    z-index: 99999; /* adjust this value */
}

That did the trick.

Guano answered 23/9, 2016 at 14:24 Comment(1)
This worked for me to put the clicked item in the textbox. I did not need to differentiate between select events that are triggered by keyboard versus by mouse.Persecution
H
1

This may be a bit farshot, but I had a similar situation where selecting an autocomplete value left the input field empty. The answer was to ignore the "change" events (as those were handled by default) and replace them with binds to "autocompletechange" events. The "change" event gets triggered before the value from autocomplete is in the field => the field had "empty" value when handling the normal "change" event.

// ignore the "change" event for the field
var item = $("#"+id); // JQuery for getting the element
item.bind("autocompletechange", function(event, ui) { [call your handler function here] }
Hexagram answered 16/8, 2012 at 7:53 Comment(0)
O
0

I was facing a similar problem. I wanted to submit the form when the user clicked on an option. But the form got submitted even before the value of the input could be set. Hence on the server side the controller got a null value.

I solved it using a modified version of William Niu's answer.

Check this post - https://mcmap.net/q/582501/-jqueryui-autocomplete-39-select-39-does-not-work-on-mouse-click-but-works-on-key-events

Ornelas answered 5/11, 2013 at 4:18 Comment(0)
S
0

I had the same issue, mouse click was not selecting the item which was clicked.My code was supposed to make an ajax call to fetch the data as per the selection item from autocomplete source.

Previous code: mouse click not working.

 select: function(event, ui) {
          event.preventDefault();
          for(i= 0; i< customer.length; i++)
          if(document.getElementById('inputBox').value == customer[i].name)
          {

          $.ajax({
          call
          })

Changed code :mouse click working

select: function(event, ui) {
          // event.preventDefault();
          for(i= 0; i< customer.length; i++)
          // if(document.getElementById('inputBox').value == customer[i].fields.name)
          if(ui.item.value == customer[i].name)
          {
          $.ajax({
          call
          })
Suffumigate answered 23/8, 2016 at 6:48 Comment(0)
D
0

After inspecting the code in the developer tools console, I noticed there were two list items added. I removed the pairing <li></li> from my response code and oh yeah, the links worked

enter image description here

I also added this function as the click event:

 $("#main-search").result(function ()
    {
        $("#main-search").val("redirecting...."), window.location.href = $("#main-search").attr("href").match(/page=([0-9]+)/)[1];
    })

This works and you can test it here: Search for the term dress -->

Dendrochronology answered 28/3, 2020 at 8:6 Comment(0)
P
0

I had the same issue. use close event of the autocomplete

  • close: function(event, ui) { //your logic here });
Pomace answered 13/7, 2023 at 18:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.