【datalist】入力もしたいしプルダウン選択もさせたい & プルダウン選択で他項目の自動入力
入力もしたいし、プルダウン選択もさせたい。
って要望があって調べたらdatalist使うのがベストかな、
という結論になったので使い方をメモ。
あと、datalistを選択して他項目に自動で入力させる方法もついでにメモ。
目次
- やりたかったこと
-
- inputタグみたいに入力させたい、かつ、プルダウンで選択させたい
- datalistとは
- カスタムデータ属性とは
- datalistの使い方(サンプルコード)
-
- プルダウン選択で、他の項目に自動入力させたい
- プルダウン選択で他項目の自動入力(サンプルコード)
- まとめ
やりたかったこと
- inputタグみたいに入力させたい、かつ、プルダウンで選択させたい
- プルダウン選択で、他の項目に自動入力させたい
2は、changeイベントで発火させれば簡単にできたんですが、
1やろうとしてちょっと悩みました。
手っ取り早く知りたい人用に、CodePen載せときます。
1. inputタグみたいに入力させたい、かつ、プルダウンで選択させたい
datalistとは
datalistで実現させるので軽く説明。
datalist要素は、HTML5から新たに追加された要素です。
フォームの入力欄などで入力候補となるデータリストを定義します。
あらかじめサジェストを登録しておくようなイメージです。
カスタムデータ属性とは
value値の設定とJavaScriptでの値の取得に使用するので軽く説明。
カスタムデータ属性(data-*)は、HTML5から新たに追加された要素です。
「data-」の後に1文字以上の文字列(任意)を設定することで、
各HTMLの要素に対し独自の値を設定することができます。
datalistの使い方(サンプルコード)
datalistは、inputタグの下にdatalistタグを配置して使用します。
inputのlistと、datalistのidを同じにすることで紐付けます。
<div>
<label for="fruit">お好きな果物を選んでください:</label>
<input id="fruit-input1" value="" list="fruit-select1" name="fruit" />
<datalist id="fruit-select1" class="fruit-select">
<option value=""></option>
<option value="りんご" data-id="data1-id1"></option>
<option value="バナナ" data-id="data1-id2"></option>
<option value="オレンジ" data-id="data1-id3"></option>
<option value="ぶどう" data-id="data1-id4"></option>
<option value="スイカ" data-id="data1-id5"></option>
</datalist>
<input
id="fruit-input-hidden1" type="hidden" name="fruit-Hidden" value="" />
<label for="price">価格:</label>
<input id="price1" value="" name="price" />
</div>
この場合は、「fruit-select1」で紐づけてます。
見た目的には、datalistに設定されたoption項目がサジェスト的な感じで出ます。
ここでは、data-id(カスタムデータ属性)作ってますが、datalist使いたいだけなら不要です。
datalistは、value値が表示される値になるので
selectタグのように裏で持たせたいvalue値は自前でセットしないといけないです。
今回は、changeイベントでhidden項目にセットすることで
selectタグのような使い方ができるようにしてます。
/****************************************************************
* @summary change event
****************************************************************/
$(function() {
$(document).on('change', 'input[name^="fruit"]', function() {
// 一番近いdivタグを取得
let targetDiv = $(this).closest("div");
let id = null;
// datalistのdata-id属性の値の取得 ★手入力だとundifined
id = targetDiv.find(".fruit-select option[value='" + $(this).val() + "']").data('id');
// hidden項目にセット
targetHidden = targetDiv.find('input[name^="fruit-Hidden"]');
targetHidden.val(id);
// 価格表示
targetVal = targetHidden.val();
setFruit(targetDiv, targetVal);
});
});
何個も同じような要素が並んでいた場合を考慮して、
closestで一番近いdivタグを指定して、そこから要素を特定するようにしてます。
optionタグに、data-*(カスタムデータ属性)を使って
value値にセットしたい一意の値を設定しておき、
その値をhidden項目にセットしてます。
2. プルダウン選択で、他の項目に自動入力させたい
プルダウン選択で他項目の自動入力(サンプルコード)
datalistに設定された項目が選択されたときは、
changeイベントで他の項目に自動入力させます。
<div>
<label for="fruit">お好きな果物を選んでください:</label>
<input id="fruit-input1" value="" list="fruit-select1" name="fruit" />
<datalist id="fruit-select1" class="fruit-select">
<option value=""></option>
<option value="りんご" data-id="data1-id1"></option>
<option value="バナナ" data-id="data1-id2"></option>
<option value="オレンジ" data-id="data1-id3"></option>
<option value="ぶどう" data-id="data1-id4"></option>
<option value="スイカ" data-id="data1-id5"></option>
</datalist>
<input
id="fruit-input-hidden1" type="hidden" name="fruit-Hidden" value="" />
<label for="price">価格:</label>
<input id="price1" value="" name="price" />
</div>
/****************************************************************
* @summary change event
****************************************************************/
$(function() {
$(document).on('change', 'input[name^="fruit"]', function() {
// 一番近いdivタグを取得
let targetDiv = $(this).closest("div");
let id = null;
// datalistのdata-id属性の値の取得 ★手入力だとundifined
id = targetDiv.find(".fruit-select option[value='" + $(this).val() + "']").data('id');
// hidden項目にセット
targetHidden = targetDiv.find('input[name^="fruit-Hidden"]');
targetHidden.val(id);
// 価格表示 ★ここで自動入力させている
targetVal = targetHidden.val();
setFruit(targetDiv, targetVal);
});
});
/****************************************************************
* @summary 価格表示
****************************************************************/
function setFruit(targetDiv, targetVal) {
let price = 0;
// data1-id1の[data1-]を削除する
targetVal = targetVal.slice(6);
switch (targetVal) {
case 'id1':
price = 100;
break;
case 'id2':
price = 200;
break;
case 'id3':
price = 300;
break;
case 'id4':
price = 400;
break;
case 'id5':
price = 500;
break;
}
// 価格設定されていない場合は何も表示しない
let priceVal = price != 0 ? price + '円' : '';
// 価格を表示する
targetDiv.find('input[name^="price"]').val(priceVal);
}
data-idに指定した値を取得して、その値によって書き込む値を判定して、
書き込みさせたい要素にセットしてます。
まとめ
本当は入力もさせるようなデータの持ち方って良くないと思うけど、
要望だから、、、仕方なく、、、。
でもdatalistの存在知らなかったので、良いじゃん〜って思いました。
入力チェックとか楽になったのかはまだ不明だけど、見た目はスッキリしました。
工夫すれば他にもいろいろ活用できそうな気がします。
サンプルコード:
Discussion