Skip to content

Instantly share code, notes, and snippets.

@goncalvesjoao
Created March 24, 2020 18:49
Show Gist options
  • Save goncalvesjoao/e86ee77f0b5766302e732e62c0570c41 to your computer and use it in GitHub Desktop.
Save goncalvesjoao/e86ee77f0b5766302e732e62c0570c41 to your computer and use it in GitHub Desktop.
CarrierWave: add and remove individual images using multiple file upload, without loosing the previously selected one.
<!-- Requires bootstrap css for style -->
<%= form_with(model: @post, local: true, html: { multipart: true }) do |f| %>
<label class="control-label">Images</label>
<div id="file-list" class="mb-2 flex">
<% @post.images.each do |image| %>
<div class="position-relative mr-3 text-center file-preview" style="width: min-content;">
<div class="img-thumbnail">
<%= image_tag(image.thumb.url || 'https://icons.iconarchive.com/icons/zhoolego/material/512/Filetype-Docs-icon.png', height: 100) %>
<button style="top: 5px; right: 5px;" class="btn btn-xs btn-danger position-absolute" onclick="$(this).closest('.file-preview').remove()">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
</div>
<%= f.hidden_field :images, multiple: true, value: image.cache_name || image.identifier %>
</div>
<% end %>
</div>
<label for="upload_input" class="btn btn-warning">Upload</label>
<%= f.file_field :images id: 'upload_input', class: 'd-none', accept: 'image/*', multiple: true, onchange: 'window.breakIntoSeparateFiles(this, "#file-list", "#file-preview")' %>
<template id="file-preview">
<div class="position-relative mr-3 text-center file-preview" style="width: min-content;">
<div class="img-thumbnail">
<%= image_tag('', height: 100) %>
<button style="top: 5px; right: 5px;" class="btn btn-xs btn-danger position-absolute" onclick="$(this).closest('.file-preview').remove()">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
</div>
<%= f.file_field :images, class: 'd-none', multiple: true %>
</div>
</template>
<%= f.submit %>
<% end %>
//= require rails-ujs
//= require jquery
//= require_tree .
(function (window, $) {
var FILE_ICON_URL = 'https://icons.iconarchive.com/icons/zhoolego/material/512/Filetype-Docs-icon.png'
function addFileToNewInput(file, newInput) {
if (!newInput) { return }
var dataTransfer = new DataTransfer()
dataTransfer.items.add(file)
newInput.files = dataTransfer.files
}
function addSrcToPreview(file, preview) {
if (!preview) { return }
if (file.type.match(/image/)) {
var reader = new FileReader()
reader.onload = function (e) { preview.src = e.target.result }
reader.readAsDataURL(file)
} else {
preview.src = FILE_ICON_URL
}
}
function breakIntoSeparateFiles(input, targetSelector, templateSelector) {
var $input = $(input)
var templateHtml = $(templateSelector).html()
if (!input.files) { return }
for(var file of input.files) {
var $newFile = $(templateHtml).appendTo(targetSelector)
addFileToNewInput(file, $newFile.find("input")[0])
addSrcToPreview(file, $newFile.find("img")[0])
}
$input.val([])
}
window.breakIntoSeparateFiles = breakIntoSeparateFiles
})(window, jQuery)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment