Stimulusを使ってドラッグ&ドロップでファイルアップロード
Rails で input[type=file] の入力欄にファイルをドラッグ&ドロップして選択する機能を追加しようと調べてみたのですが、script 要素にべた書きの実装例しか見つからなかったので、Stimulus を使った実装をしてみました。
環境
- Ruby 3.1.1
- Ruby on Rails 7.0.2
View
既存のページには、data-controller 属性と data-action 属性と data-*-target 属性を追加するだけなので、ほとんで手を入れずに済みます。
Stimulus 側に file_drop という名前のコントローラを作るので、data-* 属性の値や名前もそれに合わせます。
...
<div data-controller="file-drop"
data-action="dragover->file-drop#dragover dragleave->file-drop#dragleave drop->file-drop#drop">
<%= form.label :image, style: "display: block" %>
<%= form.file_field :image, 'data-file-drop-target': 'fileUpload' %>
</div>
...
Controller
targets
で指定した値(fileUpload
)から自動的に fileUploadTarge
というプロパティが生成されます。
これは自動で生成されるため、targets の値に file-upload
のようなケバブケースは使えません。
'data-file-drop-target': 'file-upload'
って書きたかったのですが諦めました。
data-action 属性でイベントとそれに対応するコントローラ#メソッドを指定したものが、ここで呼ばれます。
element.addEventListener('dragover', () => {})
としていたのが、ちょっとわかりやすく書けます。
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
static targets = ['fileUpload']
dragover(e) {
e.preventDefault()
// dragover したときに border の色を変える
this.fileUploadTarget.classList.add('border-primary')
}
dragleave(e) {
e.preventDefault()
this.fileUploadTarget.classList.remove('border-primary')
}
drop(e) {
e.preventDefault()
this.fileUploadTarget.classList.remove('border-primary')
const files = e.dataTransfer.files
if (typeof files[0] !== 'undefined') {
this.fileUploadTarget.files = files
}
}
}
あとは作成したコントローラを読み込むだけ。
import { application } from './application'
import FileDropController from './file_drop_controller'
application.register('file-drop', FileDropController)
Author And Source
この問題について(Stimulusを使ってドラッグ&ドロップでファイルアップロード), 我々は、より多くの情報をここで見つけました https://qiita.com/mkt1234/items/92f286a944a1fd4f8823著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .