[Autocomplete] かな入力で名前(漢字)を絞り込むセレクトボックス
入力した「ひらがな」を元に名前(漢字)の一覧を絞り込むセレクトボックスが必要になったのですが、なかなか用途に見合うサジェストプラグインがなかったのでjQuery UIのカスタムコンボボックスを改良して作ってみました。
サンプル
jQuery, jQuery Uiのライブラリとともに「autocomplete.kana.js」を読み込むんでください。
option要素に設定したdata-kana属性の値で絞り込みを行うコンボボックスを表示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
<!doctype html> <html lang="jp"> <head> <meta charset="utf-8"> <title>jQuery UI Autocomplete かな絞り込み</title> <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" /> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script> <script src="autocomplete.kana.js"></script> <style> body { font-family: 'Lucida Grande','Hiragino Kaku Gotdic ProN', Meiryo, sans-serif; font-size: 62.5%; } .custom-combobox { position: relative; display: inline-block; } .custom-combobox-toggle { position: absolute; top: 0; bottom: 0; margin-left: -1px; padding: 0; /* support: IE7 */ *height: 1.7em; *top: 0.1em; } .custom-combobox-input { margin: 0; padding: 0.3em; } </style> <script> $(function() { //コンボボックス設定 $( "#combobox" ).combobox(); //セレクト要素の表示・非表示 $( "#toggle" ).click(function() { $( "#combobox" ).toggle(); }); }); </script> </head> <body> <form action="test.php" method="post"> <div class="ui-widget"> <label>名前を選択してください: </label> <select name="name" id="combobox"> <option value="" selected>選択してください</option> <option value="清水" data-kana="しみず">清水</option> <option value="田中" data-kana="たなか">田中</option> <option value="鈴木" data-kana="すずき">鈴木</option> <option value="志村" data-kana="しむら">志村</option> <option value="佐藤" data-kana="さとう">佐藤</option> </select> </div> <input type="submit" value="送信"> </form> <hr> <button id="toggle">selectを表示</button> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
(function( $ ) { $.widget( "custom.combobox", { _create: function() { this.wrapper = $( "<span>" ) .addClass( "custom-combobox" ) .insertAfter( this.element ); this.element.hide(); this._createAutocomplete(); this._createShowAllButton(); }, _createAutocomplete: function() { var selected = this.element.children( ":selected" ), value = selected.val() ? selected.text() : ""; this.input = $( "<input>" ) .appendTo( this.wrapper ) .val( value ) .attr( "title", "" ) .addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" ) .autocomplete({ delay: 0, minLength: 0, source: $.proxy( this, "_source" ) }) .tooltip({ tooltipClass: "ui-state-highlight" }) .keypress(function(e) { //enterキーでのsubmitを抑制 var c = e.which ? e.which : e.keyCode; if (c == 13) { e.preventDefault(); } }); this._on( this.input, { autocompleteselect: function( event, ui ) { ui.item.option.selected = true; this._trigger( "select", event, { item: ui.item.option }); }, autocompletechange: "_removeIfInvalid" }); }, _createShowAllButton: function() { var input = this.input, wasOpen = false; $( "<a>" ) .attr( "tabIndex", -1 ) .attr( "title", "Show All Items" ) .tooltip() .appendTo( this.wrapper ) .button({ icons: { primary: "ui-icon-triangle-1-s" }, text: false }) .removeClass( "ui-corner-all" ) .addClass( "custom-combobox-toggle ui-corner-right" ) .mousedown(function() { wasOpen = input.autocomplete( "widget" ).is( ":visible" ); }) .click(function() { input.focus(); // 一覧が表示されているときは非表示に if ( wasOpen ) { return; } // 全ての値を表示。検索文字として空文字を渡す input.autocomplete( "search", "" ); }); }, _source: function( request, response ) { var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex(request.term), "i" ); //前方一致 response( this.element.children( "option" ).map(function() { var kana = $( this ).data('kana'); //かな名を取得 var text = $( this ).text(); var value = $( this ).val(); if ( this.value && ( !request.term || matcher.test(kana) ) ) //入力文字とかな名のマッチ return { label: text, //一覧表示時の候補ラベル名 value: value, //値(submitで渡す値) option: this }; }) ); }, _removeIfInvalid: function( event, ui ) { // 何も選択されていないときは離脱 if ( ui.item ) { return; } //一致を検索 var value = this.input.val(), valueLowerCase = value.toLowerCase(), valid = false; this.element.children( "option" ).each(function() { //大文字小文字チェック。日本語だと意味がない。かな=カナチェックに変えても良いかも if ( $( this ).text().toLowerCase() === valueLowerCase ) { this.selected = valid = true; return false; } }); // 見つけたら離脱 if ( valid ) { return; } // 見つからなかった時の処理 (無効な値を削除) this.input .val( "" ) .attr( "title", "「" + value + "」に一致する値は見つかりませんでした" ) .tooltip( "open" ); this.element.val( "" ); this._delay(function() { this.input.tooltip( "close" ).attr( "title", "" ); }, 2500 ); this.input.data( "ui-autocomplete" ).term = ""; }, _destroy: function() { this.wrapper.remove(); this.element.show(); } }); })( jQuery ); |