Skip to content

Commit

Permalink
Incorporate checkables into storageFilter:
Browse files Browse the repository at this point in the history
  • Loading branch information
seanpdoyle committed Jan 26, 2024
1 parent f20740a commit 0ef195d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ The `restoreResumableFields(id: string, options)` function supports optional con
The `persistResumableFields(id: string, options)` function supports optional configurations:

* `storage:` - [`Storage`][] instance (defaults to [`window.sessionStorage`][])
* `storageFilter:` - `(field: HTMLInputElement | HTMLTextAreaElement) => boolean` predicate to determine whether or not to store a field (defaults to `(field) => field.value !== field.defaultValue`)
* `storageFilter:` - `(field: HTMLInputElement | HTMLTextAreaElement) => boolean` predicate to determine whether or not to store a field (defaults to `(field) => field.checked !== field.defaultChecked)` for checkbox and radio buttons, `(field) => field.value !== field.defaultValue` otherwise)
* `keyPrefix:` - `string` prepended onto the storage key (defaults to `"session-resume"`)
* `scope:` - `ParentNode` used to query field elements (defaults to `document`)
* `selector:` - `string` used to query field elements (defaults to `".js-session-resumable"`)
Expand Down
25 changes: 17 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@
let submittedForm: HTMLFormElement | null = null

function shouldResumeField(field: HTMLInputElement | HTMLTextAreaElement, filter: StorageFilter): boolean {
return (
!!field.id &&
(field.value !== field.defaultValue ||
(field instanceof HTMLInputElement && field.checked !== field.defaultChecked)) &&
field.form !== submittedForm
)
return !!field.id && filter(field) && field.form !== submittedForm
}

function valueIsUnchanged(field: HTMLInputElement | HTMLTextAreaElement): boolean {
return field.value !== field.defaultValue
if (isHTMLCheckableInputElement(field)) {
return field.checked !== field.defaultChecked
} else {
return field.value !== field.defaultValue
}
}

type StorageFilter = (field: HTMLInputElement | HTMLTextAreaElement) => boolean
Expand All @@ -34,6 +33,16 @@ type PersistOptions = (PersistOptionsWithSelector | PersistOptionsWithFields) &
storageFilter?: StorageFilter
}

type HTMLCheckableInputElement = HTMLInputElement & {
type: 'checkbox' | 'radio'
}

function isHTMLCheckableInputElement(
field: HTMLInputElement | HTMLTextAreaElement
): field is HTMLCheckableInputElement {
return field instanceof HTMLInputElement && /checkbox|radio/.test(field.type)
}

// Write all ids and values of the selected fields on the page into sessionStorage.
export function persistResumableFields(id: string, options?: PersistOptions): void {
const scope = options?.scope ?? document
Expand Down Expand Up @@ -117,7 +126,7 @@ export function restoreResumableFields(id: string, options?: RestoreOptions): vo
if (document.dispatchEvent(resumeEvent)) {
const field = document.getElementById(fieldId)
if (field && (field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement)) {
if (field instanceof HTMLInputElement && (field.type === 'checkbox' || field.type === 'radio')) {
if (isHTMLCheckableInputElement(field)) {
field.checked = !field.defaultChecked
changedFields.push(field)
} else if (field.value === field.defaultValue) {
Expand Down

0 comments on commit 0ef195d

Please sign in to comment.