- はじめに
- テンプレート
- デフォルトの ファイル インプット
- カスタム・ファイル・インプット
- bs-custom-file-input を使う
- ラベルの変更
- 取消ボタン
- 取消イベントのマルチブラウザ化
- まとめ
はじめに
Bootstrap の Forms コンポーネントは、デフォルトだと file input だけ統一感がなく残念な感じです。
custom-file-input
を使って以下のような file input を作る手順を見ていきます。
なお、ここでは Bootstrap 4 を使います。
テンプレート
以下のような html を出発点とします。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <style> .container { margin: 50px; } </style> </head> <body> <div class="container"> </div> </body> </html>
<div class="container">
の中にフォームを作成していきましょう。
デフォルトの ファイル インプット
最初にデフォルトの file input を見てみましょう。
デフォルトの file input は form-control-file
クラスを使います。
以下のフォームを定義します。
<form> <div class="form-group"> <label for="inputText">Input text</label> <input type="text" class="form-control" id="inputText" placeholder="Input text"> </div> <div class="form-group"> <label for="inputFile">File input</label> <input type="file" class="form-control-file" id="inputFile"> </div> <hr/> <button type="submit" class="btn btn-primary">Submit</button> </form>
ブラウザ標準のファイル選択が使われるだけで、以下のようになります。
カスタム・ファイル・インプット
Bootstrap 4 では、custom-file
が用意されているので、これを使ってみましょう。
custom-file
の中に custom-file-input
と、custom-file-label
を定義します。
<div class="form-group"> <label for="inputFile">File input</label> <div class="custom-file"> <input type="file" class="custom-file-input" id="inputFile"> <label class="custom-file-label" for="inputFile">Choose file</label> </div> </div>
以下のようになります。
bs-custom-file-input を使う
custom-file
で見た目は変わりましたが、このままではファイル選択してもファイル名が表示されません。
input 要素の onchange イベントでラベル名を変えてあげないといけないのですが、以下のスクリプトを導入することで簡単に対応できます。
GitHub - Johann-S/bs-custom-file-input: A little plugin for Bootstrap 4 custom file input
今回は CDN から取得します。</body>
タグの直前に以下のコードを追加します。
<script src="https://cdn.jsdelivr.net/npm/bs-custom-file-input/dist/bs-custom-file-input.js"></script> <script> bsCustomFileInput.init(); </script> </body> </html>
bsCustomFileInput.init()
を呼んで初期化することで、フォームの reset
と、input の change
イベントにリスナが追加され、ファイル選択で選択したファイルが表示されるようになります。
ラベルの変更
Browse というラベルは data-browse
で変更できます(SCSS でカスタマイズすることももちろんできます)。
bs-custom-file-input を使えば、ファイルのドロップにも対応しているので、ラベル値も合わせて変更しましょう。
<div class="form-group"> <label for="inputFile">File input</label> <div class="custom-file"> <input type="file" class="custom-file-input" id="inputFile"> <label class="custom-file-label" for="inputFile" data-browse="参照">ファイルを選択(ここにドロップすることもできます)</label> </div> </div>
以下のようになりました。
取消ボタン
ファイル選択を取り消すための 取消ボタンも付けましょう。
form-group
で括って、input-group-append
で取消ボタンを追加します。
<div class="form-group"> <label for="inputFile">File input</label> <div class="input-group"> <div class="custom-file"> <input type="file" class="custom-file-input" id="inputFile"> <label class="custom-file-label" for="inputFile" data-browse="参照">ファイルを選択(ここにドロップすることもできます)</label> </div> <div class="input-group-append"> <button type="button" class="btn btn-outline-secondary input-group-text" id="inputFileReset">取消</button> </div> </div> </div>
取消ボタンのクリック時の処理は以下のようにします。
<script> bsCustomFileInput.init(); document.getElementById('inputFileReset').addEventListener('click', function() { var elem = document.getElementById('inputFile'); elem.value = ''; elem.dispatchEvent(new Event('change')); }); </script>
取消ボタン押下で file input の value を空にしています。
これだけだとファイル名のラベルが残ってしまうため、change
イベントを発行して bs-custom-file-input にファイル名を更新してもらいます。
取消イベントのマルチブラウザ化
先ほどの例では、file input の value を空に設定していましたが、IE などの古いブラウザでは動きません。
基本的には、file input の value 値の書き換えはセキュリティ上の制約で行うことができません。 ただし、空値への更新は大抵のブラウザで可能です( IE11 以前や Opera は不可)。
form の reset を行えば空にすることはできますが、その他のフォーム要素の値がすべてクリアされてしまうため、良くあるワークアラウンドが、要素を clone する方法で、以下のようになります。
<script> bsCustomFileInput.init(); document.getElementById('inputFileReset').addEventListener('click', function() { bsCustomFileInput.destroy(); var elem = document.getElementById('inputFile'); elem.value = ''; var clone = elem.cloneNode(false); elem.parentNode.replaceChild(clone, elem); bsCustomFileInput.init(); }); </script>
手元に環境がないため試せていませんが、多分これで大丈夫ではないかと思います。
まとめ
Bootstrap4 で カスタム・ファイル・インプット の使い方を見てきました。
取消ボタン含め、以下のような統一感のある UI ができました。
最後に、ここで使ったファイルの全体像を示して終わりたいと思います。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <style> .container { margin: 50px; } </style> </head> <body> <div class="container"> <form> <div class="form-group"> <label for="inputText">Input text</label> <input type="text" class="form-control" id="inputText" placeholder="Input text"> </div> <div class="form-group"> <label for="inputFile">File input</label> <div class="input-group"> <div class="custom-file"> <input type="file" class="custom-file-input" id="inputFile"> <label class="custom-file-label" for="inputFile" data-browse="参照">ファイルを選択(ここにドロップすることもできます)</label> </div> <div class="input-group-append"> <button type="button" class="btn btn-outline-secondary input-group-text" id="inputFileReset">取消</button> </div> </div> </div> <hr/> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> <script src="https://cdn.jsdelivr.net/npm/bs-custom-file-input/dist/bs-custom-file-input.js"></script> <script> bsCustomFileInput.init(); document.getElementById('inputFileReset').addEventListener('click', function() { bsCustomFileInput.destroy(); var elem = document.getElementById('inputFile'); elem.value = ''; var clone = elem.cloneNode(false); elem.parentNode.replaceChild(clone, elem); bsCustomFileInput.init(); }); </script> </body> </html>
Bootstrap4ファーストガイド―CSS設計の手間を大幅に削減!
- 作者:相澤 裕介
- 出版社/メーカー: カットシステム
- 発売日: 2018/05/01
- メディア: 単行本
- 作者:掌田津耶乃
- 出版社/メーカー: 秀和システム
- 発売日: 2018/02/22
- メディア: 単行本