クエリ文字列から事前に入力された入力フィールドで、Twitterのtypeahead.js( https://github.com/Twitter/typeahead.js/ )を使用しています。ページを読み込んだ後、ユーザーがフォームフィールドに何も入力しなくても、プログラムで先行入力結果の表示をトリガーしたいと思います。
箱から出してtypeahead.jsがトリガーされるのは、ユーザーが入力フィールドに手動で何かを入力した場合のみで、結果の表示をトリガーするために呼び出すことができるtypeahead.jsのメソッドが見つかりません。
どんなポインタでも大歓迎です。
ありがとう!
私のテストによると( fiddle を参照)、ドロップダウンを表示するにはfocus()メソッドが必要です。そう:
theVal = $('.typeahead').val();
$(".typeahead").typeahead('val', '')
$(".typeahead").focus().typeahead('val',theVal).focus();
フォームを送信する前にクライアントが座標を取得できるように、ジオコーディングAPI呼び出しからのBloodhound提案からユーザーが選択することを強く推奨するために、実際にこれが必要でした。
$(".typeahead").typeahead('lookup').focus();
入力の既存の値でトリガーします。もちろん、事前に値を変更できます
Typeahead v0.10.1以降、typeaheadの値を変更すると、別のクエリがトリガーされ、ドロップダウンが開きます。
var val = $(".typeahead").typeahead('val');
$(".typeahead").typeahead('val', '');
$(".typeahead").typeahead('val', val);
バージョン0.11.1以降のTwitterの先行入力でこの問題を見つけた人には、次のように1行で解決しました。
$(".typeahead-input").typeahead('val', "cookie")
.trigger("input")
.typeahead('open');
私はTwitter bootstrap typeaheadを使用し、提案リストが開かれることに気をつけました。
.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');
});
}
}
});
この属性を追加するだけで、フォーカス時にトリガーされます
<input typeahead-focus-trigger typeahead="">
使用:Typeahead v0.10.5
使用しないでください:$('.typeahead').typeahead('open');
現在、これは機能しません。ソース: https://github.com/Twitter/typeahead.js/issues/798 。一時的な修正として、カスタムjQueryキーダウンイベントを使用します(入力補完をインスタンス化した後)。
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
ソースコードを見ると、TypeaheadView
オブジェクトがキーtypeahead
の下の要素データに格納されているように見えます。このTypeaheadView
オブジェクトには、内部メソッド_showDropdown
。これは、フォーカスイベント(および他のいくつか)に内部的にバインドされています。
これを行うことはお勧めしませんが、その内部メソッドを手動で呼び出すことができるはずです:
$('#yourTypeaheadElement').data('typeahead')._showDropdown();
別の方法として、ページがロードされるときにtypeahead要素を単純にフォーカスしてみました(もちろん、それをtypeahead要素として初期化した後)。
// after page loads and yourTypeaheadElement is initialized as a typeahead
$('#yourTypeaheadElement').focus();
入力タグのクラスに意図的に「typeahead」を入れない限り、これらは機能しません。これを行う必要がないと感じた場合(動作させる必要はありません)、typeahead.jsによってinputタグに書き込まれたクラスを使用する方が良いでしょう。 「.tt-input」です。これは、新しいCSSクラス用に再コーディングされたSam_Butlerから引用した例です。これは、最新の先行入力0.10.5で機能します。
var theVal = jQuery('.tt-input').val();
jQuery(".tt-input").typeahead('val', 're')
jQuery(".tt-input").focus().typeahead('val',theVal).focus();
@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®ion=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()
});
私はソースコードを見て、この文書化されていない方法を見つけました:
var $myinput = $('#myinput');
$myinput.data('typeahead')._showDropdown()
これは、「古い」bootstrap typeaheadプラグインで動作するはずです:
$(".typeahead").eq(0).trigger("keyup");
IEでテストしていない...残念ながら...新しいtypeaheadプラグインについて知らない...
これは私のために働いた。
$( 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("");
});
例についてはこちらをご覧ください: http://joshuamaynard.com/sandbox/autocomplete
手動で先行入力動作をトリガーすることを考えている人(たとえば、ボタンのクリック)には、これを行わないことを強くお勧めします。
私はこの解決策を求めて来ましたが、ほぼ1日かけて回避策を適切に機能させることができませんでした(私の場合はボタンクリックでした)。
この暗い方法で本当に行きたい人のために、それを機能させる私のいコードをあなたと共有します:
//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
}
}
});
もう1つ行ったのは、typeahead.jsでイベントのコードを変更することです"_ checkInputValue"。これを変更します:
areEquivalent = areQueriesEquivalent(inputValue, this.query);
これに:
areEquivalent = false;//areQueriesEquivalent(inputValue, this.query);
Typeahead 2つの同一のリクエストをサーバーに送信しないでくださいなので、falseに設定します。これは、ユーザーが検索ボタンを2回クリックすると発生します(つまり、ユーザーが既に検索した同じテキストを複数回検索する場合)。とにかく、ローカルデータを使用している場合、これを行う必要はありません。
他の回答は役に立ちましたが、私の問題は解決しませんでした。このソリューションは、角度UIコード自体のカスタマイズを必要とせず、明示的なボタンクリックで結果を取得するために先行入力をトリガーするだけの目的に役立ちます。
これを行うには、テキストフィールドを、先行入力のある実際のフィールドである別の(無効な)テキストフィールドの上にオーバーレイする必要がありました。他の人がそこにいることを誰も知りませんが、angular-uiが正しい場所でメニューを起動するためにそこにいる必要があります。メニューを正しい場所に表示できないため、非表示フィールドにすることはできません。
以下のディレクティブは、typeaheadText
変数とtypeaheadTrigger
変数を監視して、ボタンがトリガーするときに無効フィールドに入力します(トリガーをtrueに設定することにより)。ディレクティブのスコープは分離されているため、渡されたもの以外には依存しません。
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;
}
});
}
};
})
コントローラーは、このためにいくつかのことを設定します-オブジェクト内のトリガーとテキストスコープ変数。これはそれを行う方法を示しています-理想的には、詳細全体を隠しながらアプリケーションで使用できるように、この全体を別のディレクティブでラップするのが理想的です。
ここにプランクがあります: http://plnkr.co/edit/UYjz6F5ydkMQznkZAlfx?p=preview
1つのアイテムがtt-datasetにあるときに、これを使用して手動で選択をトリガーしました。これを追加するのは理にかなっています。
$("#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);
}
}
});
私はここですべての方法を試してみましたが、使用するだけでうまくいきませんでした
$(".typeahead").val('hi').trigger('keyup');
$(".typeahead").val('hi').trigger('keydown');
上記のコードは私にとってはうまくいきました。正確に何が起こったのかわからないが、どちらを使用しても、両方を使用するだけでは機能しなかった.