Created
September 28, 2021 20:18
-
-
Save pamelafox/8a37eaa0473e52f1677da18b6520b032 to your computer and use it in GitHub Desktop.
Auto-saving Rails form example
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
<!-- Auto-saving for Rails blog example --> | |
<h1>Editing Post</h1> | |
<p>Last saved: | |
<span id="last-saved-display" data-last-saved="<%= @post.updated_at.iso8601 %>"> | |
</span> | |
<span id="save-status"> | |
</span> | |
</p> | |
<%= render 'form', post: @post %> | |
<%= link_to 'Show', @post %> | | |
<%= link_to 'Back', posts_path %> | |
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/3.6.2/fetch.min.js" integrity="sha512-1Gn7//DzfuF67BGkg97Oc6jPN6hqxuZXnaTpC9P5uw8C6W4yUNj5hoS/APga4g1nO2X6USBb/rXtGzADdaVDeA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/global/luxon.min.js" type="text/javascript"></script> | |
<script> | |
window.addEventListener("load", () => { | |
const postForm = document.getElementById("post_form"); | |
const titleInput = document.getElementById("post_title"); | |
const contentArea = document.getElementById("post_content"); | |
const saveStatus = document.getElementById("save-status"); | |
const saveTime = document.getElementById("last-saved-display"); | |
let lastSavedTimer; | |
function updateLastSaved() { | |
const lastSavedISO = saveTime.getAttribute("data-last-saved"); | |
saveTime.innerText = luxon.DateTime.fromISO(lastSavedISO).toRelative(); | |
} | |
function onSave(responseJSON) { | |
saveStatus.innerText = "(Saved!)"; | |
saveStatus.classList.remove("error"); | |
saveTime.setAttribute("data-last-saved", responseJSON.updated_at); | |
if (lastSavedTimer) { | |
window.clearInterval(lastSavedTimer); | |
} | |
lastSavedTimer = window.setInterval(updateLastSaved, 5000); | |
updateLastSaved(); | |
} | |
function onError() { | |
saveStatus.innerText = "(Error!)"; | |
saveStatus.classList.add("error"); | |
} | |
function autoSavePost() { | |
saveStatus.innerText = "(Saving...)"; | |
const request = new XMLHttpRequest(); | |
request.addEventListener("load", function() { | |
onSave(request.response); | |
}); | |
request.addEventListener("error", function() { | |
onError(); | |
}); | |
request.responseType = "json"; | |
request.open("POST", postForm.getAttribute("action") + ".json"); | |
request.send(new FormData(postForm)); | |
} | |
function autoSavePostFetch() { | |
saveStatus.innerText = "(Saving...)"; | |
fetch(postForm.getAttribute("action") + ".json", | |
{method: "POST", body: new FormData(postForm)}) | |
.then(response => { | |
if (!response.ok) { | |
onError(); | |
} | |
return response.json(); | |
}) | |
.then(responseJSON => { onSave(responseJSON) }) | |
.catch(onError); | |
} | |
titleInput.addEventListener("change", () => autoSavePostFetch()); | |
contentArea.addEventListener("change", () => autoSavePostFetch()); | |
updateLastSaved(); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment