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.

Community
  • 1
  • 1
luchomolina
  • 1,202
  • 2
  • 13
  • 24

1 Answers1

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' });
Community
  • 1
  • 1
Alfabravo
  • 7,493
  • 6
  • 46
  • 82
  • 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. – luchomolina Jan 17 '13 at 22:10
  • 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. – luchomolina Jan 17 '13 at 22:41
  • 2
    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](http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) for more information. – Andrew Whitaker Jan 17 '13 at 23:07
  • Yes, @AndrewWhitaker, that's it. The last question is: can this be done in a cleaner way? – Alfabravo Jan 17 '13 at 23:09
  • 1
    How about: `ui.content.splice(0, ui.content.length, { 'label': 'test3', 'value': 'test3' });` – Andrew Whitaker Jan 17 '13 at 23:14
  • 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. – pixshatterer Jan 18 '13 at 14:36
  • @Alfabravo 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. – pixshatterer Jan 18 '13 at 14:38
  • @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. – Andrew Whitaker Jan 18 '13 at 14:42