Skip to content

Commit

Permalink
Maintain the forms state using local storage when the page is refresh…
Browse files Browse the repository at this point in the history
…ed or reloaded, thanks @knowler
  • Loading branch information
daviddarnes committed Dec 29, 2023
1 parent 16ff04a commit 5294980
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 27 deletions.
41 changes: 29 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ General usage example:
</storage-form>
```

Example of submitting with `change` event (no submit button) and listening for `storage` event. Use case for light/dark mode:
Example of submitting with `change` event instead of a submit button. Use case for light/dark mode:

```html
<script type="module" src="storage-form.js"></script>
Expand All @@ -49,16 +49,31 @@ Example of submitting with `change` event (no submit button) and listening for `
</label>
</form>
</storage-form>
```

Example of hooking into `storage` event:

```html
<script type="module" src="storage-form.js"></script>

<storage-form>
<form>
<label>
Update the
<code>output</code>
by checking the box
<input type="hidden" name="output" value />
<input type="checkbox" name="output" value="updated" />
</label>
</form>
</storage-form>

<output></output>
<script>
// Keeping form state in sync with local storage using storage event and on page load
const updatePage = () => {
const options = ["theme", "contrast"];
for (let option of options) {
document.querySelector(
`[name='${option}'][value='${window.localStorage[option] || ""}']`
).checked = true;
}
document.querySelector("output").innerHTML = JSON.stringify(
window.localStorage
);
};
window.addEventListener("storage", updatePage);
updatePage();
Expand All @@ -69,9 +84,10 @@ Example of submitting with `change` event (no submit button) and listening for `

This Web Component allows you to:

- Use regular form elements to maniptulate data in local storage
- Use regular form elements to manipulate data in local storage
- Invoke a `storage` event on the page to hook into elsewhere on the page
- Optionally submit the form on the forms `change` event by ommiting the forms submit button/input element
- Maintain the forms state, using local storage, when the page is refreshed or reloaded
- Optionally submit the form on the forms `change` event by omitting the forms submit button/input element

## Installation

Expand All @@ -94,15 +110,15 @@ Make sure you include the `<script>` in your project (choose one of these):
<!-- 3rd party CDN, not recommended for production use -->
<script
type="module"
src="https://www.unpkg.com/@daviddarnes/storage-form@1.0.0/storage-form.js"
src="https://www.unpkg.com/@daviddarnes/storage-form@2.0.0/storage-form.js"
></script>
```

```html
<!-- 3rd party CDN, not recommended for production use -->
<script
type="module"
src="https://esm.sh/@daviddarnes/storage-form@1.0.0"
src="https://esm.sh/@daviddarnes/storage-form@2.0.0"
></script>
```

Expand All @@ -111,3 +127,4 @@ Make sure you include the `<script>` in your project (choose one of these):
With thanks to the following people:

- [Zach Leatherman](https://zachleat.com) for inspiring this [Web Component repo template](https://github.com/daviddarnes/component-template)
- [Nathan Knowler](https://knowler.dev) for proposing a solution to the `updateForm()` method
33 changes: 19 additions & 14 deletions demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ <h2>General example</h2>
<h2>
Example of submitting with
<code>change</code>
event (no submit button) and listening for
<code>storage</code>
event
event instead of a submit button
</h2>
<p>Use case for light/dark mode.</p>
<storage-form>
Expand Down Expand Up @@ -77,20 +75,27 @@ <h2>

<hr />

<h2>Data retrieved from local storage</h2>
<output></output>
<h2>
Example of hooking into
<code>storage</code>
event
</h2>

<storage-form>
<form>
<label>
Update the
<code>output</code>
by checking the box
<input type="hidden" name="output" value />
<input type="checkbox" name="output" value="updated" />
</label>
</form>
</storage-form>

<output></output>
<script>
const updatePage = () => {
const options = ["theme", "contrast"];
for (let option of options) {
// Ensure form stays in sync
document.querySelector(
`[name='${option}'][value='${window.localStorage[option] || ""}']`
).checked = true;
}

// Update output to demonstrate
document.querySelector("output").innerHTML = JSON.stringify(
window.localStorage
);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@daviddarnes/storage-form",
"version": "1.1.0",
"version": "2.0.0",
"description": "A Web Component that allows you to submit data to local storage",
"main": "storage-form.js",
"scripts": {
Expand Down
18 changes: 18 additions & 0 deletions storage-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class StorageForm extends HTMLElement {

connectedCallback() {
this.forms.forEach((form) => {
this.updateForm(form);
const eventType = this.getSubmitter(form) ? "submit" : "change";
form.addEventListener(eventType, (event) => {
event.preventDefault();
Expand All @@ -16,6 +17,23 @@ class StorageForm extends HTMLElement {
});
}

updateForm(form) {
for (const input of form.elements) {
const storedValue = window.localStorage[input.name];
if (!storedValue) return;
switch (input.type) {
case "hidden":
break;
case "checkbox":
case "radio":
input.checked = input.value == storedValue;
break;
default:
input.value = storedValue;
}
}
}

updateStorage(data) {
for (const item of data.entries()) {
if (!item[1]) {
Expand Down

0 comments on commit 5294980

Please sign in to comment.