Skip to content

Commit

Permalink
FormSaveController - Controller for persisting and restoring forms fr…
Browse files Browse the repository at this point in the history
…om LocalStorage
  • Loading branch information
Sub-Xaero committed Jan 25, 2021
1 parent 7b6bcb1 commit f91cec9
Show file tree
Hide file tree
Showing 27 changed files with 462 additions and 12 deletions.
1 change: 1 addition & 0 deletions dist/base_controller.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Context, Controller } from "stimulus";
export declare class BaseController extends Controller {
constructor(context: Context);
dispatch(element: HTMLElement, eventName: string, options?: CustomEventInit): void;
log(functionName: string, args?: {}): void;
}
//# sourceMappingURL=base_controller.d.ts.map
2 changes: 1 addition & 1 deletion dist/base_controller.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions dist/form_save_controller.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { BaseController } from './base_controller';
interface FormSavePayload {
[idx: string]: {
[idx: string]: string | boolean;
};
}
export declare class FormSaveController extends BaseController {
static values: {
id: StringConstructor;
restoreOnLoad: BooleanConstructor;
clearOnSubmit: BooleanConstructor;
};
readonly idValue: string;
readonly hasIdValue: boolean;
readonly restoreOnLoadValue: boolean;
readonly hasRestoreOnLoadValue: boolean;
readonly clearOnSubmitValue: boolean;
readonly hasClearOnSubmitValue: boolean;
get formID(): string;
get formIdentifier(): string;
get formElements(): HTMLFormControlsCollection;
get formData(): FormSavePayload;
get restoreOnLoad(): boolean;
get clearOnSubmit(): boolean;
initialize(): void;
connect(): void;
disconnect(): void;
_clear(): void;
clear(event?: Event): void;
save(event: Event): void;
restore(event?: Event): void;
}
export {};
//# sourceMappingURL=form_save_controller.d.ts.map
1 change: 1 addition & 0 deletions dist/form_save_controller.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export { DismissableController } from "./dismissable_controller";
export { EmptyDomController } from "./empty_dom_controller";
export { EnableInputsController } from "./enable_inputs_controller";
export { FallbackImageController } from "./fallback_image_controller";
export { FormSaveController } from "./form_save_controller";
export { LazyBlockController } from "./lazy_block_controller";
export { LimitedSelectionCheckboxesController } from "./limited_selection_checkboxes_controller";
export { NestedFormController } from "./nested_form_controller";
Expand Down
2 changes: 1 addition & 1 deletion dist/index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/stimulus-library.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/stimulus-library.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/stimulus-library.modern.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/stimulus-library.modern.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/stimulus-library.module.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/stimulus-library.module.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/stimulus-library.umd.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/stimulus-library.umd.js.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions dist/utilities/elements.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export declare function isHTMLLinkElement(element: Element): element is HTMLLinkElement;
export declare function isHTMLFormElement(element: Element): element is HTMLFormElement;
export declare function isHTMLInputElement(element: Element): element is HTMLInputElement;
//# sourceMappingURL=elements.d.ts.map
2 changes: 1 addition & 1 deletion dist/utilities/elements.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
** [EmptyDomController](./controllers/empty_dom_controller.md "Stimulus Library - EmptyDomController")
** [EnableInputsController](./controllers/enable_inputs_controller.md "Stimulus Library - EnableInputsController")
** [FallbackImageController](./controllers/fallback_image_controller.md "Stimulus Library - FallbackImageController")
** [FormSaveController](./controllers/form_save_controller.md "Stimulus Library - FormSaveController")
** [LazyBlockController](./controllers/lazy_block_controller.md "Stimulus Library - LazyBlockController")
** [LimitedSelectionCheckboxesController](./controllers/limited_selection_checkboxes_controller.md "Stimulus Library - LimitedSelectionCheckboxesController")
** [NestedFormController](./controllers/nested_form_controller.md "Stimulus Library - NestedFormController")
Expand Down
72 changes: 72 additions & 0 deletions docs/controllers/form_save_controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# FormSaveController

