Bonjour à vous

Voila je rencontre un petit problème avec mon code, j'essaye de faire un champ d'autocomplétion avec la librairie typeahead.js et depuis quelques heures je rencontre des difficultés, c'est à s'arracher les cheveux.

Ce que je fais

Je travaille sous laravel et voici mon code, assez simple pour l'occasion, j'ai carrément décidé de tester dans un fichier vierge au cas où il y aurait des conflits js

@section('content')

    {!! BootForm::horizontal() !!}
    <div id="remote">
        <input type="text" name="link" class="typeahead">
    </div>
    {!! BootForm::close() !!}

@stop

@section('css')
    <link rel="stylesheet" href="{{ asset('css/bootstrap-tagsinput.css') }}">
    <link rel="stylesheet" href="{{ asset('css/dropzone.css') }}">
@stop

@section('js')

    <script type="text/javascript" src="{{ asset('js/typeahead.js') }}"></script>
    <script type="text/javascript" src="{{ asset('js/bloodhound.min.js') }}"></script>

    <script type="text/javascript">
        var articles = new Bloodhound({
            //identify: function(obj) { return obj.id; },
            queryTokenizer: Bloodhound.tokenizers.obj.whitespace('title'),
            datumTokenizer: Bloodhound.tokenizers.whitespace,
            prefetch: {
                url: '{{ route('articles.json') }}',
                cache: false,
            }
        });
        //articles.initialize();

        // passing in `null` for the `options` arguments will result in the default
        // options being used
        $('#remote .typeahead').typeahead(null, {
            name: 'articles',
            source: articles,
            display: 'title',
        });

        console.log(articles.get([3, 6]));
    </script>

@stop

J'aimerais donc avoir une autocomplétion avec les articles déjà existants, mais le script ne retourne rien... Pourtant les données JSON sont belles et biens récupérées et viennent remplir la librairie Bloodhound. C'est au niveau du typeahead que ça ne marche pas, je ne sais pourquoi :/

Je précise tout de même que ça marche avec des exemples simples, comme un tableau basique : ["title","test","exemple"]

Là où je bloque c'est que j'aimerais récupérer des données complémentaires comme l'id de l'article et son slug. Mon controller qui retourne le résultat :

// getLatest dans le repository :
public function getLatest($orderBy = 'created_at', $fields = '*', $paginate = null)
    {
        return $this->getAll($orderBy, 'DESC', $fields, $paginate);
    }

// controller
$articles = $this->articleRepository->getLatest('created_at', ['id', 'title', 'slug']);
        return $articles->toArray();

Si quelqu'un a une idée ou une piste je suis preneur =)

1 réponse


Alexandre #lbac
Auteur
Réponse acceptée

J'ai finalement résolu mon soucis, pour ceux que ça intéresse :
J'en ai aussi profité pour utiliser la méthode remote pour éviter de charger tout le contenu à la fois.

var articles = new Bloodhound({
            datumTokenizer: function (result) {
                return Bloodhound.tokenizers.whitespace(result.title);
            },
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            /*
            prefetch: {
                url: '{{ route('articles.json') }}',
                cache: false,
                filter: function(articlesArray) {
                    return $.map(articlesArray, function(article) {
                        return {
                            title: article.title,
                            slug: article.slug,
                            category: article.category.slug
                        };
                    });
                }
            },
            */
            remote: {
                url: '{{ route('admin.articles.search') }}' + '?link=%QUERY',
                filter: function(searchArticles) {
                    return $.map(searchArticles, function(article) {
                        return {
                            title: article.title,
                            slug: article.slug,
                            category: article.category.slug
                        };
                    });
                },
                wildcard: "%QUERY"
            },
        });
        articles.initialize();

        var linkInput = $('input[name="link"]');
        linkInput.typeahead({
            hint: false,
            highlight: true,
            minLength: 4,
        },
        {
            name: 'articles',
            source: articles.ttAdapter(),
            displayKey: 'title',
        });

        var linkToInsert = '';
        linkInput.bind('typeahead:select', function(ev, link) {
            linkToInsert = link;
        });