问题
I'm trying to implement jQuery.autocomplete which I use to enter tags (much like here on SO). However, I don't want to show tags that I have already in my list. If I have added foo
already I don't want it to show up as a suggestion. The list of tags are fetched from my server. However, I have some issues with altering the ui.content
object.
I use the response method found here:
response: (event, ui)->
# Fetch already added tags
current = $('input#photo_tag_list').val().split(',')
# Filter out already added tags from result
ui.content = ui.content.filter (el) -> $.inArray(el.label, current) == -1
However, the above doesn't work. It still shows all tags. If I inspect ui.content I can see that it looks correct... Is the above async or something?!
The weird thing is that if I do:
ui.content.push({label: "Foo", value:"Bar"})
Foo
shows up in the autocomplete list. But if I do this:
ui.content = []
It still shows everything returned. I would expect an empty list.
Why would this be? How do I modify the result list correctly?
Update Got it to work based on Andrew Whitaker's solution.
回答1:
This is happening because of the way JavaScript passes parameters. ui.content
is a copy of a reference to an array. You cannot modify that reference and expect the results to be visible outside of the function. This is better explained here.
For a simplified example, check this out:
function modify(item) {
item.arr = [];
}
var obj = {
text: 'hi',
arr: [1,2,3,4]
};
modify(obj);
console.log(obj);
Fiddle: http://jsfiddle.net/9swwA/1/
The log statement will show that obj.arr
is still [1, 2, 3, 4]
. You essentially have the same problem.
So to get around this you can use splice
to remove the items from the array. Unfortunately you're going to have to add a bit more code:
i = ui.content.length - 1
while i >= 0
currentItem = ui.content[i]
index = $.inArray(currentItem, current)
ui.content.splice i, 1 if index is -1
i--
回答2:
Ok, I got it based on Andrew Whitaker's answer.
Coffescript:
response: (event, ui)->
current = $('input#photo_tag_list').val().split(',')
for el, i in ui.content by -1
if $.inArray(el.label, current) != -1
ui.content.splice(i, 1)
Works great!
来源:https://stackoverflow.com/questions/18275712/filter-response-in-jquery-autocomplete