## Purpose

Save the value of a form and all of its inputs to LocalStorage, and restore it, at will.

<!-- tabs:start -->

## ** Actions **

#### [Actions](https://stimulus.hotwire.dev/reference/actions)

| Action | Purpose |
| --- | --- |
| `save` | Save the contents of the form to localstorage |
| `restore` | Restore the form to its previous state from localstorage |
| `clear` | Clear any saved state from localstorage |

## ** Targets **

#### [Targets](https://stimulus.hotwire.dev/reference/targets)

[no-targets](../_partials/no-targets.md ':include')

## ** Classes **

#### [Classes](https://stimulus.hotwire.dev/reference/classes)

[no-classes](../_partials/no-classes.md ':include')

## ** Values **

#### [Values](https://stimulus.hotwire.dev/reference/values)

| Value | Type | Description | Default |
| --- | --- | --- | --- |
| `id` | `String` | The unique ID of this form on the page. This combined with the current URL will allow multiple forms on the same page to all save. | The ID of the controller root element, or throw an error an ID is not found and this is not specified |
| `restoreOnLoad` | `Boolean` | Whether the controller should try to restore any previous state when the controller connects | true |
| `clearOnSubmit` | `Boolean` | Whether the controller should clean out the saved value when the form submits | true |

## ** Events **

#### Events

| Event | When | Dispatched on | `event.detail` |
| --- | --- | --- | --- |
| `form-save:cleared` | When the form is cleared, either by `submit` or when triggered by an action | The controller root element (the form) | - |
| `form-save:save:success` | When the form saves successfully | The controller root element (the form) | - |
| `form-save:restore:success` | When the form restores values successfully | The controller root element (the form) | - |
| `form-save:restore:empty` | When a restore is triggered, but there is nothing in localstorage to restore | The controller root element (the form) | - |



## ** Side Effects **

If the `clearOnSubmit` value is set to `true`, a `submit` event listener will be installed on the form.

<!-- tabs:end -->

# How to Use

<!-- tabs:start -->

## ** HTML **

[example](../examples/form_save_controller.html ':include :type=code')

## ** HAML **

[example](../examples/form_save_controller.haml ':include :type=code')
<!-- tabs:end -->

45 changes: 45 additions & 0 deletions docs/examples/form_save_controller.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
%form#test-form{ data: { controller: "form-save"}}
%div
%label
Name
%input{ type: "text", name: "name"}
%div
%label
Age
%input{ type: "number", name: "age"}
%div
%label
Quest
%textarea{ name: "quest"}
%div
%label
Do you like cake?
%input{ type: "checkbox", name: "gorilla"}
%br
%div
%p Favourite Ice Cream
%br
%label
Mint
%input{ type: "radio", name: "ice_cream", value: "Mint"}
%label
Chocolate
%input{ type: "radio", name: "ice_cream", value: "Chocolate"}
%label
Vanilla
%input{ type: "radio", name: "ice_cream", value: "Vanilla"}
%hr
%div
%a{ href: "", data: {action:"form-save#restore"}} Restore saved progress
%div
%a{ href: "", data: {action:"form-save#save"}} Save your progress

%div
%button{ type: "reset" } reset
%button{ type: "submit" } submit
56 changes: 56 additions & 0 deletions docs/examples/form_save_controller.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<form id="test-form" data-controller="form-save">
<div>
<label>
Name
<input type="text" name="name">
</label>
</div>
<div>
<label>
Age
<input type="number" name="age">
</label>
</div>
<div>
<label>
Quest
<textarea name="quest"></textarea>
</label>
</div>

