문제

I have a bunch of hidden divs with a single table inside them. Users need to search for a name (can contain spaces) within the first th cell, and then return the div ID.
I looked into the jQueryUI autocomplete plugin, but having problems getting it to work with multiple values. Plugin docs and demos.
I use "Custom data and display" example as base with a predefined data array, but I'd like to avoid it and simply use selector.

Search box

<label for="search_name">Find name</label>
<input type="text" name="search_name" value="" id="search_name">
<span style="display:none;" id="search_result"></span>

Divs

<div id="name_101284"><table>
  <tr><th colspan="5">John Doe (<a href="http://link">text</a>) - snip</th></tr>
  <tr><th>C1</th><th>C2</th><th>C3</th><th>C4</th><th>C5</th></tr>
  <tr><td>snip
</table></div>

JS

  var nameAC = [
   {label:"John Doe",id:"101284"},
   {label:"Johnny",id:"152345"},
   {label:"Jim Nelson",id:"77344"},
   {label:"Jimmy",id:"87457"},
   {label:"Maria",id:"100934"},
   {label:"Maria Nelson",id:"94734"},
   {label:"Jane Doe",id:"86247"},
   {label:"Janet",id:"106588"}
  ];
  $('#search_name').autocomplete({
    minLength: 1,
    delay: 300,
    source: nameAC,
    focus: function(event, ui) {
      $('#search_name').val(ui.item.label);
      return false;
    },
    select: function(event, ui) {
      $('#search_result').text(ui.item.id);
      $('#search_result').show();
    }
  });

Property "label" is the expected name to contain values to fill the dropdown result UL. Changing it requires overwriting the default _renderItem method, like this

$('#search_name').autocomplete({
 stuff
})
.data("autocomplete")._renderItem = function(ul, item) {
  return $("<li></li>")
  .data("item.autocomplete", item)
  .append("<a>" + item.name + "</a>")
  .appendTo(ul);
};

But it seems flawed.

Can I make a selector (or callback function) to avoid having to make the nameAC array ?

도움이 되었습니까?

해결책

Kim, I think the way you are doing it is pretty solid. If you want to have the source generated by a function, I suggest you make it easier to parse your data, i.e. by putting a span tag around the name in each div.

That being said, here's one way to do it with your data as it is now. It's probably not perfect, thus my suggestion:

function makeArray() {
    var results = [];
    $("div[id^='name_']").each(function() {
        results.push({
            'label': $(this).find('th:first').text().replace(/(.*) \(.*/, '$1'),
            'id': this.id.replace(/name_(\d+)/, '$1')
        });
    });
    return results;
}

Obviously, if your username was something like this: <span class="name">John Doe</span>, then the label would be easier: $(this).find('span.name').text()

You can see a simple version of this in action here: http://jsfiddle.net/ryleyb/MYCbX/

EDIT: I should have mentioned, this is called from the autocomplete like this:

$('#search_name').autocomplete({
    source: makeArray() // <-- note the brackets, function is being **called** 
});
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top