diff --git a/README.md b/README.md index 9bee76e..7f8b587 100644 --- a/README.md +++ b/README.md @@ -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"`) diff --git a/src/index.ts b/src/index.ts index 541aa37..4cab310 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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 @@ -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 @@ -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) {