web-dev-qa-db-fra.com

Déclencher par programme l’affichage des résultats typeahead.js

J'utilise le fichier typeahead.js de Twitter (/ https://github.com/Twitter/typeahead.js/ ) sur un champ de saisie pré-rempli à partir d'une chaîne de requête. Après avoir chargé la page, je souhaiterais déclencher par programme l’affichage des résultats de frappe sans que l’utilisateur ait à taper quoi que ce soit dans le champ de formulaire.

Hors de la boîte, typeahead.js est uniquement déclenché si l'utilisateur tape manuellement quelque chose dans le champ de saisie et je ne trouve aucune méthode dans typeahead.js que je pourrais appeler pour déclencher l'affichage des résultats.

Tous les indicateurs seraient grandement appréciés.

Merci!

34
zıəs uɐɟəʇs

L'entrée de déclenchement semble le faire.

$(".typeahead").eq(0).val("Uni").trigger("input");

Testé ceci sur la page example .

44
epascarello

Selon mes tests (voir fiddle ), la méthode focus () est nécessaire pour afficher la liste déroulante. Alors:

theVal = $('.typeahead').val();
$(".typeahead").typeahead('val', '')
$(".typeahead").focus().typeahead('val',theVal).focus();
  • Sur la ligne 1, nous affectons la valeur actuelle de l’entrée Typeahead à la variable theVal;
  • Sur la ligne 2, nous réinitialisons simplement la valeur calculée de typeahead; et
  • Sur la ligne 3, nous rétablissons la valeur d'origine et le focus, ce qui a pour effet d'afficher le menu déroulant de suggestion comme si l'utilisateur avait saisi quelque chose.

J'avais réellement besoin de cela pour inciter fortement les utilisateurs à choisir parmi les suggestions Bloodhound provenant d'un appel d'API de géocodage afin de m'assurer que les coordonnées avaient été obtenues par le client avant de soumettre un formulaire.

12
Sam_Butler
$(".typeahead").typeahead('lookup').focus();

déclencheurs avec valeur d'entrée existante. vous pouvez changer la valeur à l'avance bien sûr

10
webenformasyon

A partir de Typeahead v0.10.1, modifier la valeur du typeahead déclenchera une autre requête et ouvrira la liste déroulante:

var val = $(".typeahead").typeahead('val');
$(".typeahead").typeahead('val', '');
$(".typeahead").typeahead('val', val);
6
Megan

Pour ceux qui découvrent ce problème avec la police de frappe de Twitter après la version 0.11.1, voici comment je l'ai résolu en une ligne:

$(".typeahead-input").typeahead('val', "cookie")
                     .trigger("input")
                     .typeahead('open');
6
kcent

J'ai utilisé le type de démarrage de Twitter et je me suis dit que la liste de suggestions s'ouvrirait au premier plan. Les réponses ne fonctionnaient pas très bien pour moi, alors j'ai écrit cette directive simple (nécessite jquery):

.directive('typeaheadFocusTrigger', function() {
        return {
            limit: 'A',
            link: function(scope, element, attrs) {
                $(element).on('focus', function(e) {
                    var $target = $(e.target);
                    var origVal = $target.eq(0).val();
                    $target.eq(0).val('').trigger('input')
                    .eq(0).val(origVal).trigger('input');
                });
            }
        }
    });

Maintenant, ajoutez simplement cet attribut, et cela déclenchera le focus

<input typeahead-focus-trigger typeahead="">
5
Vall3y

Utilisation de: Typeahead v0.10.5

N'utilisez pas:$('.typeahead').typeahead('open');

Cela ne fonctionne pas actuellement. Source: https://github.com/Twitter/typeahead.js/issues/798 . En guise de solution temporaire, utilisez un événement keydown jQuery personnalisé (après avoir instancié la tête de frappe):

var ttInstance = $('.typeahead').typeahead( config ); // Create Typeahead
ttInstance.typeahead('val', 'pancakes'); // Set an initial value

var evt = jQuery.Event('keydown');
evt.keyCode = evt.which = 40;
ttInstance.trigger(evt); // Opens the dropdown
5
Matt Jensen

En regardant à travers le code source, il semble stocker un objet TypeaheadView dans les données d'élément sous la clé typeahead. Cet objet TypeaheadView a une méthode interne, _showDropdown, qui est liée en interne à l'événement focus (et à quelques autres).

