Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
161
Help us understand the problem. What is going on with this article?
@gsk3beta

Bootstrapのファイルをアップロードするボタンを標準デザインのボタンにする

More than 3 years have passed since last update.

bootstrapを使ってファイルをアップロードするフォームをつくるとき、デフォルトのボタンは小さくて、特にスマホでは表示する際に使いにくいと感じます

こちらの投稿Bootstrap File Inputを使った方法が紹介されています。見た目だけでなく、機能も豊富で参考になります。

ただ今回はbootstrap標準デザインのボタンを使う方法を紹介します。

こちらを参考にしました。


標準の<input type="file">

まず標準の<input type="file">の確認です

<input type="file">

Screen Shot 2016-12-04 at 9.09.52 PM.png

これです。


<span class="btn">で囲んでボタンにする

spanタグで囲むことでbootstrap標準デザインのボタンにできます。inputはstyle="display:none"で隠します。

<span class="btn btn-primary">
    Choose File
    <input type="file" style="display:none">
</span>

Screen Shot 2016-12-04 at 9.40.15 PM.png

このようになります。

ただ、これではクリックしてもファイルを選択できません(Google Chromeで試しました)

さらにlabelタグで囲むと選択できるようになります。コードは下記のようになります。

<label>
    <span class="btn btn-primary">
        Choose File
        <input type="file" style="display:none">
    </span>
</label>

ファイル名を表示する

text-inputを使ってファイル名を表示します。下記のコードをみてください。

<div class="input-group">
    <label class="input-group-btn">
        <span class="btn btn-primary">
            Choose File<input type="file" style="display:none">
        </span>
    </label>
    <input type="text" class="form-control" readonly="">
</div>

Screen Shot 2016-12-04 at 10.57.20 PM.png

まだファイルを選んでも何も表示されません。jqueryを使ってファイル名を表示できるようにします

$(document).on('change', ':file', function() {
    var input = $(this),
    numFiles = input.get(0).files ? input.get(0).files.length : 1,
    label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
    input.parent().parent().next(':text').val(label);
});

おまけ:プレビューを表示する

画像を選択した際にプレビュー表示します。こちらを参考にしました

プレビューを表示するためのdivタグを追加します

<div class="imagePreview"></div>
<div class="input-group">
    <label class="input-group-btn">
        <span class="btn btn-primary">
            Choose File<input type="file" style="display:none" class="uploadFile">
        </span>
    </label>
    <input type="text" class="form-control" readonly="">
</div>
.imagePreview {
    width: 100%;
    height: 180px;
    background-position: center center;
    background-size: cover;
    -webkit-box-shadow: 0 0 1px 1px rgba(0, 0, 0, .3);
    display: inline-block;
}

Screen Shot 2016-12-04 at 10.36.10 PM.png

こうなります。

FileReaderを使って画像を読み込み、divの背景に表示します

$(document).on('change', ':file', function() {
    var input = $(this),
    numFiles = input.get(0).files ? input.get(0).files.length : 1,
    label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
    input.parent().parent().next(':text').val(label);

    var files = !!this.files ? this.files : [];
    if (!files.length || !window.FileReader) return; // no file selected, or no FileReader support
    if (/^image/.test( files[0].type)){ // only image file
        var reader = new FileReader(); // instance of the FileReader
        reader.readAsDataURL(files[0]); // read the local file
        reader.onloadend = function(){ // set image data as background of div
            input.parent().parent().parent().prev('.imagePreview').css("background-image", "url("+this.result+")");
        }
    }
});

後半を追記しています。


サンプル

html全体は下記です。試してみてください

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<style>
    .imagePreview {
        width: 100%;
        height: 180px;
        background-position: center center;
        background-size: cover;
        -webkit-box-shadow: 0 0 1px 1px rgba(0, 0, 0, .3);
        display: inline-block;
    }
</style>
    </head>
    <body>
        <div class="container page-header">
            <div class="col-sm-4">
                <form action="" method="post" enctype="multipart/form-data">
                    <div class="imagePreview"></div>
                    <div class="input-group">
                        <label class="input-group-btn">
                            <span class="btn btn-primary">
                                Choose File<input type="file" style="display:none" class="uploadFile">
                            </span>
                        </label>
                        <input type="text" class="form-control" readonly="">
                    </div>
                </form>
            </div>
        </div>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script>
        $(document).on('change', ':file', function() {
            var input = $(this),
            numFiles = input.get(0).files ? input.get(0).files.length : 1,
            label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
            input.parent().parent().next(':text').val(label);

            var files = !!this.files ? this.files : [];
            if (!files.length || !window.FileReader) return; // no file selected, or no FileReader support
            if (/^image/.test( files[0].type)){ // only image file
                var reader = new FileReader(); // instance of the FileReader
                reader.readAsDataURL(files[0]); // read the local file
                reader.onloadend = function(){ // set image data as background of div
                    input.parent().parent().parent().prev('.imagePreview').css("background-image", "url("+this.result+")");
                }
            }
        });
        </script>
    </body>
</html>
161
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
gsk3beta

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
161
Help us understand the problem. What is going on with this article?