Как использовать Twitters typeahead.js с API Microsoft OData?

Я столкнулся с проблемами при написании веб-приложения для получения данных JSON из нашего приложения CRM.

Я хочу использовать плагин Twitter typeahead.js для удаленного получения информации о клиентах из нашей CRM. заявление. Microsoft предоставляет способ использования данных JSON для связи. Они называют это OData. Однако это не похоже на типичные ответы JSON. Вот почему у меня возникают проблемы с настройкой плагина typeahead.

Когда я отправляю запрос GET на URL-адрес API, я получаю следующий ответ:

{
    "d":{
        "results":[
            {
                "__metadata":{
                    "uri":"http://*****/*****/XRMServices/2011/OrganizationData.svc/AccountSet(guid'de227fde-fb40-dd11-b5d3-001cc46325e5')",
                    "type":"Microsoft.Crm.Sdk.Data.Services.Account"
                },
                "Name":"Some company as",
                "AccountId":"de227fde-fb40-dd11-b5d3-001cc46325e5"
            },
            {
                "__metadata":{
                    "uri":"http://*****/*****/XRMServices/2011/OrganizationData.svc/AccountSet(guid'5dc70a19-e91e-e311-9ad7-005056ac083a')",
                    "type":"Microsoft.Crm.Sdk.Data.Services.Account"
                },
                "Name":"Compnay AS",
                "AccountId":"5dc70a19-e91e-e311-9ad7-005056ac083a"
            }
        ]
    }
}

Итак, вот вопрос: как настроить подключаемый модуль Twitter typeahead для работы с этой структурой данных?

Мне нужно значение Name из ответа JSON при отображении предложений. И я хочу получить связанное значение AccountId при выборе предложения.

Это то, что я получил в своем коде до сих пор:

HTML:

<!DOCTYPE html>
<html lang="no">
    <head>
        <title>Company :: Time Registrering</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" type="text/css" href="css/global.css" />
    </head>
    <body>

        <form action="" method="GET" autocomplete="off">
            <input type="text" name="account" id="account" placeholder="Kunde...">
        </form>

        <script type="text/javascript" src="js/jquery.min.js"></script>
        <script type="text/javascript" src="js/typeahead.js"></script>
        <script type="text/javascript" src="js/global.js"></script>
    </body>
</html>

JavaScript: (js/global.js)

$(document).ready(function () {
    var accounts = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Name'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: "http://*****/*****/xrmservices/2011/OrganizationData.svc/AccountSet?$select=Name,AccountId&$filter=substringof('%QUERY',Name) and StateCode/Value eq 0"
    });

    accounts.initialize();

    $("#account").typeahead({
        hint: true,
        highlight: true,
        minLength: 2
    }, {
        name: 'account',
        displayKey: 'd.results[0].Name',
        source: accounts.ttAdapter()
    });

});

Однако: мой код не работает. Все, что я получаю, это текст с надписью «undefined» под полем ввода. У меня есть подозрение, что моя ссылка datumTokenizer или displayKey неверна. Я не совсем понимаю datumTokinizer. Так что, если кто-то может просветить меня по этому поводу, я был бы благодарен :)


person Alexander Johansen    schedule 22.01.2015    source источник


Ответы (2)


Вы должны использовать фильтр и использовать jQuery.map

HTML

 <input type="text" name="account" id="account" placeholder="Kunde..." />

js

$(document).ready(function () {



    var accounts = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Name'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
        url : "https://gist.githubusercontent.com/anonymous/80a75d841a055ea0e480/raw/4eb8d4f1833d8a15cae1830097c090f5d581bd12/gistfile1.txt",
        filter: function(jsonValue) {

                return $.map(jsonValue.d.results, function (result) {
                return {
                    value: result.Name
                };
            });
        }
    }     


    });

    accounts.initialize();

    $("#account").typeahead({
        hint: false,
        highlight: true,
        minLength: 2
    }, {
        source: accounts.ttAdapter()
    });

});

Скрипка здесь

person Quannt    schedule 22.01.2015
comment
Ну это смешно. Как только я это понял и опубликовал свой ответ: вы сделали то же самое. Все равно спасибо! :) - person Alexander Johansen; 22.01.2015
comment
Рад, что ты сам догадался :D - person Quannt; 22.01.2015

Я нашел решение проблемы. Я заметил, что могу использовать функцию фильтра в объекте Bloodhound и генерировать массив с помощью $.map, чтобы движок Bloodhound мог искать его, как и предполагалось.

Вот как сейчас выглядит мой код JavaScript (HTML не изменился по сравнению с вопросом):

$(document).ready(function () {
    var accounts = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Name'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
            url: "http://****/****/xrmservices/2011/OrganizationData.svc/AccountSet?$select=Name,AccountId&$filter=substringof('%QUERY',Name) and StateCode/Value eq 0",
            filter: function (accounts) {
                return $.map(accounts.d.results, function (account) {
                    return {
                        Name: account.Name,
                        AccountId: account.AccountId
                    };
                });
            }
        }
    });

    accounts.initialize();

    $("#account").typeahead({
        hint: true,
        highlight: true,
        minLength: 2
    }, {
        name: 'account',
        displayKey: 'Name',
        source: accounts.ttAdapter()
    });


    $("#account").on('typeahead:selected', function(dom, selectedItem) {
        console.log(selectedItem.AccountId);
    });
});

Надеюсь, это поможет другим людям делать то же самое, что и я :)

person Alexander Johansen    schedule 22.01.2015