Je ne recommanderais pas cela, mais vous devriez pouvoir appeler cette méthode interne manuellement:

$('#yourTypeaheadElement').data('typeahead')._showDropdown();

Sinon, avez-vous simplement essayé de focaliser votre élément typeahead lors du chargement de la page (après l'avoir initialisé en tant qu'élément typeahead, bien sûr):

// after page loads and yourTypeaheadElement is initialized as a typeahead
$('#yourTypeaheadElement').focus();
3
jbabey

Aucun de ceux-ci ne fonctionnera à moins que vous mettiez délibérément "typeahead" dans les classes de votre balise input. Si vous ne sentez pas le besoin de le faire (ce n'est pas nécessaire pour que cela fonctionne), vous feriez mieux d'utiliser la classe écrite sur la balise input par typeahead.js. C'est ".tt-input". Voici l'exemple que j'ai cité dans Sam_Butler, recodé pour la nouvelle classe CSS. Cela fonctionne pour moi dans la plus récente typeahead 0.10.5:

var theVal = jQuery('.tt-input').val();
jQuery(".tt-input").typeahead('val', 're')
jQuery(".tt-input").focus().typeahead('val',theVal).focus();
3
Artif3x

Voici une version simplifiée du travail de @ Sam_Butler: http://jsfiddle.net/rimian/hrnf9

<button type="button" id="button">Crick</button>
<input type="text" id="text" class="typeahead">

Javascript:

$('#button').click(function() {
  $("#text").focus().typeahead('val', 'London');
});

// instantiate the bloodhound suggestion engine
var locations = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    remote: {
        url: 'https://maps.googleapis.com/maps/api/geocode/json?address=%QUERY&components=country:GB&sensor=false&region=uk', //add key
        filter: function (locations) {
            return $.map(locations.results, function (location) {
                return {
                    value: location.formatted_address
                };
            });
        }
    }
});

locations.initialize();

$('#text').typeahead(null, {
    name: 'value',
    displayKey: 'value',
    source: locations.ttAdapter()
});
2
Rimian

J'ai jeté un coup d'oeil au code source et trouvé cette manière non documentée:

var $myinput = $('#myinput');
$myinput.data('typeahead')._showDropdown()
2
Iftah

Cela devrait fonctionner avec le "vieux" plug-in bootstrap typeahead:

$(".typeahead").eq(0).trigger("keyup");

Malheureusement, je n'ai pas testé avec IE ... Je ne connais pas le nouveau plugin typeahead ...

2
MarcoL

Cela a fonctionné pour moi. 

$( document ).ready(function() {
    $('#the-basics .typeahead').typeahead({
      hint: false,
      highlight: true,
      minLength: 0
    },
    {
      name: 'states',
      displayKey: 'value',
      source: substringMatcher(states)
    });

    //set a value to input to trigger opening
    $(".typeahead").eq(0).val("a").trigger("input");
    //remove value for end user
    $(".typeahead").eq(0).val("");

});

Voir par exemple: http://joshuamaynard.com/sandbox/autocomplete

1
Joshua Maynard

Soyez prudent avec ça!

Pour ceux qui envisagent de déclencher le comportement d'une typeahead manuellement (sur un clic de bouton, par exemple), je vous recommande fortement de ne pas le faire.

Je suis venu pour cette solution et j'ai perdu presque une journée entière, ce qui a bien fonctionné (dans mon cas, il s'agissait d'un clic de bouton).

Pour ceux qui veulent vraiment passer par cette voie sombre, je partage avec vous mon code laid qui le fait fonctionner:

//Removes default features of typeahead
//This means that typeahead will not work like an "autocomplete", it only will be trigged when the user Click in #btnSearch button!
var txt = $("#typeahead");
//Save input events in variables (we'll need them)
eventInput = $._data(txt[0], "events").input[0];
eventBlur = $._data(txt[0], "events").blur[1];
//Remove input events
txt.unbind("blur");
txt.unbind("input");

