高速でフル機能のスタンドアロン オートコンプリート ライブラリ
?ハイライト?
typeahead-standalone.jsのライブ デモを含む詳細なドキュメントはこちらでご覧ください。
基本的な例のプレビュー:
# you can install typeahead with npm
$ npm install --save typeahead-standalone
# Alternatively you can use Yarn
$ yarn add typeahead-standalone
次に、ライブラリをアプリ/ページに含めます。
モジュールとしては、
// using ES6 modules
import typeahead from 'typeahead-standalone' ; // imports library (js)
import 'typeahead-standalone/dist/basic.css' ; // imports basic styles (css)
// using CommonJS modules
const typeahead = require ( 'typeahead-standalone' ) ;
require ( 'typeahead-standalone/dist/basic.css' ) ;
ブラウザのコンテキストでは、
<!-- Include the basic styles & the library -->
< link rel =" stylesheet " href =" ./node_modules/typeahead-standalone/dist/basic.css " />
< script src =" ./node_modules/typeahead-standalone/dist/typeahead-standalone.umd.js " > </ script >
<!-- Alternatively, you can use a CDN. For example, use jsdelivr to get the latest version -->
< link rel =" stylesheet " href =" https://cdn.jsdelivr.net/npm/typeahead-standalone/dist/basic.css " />
< script src =" https://cdn.jsdelivr.net/npm/typeahead-standalone " > </ script >
<!-- or use unpkg.com to get a specific version -->
< link rel =" stylesheet " href =" https://unpkg.com/[email protected]/dist/basic.css " />
< script src =" https://unpkg.com/[email protected]/dist/typeahead-standalone.umd.js " > </ script >
このライブラリはwindow.typeahead
でグローバル オブジェクトとして利用可能になります。
Typeahead には、それ自体をアタッチするinput
要素と、候補を表示するData source
(ローカル/リモート) が必要です。
これは非常に基本的な例です (高度な例についてはデモを参照してください)
<!-- include the library -->
< script src =" ... " async > </ script >
<!-- Html markup -->
< input type =" search " id =" searchInput " autocomplete =" off " placeholder =" Search... " >
// local Data
const colors = [ 'Grey' , 'Brown' , 'Black' , 'Blue' ] ;
// input element to attach to
const inputElement = document . getElementById ( "searchInput" ) ;
typeahead ( {
input : inputElement ,
source : {
local : colors ,
// prefetch: {...}
// remote: {...}
}
} ) ;
次の構成オプションをtypeahead-standalone
に渡すことができます。
パラメータ | 説明 | デフォルト |
---|---|---|
input | DOM 入力要素はこのパラメータとともに渡す必要があり、typeahead 自体がこのフィールドに付加されます。 | - (必須) |
source | これは、提案が計算されるデータのソースです。ソースはローカルにすることも、プリフェッチすることも、リモート エンドポイントから取得することもできます。詳細 | - (必須) |
minLength | 画面に候補が表示されるときの最小の長さを指定します。 | 1 |
limit | 表示する候補の最大数を指定します。 | 5 |
highlight | クエリで一致した文字が候補リストで強調表示されます。スタイルを容易にするためにクラスtt-highlight が追加されました | true |
autoSelect | true に設定すると、最初に表示される候補が事前に選択されます | false |
hint | 最初に一致した候補と等しくなるように入力プレースホルダーを更新します。スタイル設定を容易にするクラスtt-hint が追加されました | true |
diacritics | 言語の発音記号のサポートされた検索を有効/無効にするフラグ (つまり、アクセント付き文字をアクセント付きでない文字に変換することによる検索) | undefined |
classNames: Object | classNames オブジェクトを使用して、DOM に挿入されるすべての HTML 要素のカスタム クラスを設定できます。詳細 | undefined |
templates | ヘッダー、フッター、提案、グループ、および notFound 状態のテンプレートを含むオブジェクト。詳細については、「テンプレート」セクションを参照してください。 | undefined |
preventSubmit | input 要素が form 要素内で使用されている場合、このフラグにより、ENTER キーが押されたときのデフォルトの送信アクションを防止できます。 | false |
onSubmit(event, selectedItem?) | フォーム要素の外側で先行入力を使用する場合、このハンドラーを使用して入力値を処理/送信できます。 ENTER キーを押すとトリガーされます。最初のパラメータはキーボード イベントで、2 番目のパラメータは選択された項目、または項目が選択されていない場合は未定義です。 | undefined |
display(selectedItem, event?) => string | このコールバックは、ユーザーが候補から項目を選択すると実行されます。現在の提案/項目はパラメータとして渡され、入力の値として設定された文字列を返す必要があります。 2 番目のオプションのパラメーターevent 、ユーザー インタラクションの追跡や分析に使用できるマウス/キーボード イベントです。デフォルトはnull です。 | 選択した項目の文字列表現を返します。 |
tokenizer?: (words: string) => string[] | トークナイザー関数は、検索クエリと検索データを指定された文字で分割するために使用されます。この機能は、ハイフネーションされた単語や特定の接頭辞/接尾辞を持つ単語を検索したい場合に便利です。 | 単語はスペース文字 (改行、タブ、スペース) で区切られます。 |
listScrollOptions?: ScrollIntoViewOptions | スクロールが必要な多数の候補リストのスクロール動作を細かく制御できます。これらのオプションは、 scrollIntoView() 関数に渡されます。 MDN 参照 | { block: "nearest", inline: "nearest", behaviour: "auto"} |
retainFocus | このパラメータは、候補のリストが開いているときに「Tab」キーを押すときのフォーカスを制御するのに役立ちます。有効にすると、強調表示されたオプションが選択され、フォーカスが検索入力に戻ります。無効な場合、「Tab」を押すと強調表示されたオプションが選択され、フォーム内の次のフォーカス可能な項目にフォーカスが移動します。 | true |
hooks | フック構成オプションは、先行入力のライフサイクルの特定の瞬間に任意のコードを実行するのに役立ちます。詳細 | 未定義 |
これは、提案が提供されるデータのソースです。これは、ソース オブジェクトの予期される形式です。
source: {
local: [],
remote: {
url: 'https://remoteapi.com/%QUERY', // OR "url: (inputQuery: string) => `https://remoteapi.com/${inputQuery}`"
wildcard: '%QUERY',
debounce: 300 // optional, default => 200ms
requestOptions: {} // optional, default => undefined
},
prefetch: {
url: 'https://remoteapi.com/load-suggestions', // OR `url: () => string`
when: 'onFocus', // optional, default => 'onInit'
done: false, // optional, default => false
process: (items) => void, // optional, default => undefined
requestOptions: {} // optional, default => undefined
},
keys: ['...'], // optional (required when source => Object[])
groupKey: '...', // optional, default => undefined
identity: (item) => string, // optional (determines uniqueness of each suggestion)
transform: function (data) {
// modify source data if needed & return it
return data;
}
}
local
データ ソースは、変数などのローカル ソースからの提案を提供する場合に使用されます。prefetch
データ ソースは、リモート エンドポイントから事前に提案をプリロードする場合に使用されます。提案を返すエンドポイントを指すurl
パラメーターを指定する必要があります。プリフェッチ要求がいつ発生するかを定義するオプションのwhen
パラメーターを指定できます。デフォルトはonInit
で、先行入力が初期化されるとすぐに候補がプリロードされることを意味します。これをonFocus
に設定すると、ユーザーが検索入力ボックスにフォーカスを当てた場合にのみ候補がプリロードされます。 done
フラグはオプションであり、プリフェッチ要求をプログラムで無効にするために使用できます。デフォルト値はfalse
です。これは、データが初めてプリフェッチされるときに自動的にtrue
に設定されます (複数のネットワーク要求を防ぐため)。 done: true
設定すると、プリフェッチ要求は発生しなくなります。これを行うユースケースの例は、 localStorage を使用して提案を保存しているが、 localStorage には以前にすでに提案が保存されているため、データを再度プリフェッチする必要がない場合です。 process(suggestions)
コールバックはオプションです。プリフェッチ要求が発生した後に実行されます。変換された提案をパラメータとして受け取り、例として、受け取った提案を後で使用するためにlocalStorageに保存するために使用できます。remote
データ ソースは、リモート エンドポイントに問い合わせてデータをフェッチする場合に使用されます。remote
データ ソースを使用する場合、 url
とwildcard
オプションを設定する必要があります。 wildcard
リクエストの実行中に検索文字列に置き換えられます。debounce
オプションは、http リクエストの実行を (ミリ秒単位で) 遅延させるために使用されます。これはオプションであり、デフォルトは 200ms です。GET
です。transform()
関数を提供できます。先行入力によって処理される前に応答を変更できます。keys
配列が必要です。最初のキーは、オブジェクトのどのプロパティを候補を表示するためのテキストとして使用するかを識別するために使用されます。たとえば、データ ソースが次のようなものだとします。 /* Example Data source */
[
{ id : 1 , color : "Yellow" , meta : { colorCode : "YW" } } ,
{ id : 2 , color : "Green" , meta : { colorCode : "GN" } , shade : "Greenish" } ,
{ id : 3 , color : "Olive" , meta : { colorCode : "OV" } , shade : "Greenish" } ,
...
]
color
プロパティで定義されたテキストを候補として表示する場合は、キーの最初のキーとしてcolor を含める必要があります。 (つまり、 keys: ["color"]
)。
検索インデックスにさらにプロパティを追加したい場合は、それらのプロパティをkeys
配列でも指定できます。これは例を見ると最もよく理解できます。上に示したものと同じデータ ソースの例を考えてみましょう。色だけではなく、別のプロパティ ( colorCode ) で色を検索したい場合はどうすればよいでしょうか?これを行うには、 keys: ["color", "meta.colorCode"]
を設定するだけです。ここで「 YW 」を検索すると、予想どおり「Yellow」という候補が表示されます。
groupKey: "shade"
を設定すると、候補はプロパティ " shade " によってグループ化されます。この例では、緑とオリーブの色は「 Greenish 」( shade
) グループの下に表示されますが、黄色の色にはグループがありません。 groupKey は、ドット表記を使用したネストされたプロパティへのアクセスもサポートします。 (例 - groupKey: "category.title"
)identity()
関数は、各提案の一意性を判断するために使用されます。パラメータとして提案を受け取り、指定された提案に固有の文字列を返す必要があります。これはオプションのプロパティであり、デフォルトでは最初のキー( keys[0]
に関連付けられた値を返します。ただし、デフォルト値が常に機能するとは限りません。たとえば、次のコードを考えてみましょう。 /* Example Data source of Songs */
[
{ title : "God is Good" , artist : "Don Moen" } ,
{ title : "God is Good" , artist : "Paul Wilbur" } ,
{ title : "God is Good" , artist : "Micheal Smith" } ,
{ title : "El Shaddai" , artist : "Amy Grant" } ,
...
]
キーがkeys: ["title"]
に設定されていると仮定します。デフォルトでは、 identity()
関数は最初のキー(つまり、 title ) を使用して一意性を判断します。したがって、 God
を検索すると、まったく同じtitle
プロパティを持つ曲が 3 曲あるため、候補は 1 つだけ表示されます。異なるアーティストの 3 つの提案をすべて表示するには、一意の文字列を返すようにidentity
プロパティを設定する必要があります。
identity ( item ) = > ` ${ item . title } ${ item . artist } ` ;
データ ソースがオブジェクトの配列である場合は、 identity()
構成オプションを設定して一意の文字列を返すようにすることを強くお勧めします。
さらに詳しく説明するには、実際の例を確認してください。
現在利用可能なフックは 1 つだけです。
updateHits: async (resultSet, loader) => Promise<resultSet>
は、検索結果がユーザーに表示される直前に実行され、検索インデックスによって返された候補をオーバーライドするために使用できます。 (カスタムの並べ替え、フィルタリング、結果の追加または削除に役立ちます。このフックは、必要に応じて新しい結果を取得するための AJAX リクエストを作成できる非同期関数です) // Example usage of "updateHits" hook
typeahead ( {
input : document . querySelector ( ".myInput" ) ,
source : {
local : [ ] ,
// ...
} ,
hooks : {
updateHits : async ( resultSet , loader ) => {
resultSet . hits . push ( { name : "new suggestion" } ) ; // add new suggestion
// resultSet.hits.filter( ... ); // filter the suggestions
// resultSet.hits.sort( ... ); // custom sort the suggestions
// resultSet.count = 5000; // to set the total results found
/*** You can also make an AJAX request to fetch results ***/
// loader(); // display the loader template
// const response = await fetch('https://example.com');
// const text = await response.text();
// resultSet.hits = text && JSON.parse(text);
// loader(false); // hide the loader template
// resultSet.updateSearchIndex = true; // updates search index if necessary. Default `false`
return resultSet ; // you must return the resultSet
} ,
} ,
templates : {
loader : ( ) => { ... } ,
}
} ) ;
いくつかの基本的なスタイルは、先行入力によって提供されます。 UI は完全にユーザー次第で、ピクセル単位でカスタマイズできます。次のクラスを使用してスタイルを追加/オーバーライドできます。
typeahead-standalone
クラスを持つコンテナーにラップされます。tt-input
クラスがあります。tt-hint
クラスがあります。tt-list
クラスのコンテナーにラップされます。 (提案がない場合は、クラスtt-hide
が追加されます)tt-suggestion
クラスがあり、提案が選択されている場合は、さらにtt-selected
クラスがあります。tt-highlight
クラスがあります。親セレクター.typeahead-standalone
ターゲットにすることで、独自のスタイルを追加できます。たとえば、以下に示すように、すべての提案の背景色を更新できます。
/* set background color for each suggestion */
. typeahead-standalone . tt-list . tt-suggestion {
background-color : green;
}
デフォルトのスタイルをオーバーライドするには、構成オプションclassName
を設定し、それをセレクターとして使用します。 className: "my-typeahead"
を設定したとします。その後、候補のホバー/選択時にスタイルをオーバーライドするには、次のように使用できます。
/* override styles */
. typeahead-standalone . my-typeahead . tt-list . tt-suggestion : hover ,
. typeahead-standalone . my-typeahead . tt-list . tt-suggestion . tt-selected {
color : black;
background-color : white;
}
v4.0
以降、JS と CSS が分離され、スタイルをより細かく制御できるようになりました。 CSS 全体は CDN または以下から取得してプロジェクトに直接コピーでき、必要に応じてスタイルを破棄/オーバーライドできます。
/***** basic styles *****/
. typeahead-standalone {
position : relative;
text-align : left;
color : # 000 ;
}
. typeahead-standalone . tt-input {
z-index : 1 ;
background : transparent;
position : relative;
}
. typeahead-standalone . tt-hint {
position : absolute;
left : 0 ;
cursor : default;
user-select : none;
background : # fff ;
color : silver;
z-index : 0 ;
}
. typeahead-standalone . tt-list {
background : # fff ;
z-index : 1000 ;
box-sizing : border-box;
overflow : auto;
border : 1 px solid rgba ( 50 , 50 , 50 , 0.6 );
border-radius : 4 px ;
box-shadow : 0 px 10 px 30 px 0 px rgba ( 0 , 0 , 0 , 0.1 );
position : absolute;
max-height : 70 vh ;
}
. typeahead-standalone . tt-list . tt-hide {
display : none;
}
. typeahead-standalone . tt-list div [ class ^= "tt-" ] {
padding : 0 4 px ;
}
. typeahead-standalone . tt-list . tt-suggestion : hover ,
. typeahead-standalone . tt-list . tt-suggestion . tt-selected {
background : # 55acee ;
cursor : pointer;
}
. typeahead-standalone . tt-list . tt-suggestion . tt-highlight {
font-weight : 900 ;
}
. typeahead-standalone . tt-list . tt-group {
background : # eee ;
}
テンプレートを使用してヘッダー、フッターを追加し、各提案をさらにスタイル設定することもできます。
テンプレートを使用して、リストのレンダリングをカスタマイズできます。それらの使用は完全に任意です。現在、7 つのテンプレートが利用可能です -
templates: {
header : ( resultSet ) => '<h1>List of Countries</h1>' , /* Rendered at the top of the dataset */
footer : ( resultSet ) => '<div>See more</div>' , /* Rendered at the bottom of the dataset */
suggestion : ( item , resultSet ) => { /* Used to render a single suggestion */
return `<div class="custom-suggestion"> ${ item . label } </div>` ;
} ,
group : ( groupName , resultSet ) => { /* Used to render a group */
return `<div class="custom-group"> ${ groupName } </div>` ;
} ,
empty : ( resultSet ) => { /* Rendered when the input query is empty */
return `<div>Search for Colors...</div>` ;
// OR (to display some suggestions by default)
return [ { title : "France" } , { title : "Spain" } ] ;
}
loader : ( ) = > 'Loading...' , /* Rendered while awaiting data from a remote source */
notFound : ( resultSet ) => '<span>Nothing Found</span>' , /* Rendered if no suggestions are available */
}
上で見たように、各テンプレートはコールバックを受け取り、後で HTML として解釈されるstring
を返す必要があります。テンプレートは、以下に示す構造を持つパラメーターresultSet
も受け取ります。
resultSet = {
query : '...' , // the input query
hits : [ ... ] , // found suggestions
count : 0 , // the total suggestions found in the search index
limit : 5 , // the number of suggestions to show
wrapper : DOMElement , // the container DOM element
}
スタイル設定を容易にするために、各テンプレートは対応するクラスを持つdiv
要素でラップされます。つまり
header
=> クラスtt-header
footer
=> クラスtt-footer
suggestion
=> クラスtt-suggestion
group
=> クラスtt-group
loader
=> クラスtt-loader
empty
=> クラスtt-empty
notFound
=> クラスtt-notFound
classNames
構成オプションを使用すると、デフォルトのクラス名を好みに応じて置き換えることができます。
先行入力内で使用されるデフォルトのクラス名は次のとおりです。
const classNames = {
wrapper : 'typeahead-standalone' , /* main container element */
input : 'tt-input' ,
hint : 'tt-hint' ,
highlight : 'tt-highlight' ,
list : 'tt-list' , /* container element for suggestions */
hide : 'tt-hide' ,
show : 'tt-show' ,
selected : 'tt-selected' ,
/* classes used within templates */
header : 'tt-header' ,
footer : 'tt-footer' ,
loader : 'tt-loader' ,
suggestion : 'tt-suggestion' ,
group : 'tt-group' ,
empty : 'tt-empty' ,
notFound : 'tt-notFound' ,
} ;
たとえば、入力要素に別のクラス名を使用したい場合は、次のように typeahead を初期化できます。
typeahead ( {
input : '...' ,
source : '...' ,
classNames : {
input : 'my-custom-input-class' // this class is used instead of tt-input
}
} ) ;
typeahead.reset()
typeahead.addToIndex()
typeahead.destroy()
reset(clearLocalSrc?: boolean)
先行入力インスタンスをユーザー操作前の状態にリセットします。ローカル ソースを介して追加されたアイテムを除くすべてのアイテムが検索インデックスから削除されます。完全にすべての項目を削除するには、関数はtrue
に設定する必要があるオプションのパラメーターを受け入れます。 Reset() は、キャッシュされたリモート要求もクリアします。
const instance = typeahead ( { /* options */ } ) ;
// clear search index except items added via Local source
instance . reset ( ) ;
// clears entire search index
instance . reset ( true ) ;
この API は、一定時間が経過した後にデータを無効にする必要がある場合に役立ちます。
addToIndex()
検索インデックスに項目を追加します。自分でデータを取得して検索インデックスに追加する場合に便利です。これは、ローカル ソースを介して項目を追加するのと似ています。
const instance = typeahead ( { /* options */ } ) ;
instance . reset ( true ) ; // or instance.reset();
instance . addToIndex ( [ 'Blue, Baige , Black' ] ) ;
destroy()
先行入力インスタンスを破棄し、検索インデックスをクリアし、すべてのイベント ハンドラーを削除して、DOM をクリーンアップします。先行入力を無効化したい場合に使用できます。
const instance = typeahead ( { /* options */ } ) ;
instance . destroy ( ) ;
ここでは、遭遇する可能性のあるエラー コードの小さな用語集を示します。
コード | 説明 |
---|---|
e01 | 入力 DOM 要素がありません |
e02 | 提案のソースが欠落しているか間違っています。予想されるソース形式で、ローカル、プリフェッチ、リモートの 3 つのソースのうち少なくとも 1 つを指定する必要があります (参照)。 |
e03 | 紛失したキー |
e04 | プリフェッチ要求が失敗しました |
e05 | リモート要求が失敗しました |
機能や修正に貢献することに興味がありますか?
貢献について詳しくはこちらをお読みください。
変更履歴を参照してください
MIT © DigitalFortress