jQuery UI の Autocomplete…

jQuery UI ドキュメントのナビゲーション頼みだと autocomplete に辿り着きにくい気がするんだが気のせいだろうか…。

結構しょーもない話で、multi values のパターンを「猿真似」したらこんなドエラいことになった:

同じ仲間の jQuery UI の Dialog に包んでるのって「そんなに異常?」。あるいは Dialog に包まなくてもこうなるんかいね? まぁ前提とするテーマの css を取り込んでないから、みたいなことだとは思うけれど、せめて z-index くらいはコントロールしてくれんかねぇ? ブラウザの「検証」で解読して、とりあえず最低限のスタイル設定はこんなかしらね:

 1 .ui-autocomplete {
 2    z-index: 999;  /* 最低でもこれは絶対 */
 3    height: 10em;        /* 候補リストがそれなりなら必須。すぐに画面が溢れちゃう。*/
 4    overflow-y: scroll;  /* 同上。*/
 5 
 6    font-size: small;  /* これはあなたのスタイルに合わせてな */
 7 }
 8 .ui-autocomplete li div {
 9    /* この div が「色々」やってるのであまり乱暴なオーバライドはやめた方がいい。
10       hover で hand icon にしたりとかとにかく結構色んなことするみたい。
11       ただ width だけは少し小さめにしないと、スタイルによってはすぐに
12       恐怖の横スクロールバーにご登場願うハメになる。*/
13 
14    /* display: inline; */
15    width: 90%;
16 }

で、スタイルに関しては以上で、なおかつ、「猿真似で期待したことをそのデモはやってなかった」話。このソースコードみてさぁ、「重複アイテムを挿入するのを回避」してると勘違いするのって、「とても正常」だと思うんだけど、同意する人いる? 少なくともワタシは「一般的レベルの阿呆」なので当然誤解した。

なので「そう期待したのなら」期待したとおりのことを実現したくて:

 1 $(function() {
 2     const availableGenres = [
 3         "Action", "Adventure", "Cars", "Comedy", "Dementia",
 4         "Demons", "Drama", "Ecchi", "Fantasy", "Game",
 5         "Harem", "Hentai", "Historical", "Horror", "Josei",
 6         "Kids", "Magic", "Martial Arts", "Mecha", "Military",
 7         "Music", "Mystery", "Parody", "Police", "Psychological",
 8         "Romance", "Samurai", "School", "Sci-Fi", "Seinen",
 9         "Shoujo", "Shoujo Ai", "Shounen", "Shounen Ai", "Slice of Life",
10         "Space", "Sports", "Super Power", "Supernatural", "Thriller",
11         "Vampire", "Yaoi", "Yuri",
12     ];
13     $("#genres")
14         .on("keydown", function(event) {
15             // don't navigate away from the field on tab when selecting an item
16             if (event.keyCode === $.ui.keyCode.TAB &&
17                  $(this).autocomplete("instance").menu.active) {
18                 event.preventDefault();
19             }
20         });
21     var genres_autocomplete_opts = {
22         minLength: 0,
23         source: function(request, response) {
24             // delegate back to autocomplete, but extract the last term
25             var cur_genres = request.term.split(/,\s*/);
26             var rest = [];
27             availableGenres.forEach(function(gnr, _) {
28                 if (!cur_genres.includes(gnr)) {
29                     rest.push(gnr);
30                 }
31             });
32             response($.ui.autocomplete.filter(
33                 rest, cur_genres.pop()));
34         },
35         focus: function() { // prevent value inserted on focus
36             return false;
37         },
38         select: function(event, ui) {
39             var terms = this.value.split(/,\s*/);
40             terms.pop();  // remove the current input
41             terms.push(ui.item.value);  // add the selected item
42             // add placeholder to get the comma-and-space at the end
43             terms.push("");
44             this.value = terms.join(", ");
45             return false;
46         }
47     };
48     $("#genres").autocomplete(genres_autocomplete_opts);
49 });

まぁ小1時間程度で出来ちゃったので、「簡単といえば簡単」ではあるのかしらね。てわけで期待通り:

あとなんか spell check が動いちゃってる。えーっと…autocomplete 入れなくてもなってたっけか? 外してみても効いてる。なんだ autocomplete のせいではないのか。調べたらこれで無効に出来る…:

 1 Genres: <input
 2  class="cynodes-filters"
 3  id="genres"
 4  type="text"
 5  placeholder="comma separated genres"
 6  title="comma separated genres like 'Action, Fantasy'"
 7  value="Action, Fantasy, Seinen"
 8  size=24
 9  spellcheck="false"
10  />

いつからこんなこと出来るようになったんだ、と思うが、まぁ「HTML5 から」なんだろうなぁ、きっと。そもそもこんなこと出来てたんだね。知らんうちに随分進化したもんだよ。



Related Posts