How do I drag and drop an image file?
I have a rails application that can upload an image using CarrierWave and MiniMagick and a file_field. This seems to be the usual way to do things and works well. I have a user that wants to open an email that has an image attachment and drag and drop that image into my application. This would be quicker than them downloading the email attachment and then attaching it in the application from the download folder. Is there an easy way to code this?
It turns out to be really easy. Just click and hold over the email attachment and drop it on the choose file button on the file field on the application and let go of the mouse button. That's it.
Here is one of many ways to create drag and drop
functionallity into your application.
Create a new .js
file (or add into application.js
) in your assets and add the following code:
var $fileInput = $('.file_input');
var $droparea = $('.file_droparea');
$fileInput.on('dragenter focus click', function () {
$droparea.addClass('is-active');
});
$fileInput.on('dragleave blur drop', function () {
$droparea.removeClass('is-active');
});
$fileInput.on('change', function () {
var filesCount = $(this)[0].files.length;
var $textContainer = $(this).prev('.js-set-number');
if (filesCount === 1) {
$textContainer.text($(this).val().split('\\').pop());
} else {
$textContainer.text(filesCount + ' uploaded files');
}
});
The code above will track the hover effects on the field (.file_droparea
in my case, feel free to change it however you like).
Next, we need to create our form (HAML):
= form_for Something.new, method: 'post', :html => { :multipart => true }, class: "form-block" do |f|
.form-block_container
.form-block_input
.form-block_avatar_file
.file_droparea
%p.file_msg.js-set-number Choose your files or drag them here
= f.file_field :photo, multiport: false, class: "file_input", type: :file, multiple: false, required: true
Note: if you want to drag more then 1 file, simply change multiple: false
to multiple: true
in f.filed_field :photo
.
The last thing to do is to style your form, here is my sample (SCSS):
.file_droparea {
border: 1px dashed black;
border-radius: 4px;
background-color: gray;
position: relative;
width: 100%;
max-width: 100%;
margin: 0 auto;
padding: 26px 20px 30px;
-webkit-transition: 0.2s;
transition: 0.2s;
text-align: center;
cursor: pointer;
&.is-active,
&:focus,
&:hover {
border-color: $blue;
}
}
.file_msg {
color: #777;
font-size: small;
font-weight: 400;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
max-width: calc(100% - 130px);
vertical-align: middle;
}
.file_input {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
cursor: pointer;
opacity: 0;
&:focus {
outline: none;
}
}