Сопоставление Bloodhound не работает со специальными символами

Я использую typeahead.js с Bloodhound для поиска пользователей с использованием локального источника:

let users = [
  {name: 'John Doe ([email protected])', value: '3421'},
  {name: 'Jane Doe ([email protected])', value: '8100'},
];

Ключ соответствия и отображения — name:

$('input').typeahead(
  {
    minLength: 1,
    highlight: true
  },
  {
    name: 'users',
    displayKey: 'name',
    source: new Bloodhound({
      datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      local: users
    })
  }
);

Он совпадает при поиске по имени пользователя, например. «Джон» или «Джейн». Но нет, если вы ищете по электронной почте, например. «john.doe», «test» или «email.org».

Однако, если скобки удалены, например. 'John Doe [email protected]', то "john.doe" действительно совпадает. Но не "email.org".

Другие специальные символы, такие как <, например. У 'John Doe <[email protected]>' та же проблема.

Почему специальные символы нарушают сопоставление данных и что я могу сделать, чтобы помочь?

Вот рабочая ручка.

У меня может быть дополнительный атрибут:

let users = [
  {name: 'John Doe ([email protected])', value: '3421', match: 'John Doe [email protected]'},
  {name: 'Jane Doe ([email protected])', value: '8100', match: 'Jane Doe [email protected]'},
];

И сопоставить по новому ключу:

datumTokenizer: Bloodhound.tokenizers.obj.whitespace('match')

Или у меня может быть новое свойство email и следующий токенизатор данных:

datumTokenizer: u => Bloodhound.tokenizers.whitespace([u.name + ' ' + u.email])

Но это далеко не идеал. Но как я могу просто сделать так, чтобы ключ name совпадал?


person dabadaba    schedule 22.04.2020    source источник


Ответы (2)


Кажется, вам нужно использовать собственный токенизатор, например.

const customTokenizer = (user) => {
  const tokens = user.name.split(/[\s()]+/);
  console.info('Tokenizer', user, '=>', tokens);
  return tokens;
};

let users = [{
    name: 'John Doe ([email protected])',
    value: '3421'
    // , email: '[email protected]'
  },
  {
    name: 'Jane Doe ([email protected])',
    value: '8100'
    //, email: '[email protected]'
  },
];

$('input').typeahead({
  minLength: 1,
  highlight: true
}, {
  name: 'users',
  displayKey: 'name',
  source: new Bloodhound({
    // datumTokenizer: u => Bloodhound.tokenizers.whitespace([u.name + ' ' + u.email]),
    datumTokenizer: customTokenizer,
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: users
  })
});
.tt-menu {
  background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>

<div id="search">
  <input type="text" placeholder="Search user">
</div>

person Kyr    schedule 22.04.2020

используйте токенизатор nonword как для datumTokenizer, так и для queryTokenizer.

person user1660678    schedule 22.04.2020