jqueryui автозаполнение, как передать массив ключевых слов для поиска для каждого объекта? - PullRequest
0 голосов
/ 26 января 2012

Я пытаюсь использовать автозаполнение jQueryUI для реализации функции быстрого поиска по сайту для различных страниц функциональности на моем сайте.Поэтому, когда они ищут слово «создать», оно вызывает опции «Создать пользователя» и «Создать организацию».Когда они ищут «create u», будет отображаться только опция «Создать пользователя».Это только некоторые из ссылок.Но, как вы можете видеть, каждая страница будет иметь несколько различных ключевых слов / синонимов, которые все будут указывать на одну и ту же страницу.

В основном я хочу такую ​​структуру:

var links = [   
{
    keywords: ['create', 'add', 'make', 'insert', 'user'],
    label: "Create user",
    desc: "Create a user in the system",
    url: 'http://mysite.com/user/create/'
},
{
    keywords: ['create', 'add', 'make', 'insert', 'organisation'],
    label: "Create organisation",
    desc: "Create an organisation in the system",
    url: 'http://mysite.com/organisation/create/'
}];

Так как онипри его наборе следует искать массив ссылок, а затем искать в массивах ключевых слов, ища частичное совпадение текста на основе того, что они ввели. Если он найдет его, он покажет эту запись в автозаполнении.Но если второе или третье поисковое слово не соответствует ни одному из ключевых слов, оно не будет отображаться.

Теперь я слышал, что вы можете сделать это, указав источник в качестве обратного вызова?

Вот мой код (Редактирование: обновлено с помощью рабочего решения):

        var links = [
        {
            keywords: ['create', 'add', 'make', 'insert', 'user'],
            label: "Create user",
            desc: "Create a user in the system",
            url: 'http://mysite.com/user/create/'
        },
        {
            keywords: ['create', 'add', 'make', 'insert', 'organisation'],
            label: "Create organisation",
            desc: "Create an organisation in the system",
            url: 'http://mysite.com/organisation/create/'
        }];

        $("#searchTerms").autocomplete(
        {
            minLength: 2,               
            source: function(request, response)
            {
                var matched = [];

                // Get entered search terms (request.term) from user and search through all links keywords
                for (var k = 0; k < links.length; k++)
                {
                    // If it matches, push the object into a new array
                    if (checkSearchWordsMatchKeywords(request.term, links[k]['keywords']))
                    {
                        matched.push(links[k]);
                    }
                }

                // Display the filtered results
                response(matched);
            },
            focus: function( event, ui )
            {
                $( "#searchTerms" ).val( ui.item.label );
                return false;
            },
            select: function( event, ui )
            {
                // Redirect to the url
                $( "#searchTerms" ).val( ui.item.label );
                window.location.replace(ui.item.url);

                return false;
            }
        })
        .data( "autocomplete" )._renderItem = function( ul, item ) {
            return $( "<li></li>" )
                .data( "item.autocomplete", item )
                .append( '<a href=""><b>' + item.label + '</b><br>' + item.desc + '</a>' )
                .appendTo( ul );
        };


        /**
         * Check that each word in a search string matches at least one keyword in an array
         * E.g. searchWords = 'create use'  and  keywords = ['create', 'add', 'make', 'insert', 'user'] will return true
         */
        function checkSearchWordsMatchKeywords(searchWords, keywords)
        {
            var searchWords = searchWords.toLowerCase();    // Lowercase the search words
            var searchWords = searchWords.split(' ');       // Break up the search into separate words
            var numOfSearchWords = searchWords.length;      // Count number of search words
            var numOfKeywords = keywords.length;            // Count the number of keywords
            var matches = [];                               // Will contain the keywords that matched the search words

            // For each search word look up the keywords array to see if the search word partially matches the keyword
            for (var i = 0; i < numOfSearchWords; i++)
            {
                // For each keyword
                for (var j = 0; j < numOfKeywords; j++)
                {   
                    // Check search word is part of a keyword
                    if (keywords[j].indexOf(searchWords[i]) != -1)
                    {
                        // Found match, store match, then look for next search word
                        matches.push(keywords[j]);
                        break;
                    }
                }
            }

            // Count the number of matches, and if it equals the number of search words then the search words match the keywords
            if (matches.length == numOfSearchWords)
            {
                return true;
            }

            return false;
        }
    });

Хорошо, так что функция checkSearchWordsMatchKeywords в конце определенно работает, потому что я ее протестировал.Что не работает, так это то, что я не знаю, что я должен вернуть из функции поиска jQueryUI:

Любая помощь, пожалуйста?

1 Ответ

1 голос
/ 26 января 2012

Я работаю над этой проблемой на работе. Чтобы исправить это, мы создали собственную функцию поиска. Для поиска в keywords, даже если они находятся в реальной строке, которую вы хотите отобразить.

$( "#searchTerms" ).autocomplete({
   search: function(event, ui) {  
      // Add your super search function here
   }
});
...