Bootstrap の File input の見た目を Cool にする

## 概要

[Bootstrap](http://getbootstrap.com/) を使うと見た目がかなりキレイになりますが、まだまだイケてない部分があります。
例えば、Forms の File input。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/6697/b276dbf9-1313-b2ac-6d34-bdb18b60ffdc.png)

汚い！！！せっかくその他のボタン等は綺麗なのに、もったいないですね。

そこで、少しでも見た目が Cool になるように改善したい思います。
今回は [Bootstrap File Input](http://plugins.krajee.com/file-input) というライブラリを導入してみました。
そして、このライブラリを利用して、実際に CSV ファイルをアップロードするための form を作ってみたいと思います。

### お断り

本当は [Bootstrap File Input](http://plugins.krajee.com/file-input) を使うと、
例えば画像ファイルを選択した際にとても Cool なプレビューが表示されたりするのですが、
今回は CSV ファイルをアップロードするという用途に限定したいと思います。
気になる方は公式の [デモ](http://plugins.krajee.com/file-input/demo) をご覧ください。

## Bootstrap File Input の導入方法

### 1. Gemfile に追加して bundle install

* [Rails Assets](https://rails-assets.org/) を利用しています。

``` Gemfile
source 'https://rails-assets.org' do
  gem 'rails-assets-bootstrap-fileinput', '~> 2.5.0'
end
```

### 2. マニフェストに追加

``` sass:application.css.scss
@import 'bootstrap-fileinput';
```

``` js:application.js
//= require bootstrap-fileinput
```

### 3. form を作る

``` slim:csv_upload.html.slim
= form_tag import_hoges_path, multipart: true do
  = file_field_tag :csv_file, class: 'js-csv-upload'
```

### 4. Bootstrap File Input を適用する

``` coffeescript:csv_upload.js.coffee
$('.js-csv-upload').fileinput
  showPreview: false
  maxFileCount: 1
  browseClass: 'btn btn-info fileinput-browse-button'
  browseIcon: ''
  browseLabel: ' ファイル選択'
  removeClass: 'btn btn-warning'
  removeIcon: ''
  removeLabel: ' キャンセル'
  uploadClass: 'btn btn-success fileinput-upload-button'
  uploadIcon: '<i class="fa fa-upload"></i>'
  uploadLabel: ' インポート'
  allowedFileExtensions: ['csv']
  msgValidationError: '''
    <span class="text-danger">
      <i class="fa fa-warning"></i> CSV ファイルのみ有効です。
    </span>
  '''
```

### 5. スタイルをゴニョゴニョする。

* ファイル選択前には remove ボタンと upload ボタンを表示しないようにする。
* ファイル選択後に 、選択したファイルの形式が不正だった場合 (この例では CSV 以外のファイルだった場合) は、  
remove ボタンのみを表示するようにする。

``` scss:_bootstrap_overrides.css.scss
@import 'compass/css3/border-radius';

/* Bootstrap File Input */

.fileinput-browse-button {
  display: none;
}

.fileinput-upload-button {
  @include border-top-right-radius(4px !important);
  @include border-bottom-right-radius(4px !important);
}

.file-input.file-input-new {
  .fileinput-browse-button {
    display: inline-block;
  }
}

.file-input.has-error {
  .fileinput-upload-button {
    display: none;
  }

  .fileinput-remove-button {
    @include border-top-right-radius(4px !important);
    @include border-bottom-right-radius(4px !important);
  }
}
```

## Before

![01.png](https://qiita-image-store.s3.amazonaws.com/0/6697/b276dbf9-1313-b2ac-6d34-bdb18b60ffdc.png)

## After

#### 1. ファイル選択前

![2.png](https://qiita-image-store.s3.amazonaws.com/0/6697/b3a8b95d-e077-0fee-a486-730eb0dc648b.png)

#### 2. ファイル選択後 (CSV ファイルを選択した場合)

![3.png](https://qiita-image-store.s3.amazonaws.com/0/6697/452be460-9ba5-0359-ca13-07b0a149b9ff.png)

#### 3. ファイル選択後 (CSV ファイル以外を選択した場合)

![4.png](https://qiita-image-store.s3.amazonaws.com/0/6697/c31c2043-99f0-5cb0-be7d-2b6d7cf6e88d.png)

✌ ('ω' ✌ )三 ✌ ('ω') ✌ 三( ✌ 'ω') ✌ 綺麗になった！

## 参考

* [Bootstrap File Input](http://plugins.krajee.com/file-input)
    * [デモ](http://plugins.krajee.com/file-input/demo)