<div>
<label>
Do you like cake?
<input type="checkbox" name="gorilla">
</label>
</div>
<br>
<div>
<p> Favourite Ice Cream</p>
<br>
<label>
Mint
<input type="radio" name="ice_cream" value="Mint">
</label>
<label>
Chocolate
<input type="radio" name="ice_cream" value="Chocolate">
</label>
<label>
Vanilla
<input type="radio" name="ice_cream" value="Vanilla">
</label>
</div>
<hr>

<div>
<a href="" data-action="form-save#restore">Restore saved progress</a>
</div>
<div>
<a href="" data-action="form-save#save">Save your progress</a>
</div>
<div>
<button type="reset"></button>
<button type="submit"></button>
</div>
</form>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "stimulus-library",
"description": "A library of useful controllers for Stimulus",
"version": "0.1.4",
"version": "0.1.5",
"license": "MIT",
"author": "@Sub-Xaero",
"repository": {
Expand Down
79 changes: 79 additions & 0 deletions playground/controllers/form_save_controller.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Stimulus Library Playground</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.css"/>
<script type="module" src="/index.js"></script>
</head>
<body>
<section class="section">
<div class="container">
<h1 class="title is-1">Stimulus Library</h1>
<div class="has-text-centered">
<a href="../index.html">Back</a>

<form id="test-form" data-controller="form-save">
<div>
<label>
Name
<input type="text" name="name">
</label>
</div>
<div>
<label>
Age
<input type="number" name="age">
</label>
</div>
<div>
<label>
Quest
<textarea name="quest"></textarea>
</label>
</div>

<div>
<label>
Do you like cake?
<input type="checkbox" name="gorilla">
</label>
</div>
<br>
<div>
<p> Favourite Ice Cream</p>
<br>
<label>
Mint
<input type="radio" name="ice_cream" value="Mint">
</label>
<label>
Chocolate
<input type="radio" name="ice_cream" value="Chocolate">
</label>
<label>
Vanilla
<input type="radio" name="ice_cream" value="Vanilla">
</label>
</div>
<hr>

<div>
<a href="" data-action="form-save#restore">Restore</a>
</div>
<div>
<a href="" data-action="form-save#save">Save</a>
</div>
<div>
<a href="" data-action="form-save#clear">Clear</a>
</div>
</form>
</div>
</div>
</section>


</body>
</html>
1 change: 1 addition & 0 deletions playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ <h1 class="title is-1">Stimulus Library</h1>
<div class="column is-one-third"><a href="./controllers/empty_dom_controller.html">EmptyDomController</a></div>
<div class="column is-one-third"><a href="./controllers/enable_inputs_controller.html">EnableInputsController</a></div>
<div class="column is-one-third"><a href="./controllers/fallback_image_controller.html">FallbackImageController</a></div>
<div class="column is-one-third"><a href="./controllers/form_save_controller.html">FormSaveController</a></div>
<div class="column is-one-third"><a href="./controllers/lazy_block_controller.html">LazyBlockController</a></div>
<div class="column is-one-third"><a href="./controllers/limited_selection_checks_controller.html">LimitedSelectionChecksController</a></div>
<div class="column is-one-third"><a href="./controllers/password_confirm_controller.html">PasswordConfirmController</a></div>
Expand Down
2 changes: 2 additions & 0 deletions playground/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
EmptyDomController,
EnableInputsController,
FallbackImageController,
FormSaveController,
LazyBlockController,
LimitedSelectionCheckboxesController,
PasswordConfirmController,
Expand Down Expand Up @@ -46,6 +47,7 @@ application.register("dismissable", DismissableController);
application.register("empty-dom", EmptyDomController);
application.register("enable-inputs", EnableInputsController);
application.register("fallback-image", FallbackImageController);
application.register("form-save", FormSaveController);
application.register("lazy-block", LazyBlockController);
application.register("limited-selection-checkboxes", LimitedSelectionCheckboxesController);
application.register("password-confirm", PasswordConfirmController);
Expand Down
Loading

0 comments on commit f91cec9

Please sign in to comment.