forked from justalever/drag_and_drop_active_storage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Andy Leverenz
committed
Sep 15, 2019
1 parent
3a2fdd0
commit f5181a4
Showing
26 changed files
with
563 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
class PostsController < ApplicationController | ||
before_action :authenticate_user!, except: [:show, :index] | ||
before_action :set_post, only: [:show, :edit, :update, :destroy] | ||
|
||
|
||
def index | ||
@posts = Post.all | ||
end | ||
|
||
def show | ||
end | ||
|
||
def new | ||
@post = Post.new | ||
end | ||
|
||
def edit | ||
end | ||
|
||
def create | ||
@post = Post.new(post_params) | ||
@post.user_id = current_user.id | ||
|
||
respond_to do |format| | ||
if @post.save | ||
format.html { redirect_to @post, notice: 'Post was successfully created.' } | ||
format.json { render :show, status: :created, location: @post } | ||
else | ||
format.html { render :new } | ||
format.json { render json: @post.errors, status: :unprocessable_entity } | ||
end | ||
end | ||
end | ||
|
||
def update | ||
respond_to do |format| | ||
if @post.update(post_params) | ||
format.html { redirect_to @post, notice: 'Post was successfully updated.' } | ||
format.json { render :show, status: :ok, location: @post } | ||
else | ||
format.html { render :edit } | ||
format.json { render json: @post.errors, status: :unprocessable_entity } | ||
end | ||
end | ||
end | ||
|
||
def destroy | ||
@post.destroy | ||
respond_to do |format| | ||
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' } | ||
format.json { head :no_content } | ||
end | ||
end | ||
|
||
private | ||
|
||
def set_post | ||
@post = Post.find(params[:id]) | ||
end | ||
|
||
def post_params | ||
params.require(:post).permit(:title, :body, :user_id, :feature_image) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
module PostsHelper | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
import Dropzone from "dropzone"; | ||
import { Controller } from "stimulus"; | ||
import { DirectUpload } from "@rails/activestorage"; | ||
import { | ||
getMetaValue, | ||
toArray, | ||
findElement, | ||
removeElement, | ||
insertAfter | ||
} from "helpers"; | ||
|
||
export default class extends Controller { | ||
static targets = ["input"]; | ||
|
||
connect() { | ||
this.dropZone = createDropZone(this); | ||
this.hideFileInput(); | ||
this.bindEvents(); | ||
Dropzone.autoDiscover = false; | ||
} | ||
|
||
// Private | ||
hideFileInput() { | ||
this.inputTarget.disabled = true; | ||
this.inputTarget.style.display = "none"; | ||
} | ||
|
||
bindEvents() { | ||
this.dropZone.on("addedfile", file => { | ||
setTimeout(() => { | ||
file.accepted && createDirectUploadController(this, file).start(); | ||
}, 500); | ||
}); | ||
|
||
this.dropZone.on("removedfile", file => { | ||
file.controller && removeElement(file.controller.hiddenInput); | ||
}); | ||
|
||
this.dropZone.on("canceled", file => { | ||
file.controller && file.controller.xhr.abort(); | ||
}); | ||
} | ||
|
||
get headers() { | ||
return { "X-CSRF-Token": getMetaValue("csrf-token") }; | ||
} | ||
|
||
get url() { | ||
return this.inputTarget.getAttribute("data-direct-upload-url"); | ||
} | ||
|
||
get maxFiles() { | ||
return this.data.get("maxFiles") || 1; | ||
} | ||
|
||
get maxFileSize() { | ||
return this.data.get("maxFileSize") || 256; | ||
} | ||
|
||
get acceptedFiles() { | ||
return this.data.get("acceptedFiles"); | ||
} | ||
|
||
get addRemoveLinks() { | ||
return this.data.get("addRemoveLinks") || true; | ||
} | ||
} | ||
|
||
class DirectUploadController { | ||
constructor(source, file) { | ||
this.directUpload = createDirectUpload(file, source.url, this); | ||
this.source = source; | ||
this.file = file; | ||
} | ||
|
||
start() { | ||
this.file.controller = this; | ||
this.hiddenInput = this.createHiddenInput(); | ||
this.directUpload.create((error, attributes) => { | ||
if (error) { | ||
removeElement(this.hiddenInput); | ||
this.emitDropzoneError(error); | ||
} else { | ||
this.hiddenInput.value = attributes.signed_id; | ||
this.emitDropzoneSuccess(); | ||
} | ||
}); | ||
} | ||
|
||
createHiddenInput() { | ||
const input = document.createElement("input"); | ||
input.type = "hidden"; | ||
input.name = this.source.inputTarget.name; | ||
insertAfter(input, this.source.inputTarget); | ||
return input; | ||
} | ||
|
||
directUploadWillStoreFileWithXHR(xhr) { | ||
this.bindProgressEvent(xhr); | ||
this.emitDropzoneUploading(); | ||
} | ||
|
||
bindProgressEvent(xhr) { | ||
this.xhr = xhr; | ||
this.xhr.upload.addEventListener("progress", event => | ||
this.uploadRequestDidProgress(event) | ||
); | ||
} | ||
|
||
uploadRequestDidProgress(event) { | ||
const element = this.source.element; | ||
const progress = (event.loaded / event.total) * 100; | ||
findElement( | ||
this.file.previewTemplate, | ||
".dz-upload" | ||
).style.width = `${progress}%`; | ||
} | ||
|
||
emitDropzoneUploading() { | ||
this.file.status = Dropzone.UPLOADING; | ||
this.source.dropZone.emit("processing", this.file); | ||
} | ||
|
||
emitDropzoneError(error) { | ||
this.file.status = Dropzone.ERROR; | ||
this.source.dropZone.emit("error", this.file, error); | ||
this.source.dropZone.emit("complete", this.file); | ||
} | ||
|
||
emitDropzoneSuccess() { | ||
this.file.status = Dropzone.SUCCESS; | ||
this.source.dropZone.emit("success", this.file); | ||
this.source.dropZone.emit("complete", this.file); | ||
} | ||
} | ||
|
||
function createDirectUploadController(source, file) { | ||
return new DirectUploadController(source, file); | ||
} | ||
|
||
function createDirectUpload(file, url, controller) { | ||
return new DirectUpload(file, url, controller); | ||
} | ||
|
||
function createDropZone(controller) { | ||
return new Dropzone(controller.element, { | ||
url: controller.url, | ||
headers: controller.headers, | ||
maxFiles: controller.maxFiles, | ||
maxFilesize: controller.maxFileSize, | ||
acceptedFiles: controller.acceptedFiles, | ||
addRemoveLinks: controller.addRemoveLinks, | ||
autoQueue: false | ||
}); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
// Load all the controllers within this directory and all subdirectories. | ||
// Load all the controllers within this directory and all subdirectories. | ||
// Controller files must be named *_controller.js. | ||
|
||
import { Application } from "stimulus" | ||
import { definitionsFromContext } from "stimulus/webpack-helpers" | ||
import { Application } from "stimulus"; | ||
import { definitionsFromContext } from "stimulus/webpack-helpers"; | ||
|
||
const application = Application.start() | ||
const context = require.context("controllers", true, /_controller\.js$/) | ||
application.load(definitionsFromContext(context)) | ||
const application = Application.start(); | ||
const context = require.context("controllers", true, /_controller\.js$/); | ||
application.load(definitionsFromContext(context)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
export function getMetaValue(name) { | ||
const element = findElement(document.head, `meta[name="${name}"]`); | ||
if (element) { | ||
return element.getAttribute("content"); | ||
} | ||
} | ||
|
||
export function findElement(root, selector) { | ||
if (typeof root == "string") { | ||
selector = root; | ||
root = document; | ||
} | ||
return root.querySelector(selector); | ||
} | ||
|
||
export function toArray(value) { | ||
if (Array.isArray(value)) { | ||
return value; | ||
} else if (Array.from) { | ||
return Array.from(value); | ||
} else { | ||
return [].slice.call(value); | ||
} | ||
} | ||
|
||
export function removeElement(el) { | ||
if (el && el.parentNode) { | ||
el.parentNode.removeChild(el); | ||
} | ||
} | ||
|
||
export function insertAfter(el, referenceNode) { | ||
return referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class Post < ApplicationRecord | ||
belongs_to :user | ||
has_one_attached :feature_image | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<%= form_with(model: post, local: true, multipart: true) do |form| %> | ||
<% if post.errors.any? %> | ||
<div id="error_explanation"> | ||
<h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2> | ||
|
||
<ul> | ||
<% post.errors.full_messages.each do |message| %> | ||
<li><%= message %></li> | ||
<% end %> | ||
</ul> | ||
</div> | ||
<% end %> | ||
|
||
<div class="mb-6"> | ||
<%= form.label :title, class: "label" %> | ||
<%= form.text_field :title, class: "input" %> | ||
</div> | ||
|
||
<div class="mb-6"> | ||
<%= form.label :body, class: "label" %> | ||
<%= form.text_area :body, class: "input" %> | ||
</div> | ||
|
||
<div class="mb-6"> | ||
<%= form.label :feature_image, class: "label" %> | ||
<div class="dropzone dropzone-default dz-clickable" data-controller="dropzone" data-dropzone-max-file-size="2" data-dropzone-max-files="1"> | ||
<%= form.file_field :feature_image, direct_upload: true, data: { target: 'dropzone.input' } %> | ||
<div class="dropzone-msg dz-message needsclick text-gray-600"> | ||
<h3 class="dropzone-msg-title">Drag here to upload or click here to browse</h3> | ||
<span class="dropzone-msg-desc text-sm">2 MB file size maximum. Allowed file types png, jpg.</span> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="mb-6"> | ||
<%= form.submit class: "btn-default btn" %> | ||
</div> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
json.extract! post, :id, :title, :body, :user_id, :created_at, :updated_at | ||
json.url post_url(post, format: :json) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<div class="max-w-2xl m-auto"> | ||
<h1 class="text-3xl font-bold text-black mb-6">Edit Post</h1> | ||
|
||
<%= render 'form', post: @post %> | ||
</div> |
Oops, something went wrong.