【簡単】ドラッグ &ドロップはCSSのみで実装できる！？参考画像でやり方ご紹介

##はじめに
画像投稿の際に１つ１つ画像を選んで投稿...とても面倒ですよね:disappointed_relieved:
そこでドラッグ&ドロップができればめちゃくちゃ簡単に投稿できかな？と思い調べてみました。

結果JavaScriptを使えば可能なのはわかったけれど、初学者としてはもっとシンプルに、簡単に実装したい！
もっと楽したい！！

そんな時に閃いた力技をご紹介します。

##実は最初からドラッグ&ドロップできる！
実はfile_fierdを使用すると、何もしなくてもドラッグ&ドロップできます。
「...？」ですよね、実際に確認してみましょう

![55c81fbbba05599cef2cc8a79135892f.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508299/6ccb6999-f549-23a7-f662-de517cd8e7fb.gif)

ちゃんとできてますよね？
ちなみに今のViewはこれだけです。

```ruby:articles>new.html.haml
= form_with model: @article de |f|
 .new_article
  = f.file_field :image
  = f.submit
```
file_fieldを使用した際に作られる「ファイルを選択」ボタンの上であれば、ドラッグ&ドロップは可能な状態にあります！
ね、簡単でしょう？

#viewを整える
これを利用すれば、使いやすいドラッグ&ドロップ機能が実装できます！
そこで、これからやることは以下の３つ
1. ファイル選択ボタンを広げる
2. ドラッグ&ドロップエリアを作成する。
3. "1"のファイル選択ボタンと"2"のドラッグ&ドロップエリアを重ねる。
それでは、順を追ってご紹介します。

###1.ファイル選択ボタンを広げる
file_fieldで作成したボタンにクラスをつけて、CSSで広げる。

```ruby:articles>new.html.haml
= form_with model: @article de |f|
 .new_article
  = f.file_field :image, id: "post"
  = f.submit
```

```css:new.scss
#post{
 height: 300px;
 width: 300px;
 cursor: pointer;
 background-color: aqua;
}
```

![7ffca4b4167eb1dd5d8f6d913b77195d.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508299/6e3d2832-91c3-45c3-e44f-00733332c2b5.gif)

※ 今回はわかりやすいようにJSでプレビュー表示させています。
>引用：http://www.koikikukan.com/archives/2016/07/06-000300.php

###2. ドラッグ&ドロップエリアを作成する
ファイルを選択ボタンが邪魔なので、ドラッグ＆ドロップできるエリアを作ります。

```ruby:articles>new.html.haml
= form_with model: @article do |f|
  = f.file_field :image, id:"post"
  .choice_box ドラック＆ドロップまたはクリック
  .submit
    = f.submit
```

```css:new.scss
#post{
 height: 300px;
 width: 300px;
 cursor: pointer;
 background-color: aqua;
}
.choice_box{
  height: 300px;
  width: 300px;
  background-color: rgb(186, 186, 186);
  pointer-events: none;
  line-height: 300px;
  text-align: center;
  border: 2px dashed black;
}
```

###3. "1"のファイル選択ボタンと"2"のドラッグ&ドロップエリアを重ねる

<img width="658" alt="スクリーンショット 2019-12-08 12.49.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508299/225d19de-8bd0-f0b7-4cfa-bf221690f8d7.png">

#完成
以上でドラッグ&ドロップが完成です！（もちろん、ファイルクリックでも選択できます。）
簡単でしたよね？

最終的にはこんな感じになります。
![948c466c0e5e33e51ce1fdefbb80045a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508299/897382a5-6225-5f0d-f5a2-f3e2ff68e20a.gif)

もちろん、データはちゃんと入っています。

<img width="1356" alt="スクリーンショット 2019-12-08 13.49.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508299/04863de4-c245-d8fc-3c1f-b1cf8a052e08.png">

以上が実装方法です。

##終わりに
プログラミング始めたばっかでJSはまだ難しい...と言う人は、このやり方を参考にしてみてください！
最初は難しいやり方を勉強するのではなく、自分ができそうなやり方で経験を積んで、プログラミングを楽しむことをお勧めします。

最後にコードを残しておきますので、色々触ってみてください。

```ruby:articles>new.html.haml
= form_with model: @article do |f|
  = f.file_field :image, id:"post"
  .choice_box
    ドラック＆ドロップまたはクリック
  #show
  .submit
    = f.submit

#以下、画像プレビューです。file_field (#post) が選択されたら プレビュー (#show)に画像を表示させます。
%script{:src => "https://code.jquery.com/jquery-3.0.0.min.js"}
:javascript
  $(function(){
    $('#post').change(function(){
      $('img').remove();
      var file = $(this).prop('files')[0];
      if(!file.type.match('image.*')){
        return;
      }
      var fileReader = new FileReader();
      fileReader.onloadend = function() {
        $('#show').html('<img src="' + fileReader.result + '"/>');
      }
      fileReader.readAsDataURL(file);
    });
  });
```

```css:new.scss
@mixin imageBox{
  height: 300px;
  width: 300px;
  cursor: pointer;
  position: absolute;
  top: 0;
  left: 0;
}
#post{
  @include imageBox;
  background-color: aqua;
  z-index: 1;
}
.choice_box{
  @include imageBox;
  background-color: rgb(186, 186, 186);
  z-index: 2;
  pointer-events: none;
  line-height: 300px;
  text-align: center;
  border: 2px dashed black;
}
#show{
  height: 300px;
  width: 300px;
  border: 2px solid #333;
  position: absolute;
  top: 0;
  left: 300px;
  img{
    height: 296px;
    width: 296px;
    object-fit: cover;
  }
}
.submit{
  position: absolute;
  top: 300px;
  left: 0;
}
```