//Set click event that triggers typeahead features manually
$("#btnSearch").click(function () {
    //Clears the cache of engine for it call ajax again, without it when the term was already searched the ajax is not called!
    engine.clearRemoteCache();

    txt.focus(); //When we click in a button, the focus from input is lost, so we set it again to not lose the behaviors of keyboard keys (up, down, tab, etc)
    txt.bind("input", eventInput); //Bind the event that we had saved
    txt.trigger("input"); //Trigger input (like the answer from @epascarello)
    txt.unbind("input"); //Removes it again 
});

//Set event on parent of the suggestion's div, this makes the sugestion div close when user click outside it
$("body").click(function () {            
    if (eventBlur != undefined) {
        if ($(".tt-dropdown-menu:visible").length > 0) {
            eventBlur.handler(); //This event closes the suggestion menu
        }
    }
});

Une autre chose que j'ai faite a été de changer le code de l'événement "_checkInputValue" sur typeahead.js. Je change ceci:

areEquivalent = areQueriesEquivalent(inputValue, this.query);

pour ça:

areEquivalent = false;//areQueriesEquivalent(inputValue, this.query);

Je l'ai défini sur false car typeahead n'envoie pas deux requêtes identiques au serveur . Cela se produit lorsque l'utilisateur clique deux fois sur le bouton de recherche (je veux dire, lorsqu'il recherche plusieurs fois le même texte qu'il a déjà recherché). Quoi qu'il en soit, si vous utilisez des données locales, vous n'aurez pas besoin de le faire.

1
fabriciorissetto

Les autres réponses ont été utiles mais n'ont pas résolu mon problème. Cette solution n'implique pas la personnalisation du code angular-ui elle-même. Elle permet uniquement de déclencher l'extraction du résultat par la tête de frappe sur un clic de bouton explicite.

Pour ce faire, j'ai dû superposer un champ de texte au-dessus d'un autre champ de texte (désactivé) qui correspond au champ de texte. Personne ne saura que l'autre est présent mais il doit être présent pour que angular-ui lance le menu au bon endroit. Vous ne pouvez pas en faire un champ caché car il ne pourra pas afficher le menu au bon endroit.

La directive ci-dessous surveillera les variables typeaheadText et typeaheadTrigger pour renseigner le champ désactivé lorsque le bouton le déclenchera (en définissant le déclencheur sur true). La directive a une portée isolée, elle ne dépend donc d’aucun autre élément que celui transmis.

directive('typeaheadTrigger', function() {
  return {
    require: ["ngModel"],
    scope: {
      typeaheadText: '=',
      triggerFlag: '='
    },
    link: function(scope, element, attr, ctrls) {
      scope.$watch('triggerFlag', function(value) {
        if (scope.triggerFlag) {
          ctrls[0].$setViewValue(scope.typeaheadText);
          scope.typeaheadText = '';
          scope.triggerFlag = false;
        }
      });
    }
  };
})

Le contrôleur définit quelques éléments pour cela: les variables de déclencheur et de portée du texte dans un objet. Cela montre comment procéder. Dans l'idéal, vous devriez envelopper tout cela dans une autre directive afin qu'elle puisse être utilisée dans votre application tout en cachant les détails.

Voici le code: http://plnkr.co/edit/UYjz6F5ydkMQznkZAlfx?p=preview

1
Matt Byrne

J'ai utilisé cela pour déclencher manuellement une sélection, lorsqu'un élément était dans le jeu de données tt. Il était logique d'ajouter ceci.

$("#mytypeahead").keyup(function (e) {
                var charCode = (typeof e.which === "number") ? e.which : e.keyCode;
                if (charCode == 13) {
                    if ($(this).parent().find(".tt-dataset").children().length == 1) {
                        //This is how we are submitting a single selection on enter key
                        $(this).parent().find(".tt-dataset").children(0).addClass("tt-cursor");
                        var kde = jQuery.Event("keydown");
                        kde.which = 13;
                        $(this).trigger(kde);                           
                    }    
                }                    
            });
0
DeadlyChambers

J'ai essayé toutes les méthodes ici mais cela ne fonctionnait pas, seulement en utilisant

$(".typeahead").val('hi').trigger('keyup');
$(".typeahead").val('hi').trigger('keydown');

Le code ci-dessus cela a fonctionné pour moi. Je ne sais pas ce qui est arrivé exactement, mais l’utilisation de l’un ou de l’autre ne fonctionnait qu’en utilisant les deux.

0
weBBer