Last active
April 17, 2023 06:59
-
-
Save danielfriis/ba7db29c590c47d32afc279a9bf40f35 to your computer and use it in GitHub Desktop.
Autosave using Stimulus and Rails 7
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
// app/javascript/controllers/autosave_controller.js | |
import { Controller } from "@hotwired/stimulus"; | |
import debounce from "lodash.debounce"; | |
// Connects to data-controller="autosave" | |
export default class extends Controller { | |
connect() { | |
this.form = this.element.closest("form"); | |
this.formData = new FormData(this.form); | |
this.url = this.form.action; | |
// Get the autosave delay from the data-autosave-delay attribute on the form. | |
const autosave_delay = this.form.dataset.autosaveDelay; | |
this.autosaveDelayAsInt = parseInt(autosave_delay); | |
const requestToDelay = () => this.sendRequest(this.url, this.formData); | |
// Debounce the request to avoid sending too many requests. | |
// The request will be sent after the time specified in autosave_target | |
// has passed since the last call to the debounced function. | |
this.debouncedRequest = debounce(requestToDelay, this.autosaveDelayAsInt); | |
} | |
save() { | |
this.formData = new FormData(this.form); | |
// Call the debounced request with the new form data. | |
this.debouncedRequest(this.url, this.formData); | |
} | |
sendRequest(url, formData) { | |
console.log("Sending request to " + url); | |
// fetch and trigger turbo_stream response | |
fetch(url, { | |
method: "POST", | |
body: formData, | |
headers: { | |
"X-CSRF-Token": document.querySelector("meta[name='csrf-token']").content, | |
Accept: "text/vnd.turbo-stream.html", | |
}, | |
credentials: "same-origin", | |
}).then((response) => { | |
response.text().then((html) => { | |
document.body.insertAdjacentHTML("beforeend", html); | |
}); | |
}); | |
} | |
} |
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
<%= form_with(model: @my_model, data: {controller: 'autosave', autosave_delay: '1000'}) do |f| %> | |
<%= f.text_field :title, data: {action: "keyup->autosave#save blur->autosave#save"} %> | |
<% end %> |
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
# config/importmap.rb | |
pin "lodash.debounce", to: "https://ga.jspm.io/npm:[email protected]/index.js" |
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
// app/javascript/controllers/index.js | |
import { application } from "./application" | |
import AutosaveController from "./autosave_controller" | |
application.register("autosave", AutosaveController) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment