From 4121f68f7dda164128bd78ec166db58efc322def Mon Sep 17 00:00:00 2001 From: Kevin McConnell Date: Mon, 10 Feb 2025 13:53:37 +0000 Subject: [PATCH] Auto-save edits to bubble title --- .../controllers/auto_save_controller.js | 48 +++++++++++++++++++ app/javascript/helpers/form_helpers.js | 9 ++++ app/views/bubbles/_bubble.html.erb | 4 +- 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 app/javascript/controllers/auto_save_controller.js create mode 100644 app/javascript/helpers/form_helpers.js diff --git a/app/javascript/controllers/auto_save_controller.js b/app/javascript/controllers/auto_save_controller.js new file mode 100644 index 000000000..0323ab9ad --- /dev/null +++ b/app/javascript/controllers/auto_save_controller.js @@ -0,0 +1,48 @@ +import { Controller } from "@hotwired/stimulus" +import { submitForm } from "helpers/form_helpers" + +const AUTOSAVE_INTERVAL = 3000 + +export default class extends Controller { + #timer + + // Lifecycle + + disconnect() { + this.submit() + } + + // Actions + + async submit() { + if (this.#dirty) { + await this.#save() + } + } + + change(event) { + if (event.target.form === this.element && !this.#dirty) { + this.#scheduleSave() + } + } + + // Private + + #scheduleSave() { + this.#timer = setTimeout(() => this.#save(), AUTOSAVE_INTERVAL) + } + + async #save() { + this.#resetTimer() + await submitForm(this.element) + } + + #resetTimer() { + clearTimeout(this.#timer) + this.#timer = null + } + + get #dirty() { + return !!this.#timer + } +} diff --git a/app/javascript/helpers/form_helpers.js b/app/javascript/helpers/form_helpers.js new file mode 100644 index 000000000..f9a872702 --- /dev/null +++ b/app/javascript/helpers/form_helpers.js @@ -0,0 +1,9 @@ +import { FetchRequest } from "@rails/request.js" + +export async function submitForm(form) { + const request = new FetchRequest(form.method, form.action, { + body: new FormData(form) + }) + + return await request.perform() +} diff --git a/app/views/bubbles/_bubble.html.erb b/app/views/bubbles/_bubble.html.erb index 1a126fa97..0fc806347 100644 --- a/app/views/bubbles/_bubble.html.erb +++ b/app/views/bubbles/_bubble.html.erb @@ -9,8 +9,8 @@

<% if bubble.creating? %> - <%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble) do |form| %> - <%= form.text_field :title, placeholder: "Name it…", class: "input txt-align-center full-width borderless", autofocus: bubble.title.blank? %> + <%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble), data: { controller: "auto-save" } do |form| %> + <%= form.text_field :title, placeholder: "Name it…", class: "input txt-align-center full-width borderless", autofocus: bubble.title.blank?, data: { action: "auto-save#change blur->auto-save#submit" } %> <% end %> <% else %> <%= turbo_frame_tag bubble, :edit do %>