jQuery UI Autocomplete Widget: modifying response data in "response" event doesn't have any effect
Asked Answered
C

1

9

From the JQuery UI docs:

(The response event is) triggered after a search completes, before the menu is shown. Useful for local manipulation of suggestion data.

And

(The ui.content argument) contains the response data and can be modified to change the results that will be shown.

Hoewever, if I modify ui.content on the response event it doesn't affect the results shown in the dropdown, instead my code is just ignored. Here's my (test) code:

$('input.autocomplete').autocomplete({
    source: new Array({label: 'test1', value: 'test1'}, {label: 'test2', value: 'test2'}),
    response: function( event, ui ) {
        ui = {content: new Array({label: 'test3', value: 'test3'}, {label: 'test4', value: 'test4'})};
    }
});

In theory, if the term is "t", it should display test3 and test4 as my autocomplete options, but it doesn't. I get test1 and test2.

What am I missing?

I'm using version 1.9.2 in case you want to point me to this thread.

Costive answered 17/1, 2013 at 21:35 Comment(0)
C
11

What if you try to set the source for your search using source attribute, instead of intercepting the response? Look at this fiddle.

It basically does it this way:

$("input.johndoe").autocomplete({
        source: [
            "test1",
            "test2",
            "test3"
            ...
            ],
        ...

P.S. It comes from this question: Detecting no results on jQuery UI autocomplete

Edit 1: Well. If you set a console.log at some point in the response event (like in this example), it will tell you that ui.content has two elements, even if the search returns no results. So, it looks like the problem is sending the updated ui in the callback. Still looking...

Edit 2: Got it in a way. Look at this updated jsfiddle. It clears the content array and sets the new one. Still guessing why it does not get empty after something like ui.content = []; and it kinda annoys me. Maybe it's related to the fact it is inside a JQuery object (even if it's defined as an pure and simple Array.

The fiddle

I just use push method to put the desired key-value combinations in the array.

// Set default content
      for ( var i = 0; i = ui.content.length; i++ ) {
        ui.content.pop();
      }
      ui.content.push({ label: "pepe", value: "pepe" });

And it works, as it always shows the desired list of suggestions. Hope it helps and perhaps someone else finds a more elegant solution.

Edit3: Just to add the solution that @andrewWhithaker suggests, as it works as well (haven't checked if it takes longer in case the original content array is too big).

The fiddle with splice

It changes the whole pop and push on the previous approach with one splice.

 ui.content.splice(0, ui.content.length, { 'label': 'test3', 'value': 'test3' });
Countermark answered 17/1, 2013 at 21:56 Comment(8)
Hey thanks for answering. The code on the question is merely a test code dumbed down to make it easy to understand. The actual logic is way more complex and uses remote data.Costive
Response to your edit #1: yes, ui.content contains the data indeed, and (according to the documentation) changing it should modify the results, it just doesn't.Costive
This has to do with the way objects are passed to methods in JavaScript. You can't replace ui.content, but you can modify it. Check out this answer for more information.Voyage
Yes, @AndrewWhitaker, that's it. The last question is: can this be done in a cleaner way?Countermark
How about: ui.content.splice(0, ui.content.length, { 'label': 'test3', 'value': 'test3' });Voyage
Hey @AndrewWhitaker how about ui.content.length = 0 before pushing the new contents? this should empty the array before pushing new contents and it is, imo, a little bit more readable.Holcman
@Countermark using [] to doesn't empty an array, it just creates a new instance to replace the current one... and since replacing ui.content doesn't work, that shouldn't work either.Holcman
@pixshatterer: Good idea; I'm personally not a huge fan of splice either (it's a weird little method). Your solution would work just as well.Voyage

© 2022 - 2024 — McMap. All rights reserved.