Last active
March 23, 2021 21:07
-
-
Save archonic/5579208e6acba76020d359c1c9326d3c to your computer and use it in GitHub Desktop.
Rails generic edit-in-place feature using Stimulus.
This file contains hidden or 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
.row.no-gutters.attachment_item.my-3{ class: "resource_#{resource.id}", data: { controller: "edit-in-place", "edit-in-place-update-url": resource_path(resource.id), "edit-in-place-resource": "resource" } } | |
.col | |
%input{ type: :hidden, name: "attachment_detail[attachment_id]", value: file.id } | |
%h6 | |
%span{ data: { target: "edit-in-place.input", fieldtype: "text", attr: "name", value: resource.name } } | |
%p | |
%span{ data: { target: "edit-in-place.input", fieldtype: "textarea", attr: "description", value: resource.description } } | |
.col-auto.pull-right | |
.btn-group{ role: "group" } | |
%button.btn.btn-sm{ type: "button", data: { action: "edit-in-place#editMode", target: "edit-in-place.editBtn" } } | |
= icon "pencil" | |
%button.btn.btn-sm{ type: "button", data: { action: "resources#removeResource", "resource-id": resource.id } } | |
= icon "trash" |
This file contains hidden or 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
import { Controller } from "stimulus" | |
export default class extends Controller { | |
static targets = ["input", "editBtn"] | |
connect() { | |
this.viewMode() | |
this.element.controller = this; | |
} | |
viewMode() { | |
this.inputTargets.forEach((element) => { | |
element.innerText = element.dataset.value ?? "" | |
}) | |
} | |
editMode() { | |
this.inputTargets.forEach((element) => { | |
var input = document.createElement("input") | |
input.classList.add("edit-in-place") | |
input.setAttribute("type", element.dataset.fieldtype) | |
var name = `${this.data.get("resource")}[${element.dataset.attr}]` | |
input.setAttribute("name", name) | |
input.setAttribute("placeholder", element.dataset.attr) | |
input.setAttribute("value", element.innerHTML) | |
element.parentElement.replaceChild(input, element) | |
}) | |
this.editBtnTarget.innerHTML = "<i style='font-size: 16px;' class='fa fa-save'></i>" | |
this.editBtnTarget.setAttribute("data-action", "edit-in-place#submit") | |
} | |
submit() { | |
let container = this.element | |
Rails.ajax({ | |
url: this.data.get("update-url"), | |
data: this.formData(), | |
type: "patch", | |
beforeSend: function () { | |
return true; | |
}, | |
success: function (response) { | |
container.parentElement.replaceChild(response.body, container) | |
}, | |
error: function (response) { | |
container.classList.add("has-error") | |
} | |
}); | |
} | |
formData() { | |
var virtualForm = document.createElement("form") | |
var inputs = this.element.querySelectorAll("input") | |
inputs.forEach(function(input) { | |
virtualForm.appendChild(input.cloneNode()) | |
}) | |
// https://stackoverflow.com/a/44033425/1686604 | |
var data = Array.from( | |
new FormData(virtualForm), | |
e => e.map(encodeURIComponent).join('=') | |
).join('&') | |
return data | |
} | |
} |
This file contains hidden or 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
- resources.each do |resource| | |
= render partial: "index_item", locals: { resource: resource } |
This file contains hidden or 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
# frozen_string_literal: true | |
class ResourceController < ApplicationController | |
before_action :set_resource, only: :update | |
def update | |
authorize @resource | |
success = @resource.update resource_params | |
render partial: "resources/index_item", | |
locals: { resource: @resource }, | |
status: success ? :ok : :bad_request | |
end | |
private | |
def set_resource | |
@resource = Resource.find( resource_params[:id] ) | |
end | |
def resource_params | |
params.require(:resource).permit( | |
:id, | |
:attribute_1, | |
:attribute_2 | |
) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment