Skip to content

Commit 909d41c

Browse files
committed
Incorporate checkables into storageFilter:
1 parent f20740a commit 909d41c

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ The `restoreResumableFields(id: string, options)` function supports optional con
6161
The `persistResumableFields(id: string, options)` function supports optional configurations:
6262

6363
* `storage:` - [`Storage`][] instance (defaults to [`window.sessionStorage`][])
64-
* `storageFilter:` - `(field: HTMLInputElement | HTMLTextAreaElement) => boolean` predicate to determine whether or not to store a field (defaults to `(field) => field.value !== field.defaultValue`)
64+
* `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)
6565
* `keyPrefix:` - `string` prepended onto the storage key (defaults to `"session-resume"`)
6666
* `scope:` - `ParentNode` used to query field elements (defaults to `document`)
6767
* `selector:` - `string` used to query field elements (defaults to `".js-session-resumable"`)

src/index.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@
22
let submittedForm: HTMLFormElement | null = null
33

44
function shouldResumeField(field: HTMLInputElement | HTMLTextAreaElement, filter: StorageFilter): boolean {
5-
return (
6-
!!field.id &&
7-
(field.value !== field.defaultValue ||
8-
(field instanceof HTMLInputElement && field.checked !== field.defaultChecked)) &&
9-
field.form !== submittedForm
10-
)
5+
return !!field.id && filter(field) && field.form !== submittedForm
116
}
127

138
function valueIsUnchanged(field: HTMLInputElement | HTMLTextAreaElement): boolean {
14-
return field.value !== field.defaultValue
9+
if (isHTMLCheckableInputElement(field)) {
10+
return field.checked !== field.defaultChecked
11+
} else {
12+
return field.value !== field.defaultValue
13+
}
1514
}
1615

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

36+
type HTMLCheckableInputElement = HTMLInputElement & {
37+
type: 'checkbox' | 'radio'
38+
}
39+
40+
function isHTMLCheckableInputElement(
41+
field: HTMLInputElement | HTMLTextAreaElement
42+
): field is HTMLCheckableInputElement {
43+
return field instanceof HTMLInputElement && /checkbox|radio/.test(field.type)
44+
}
45+
3746
// Write all ids and values of the selected fields on the page into sessionStorage.
3847
export function persistResumableFields(id: string, options?: PersistOptions): void {
3948
const scope = options?.scope ?? document
@@ -117,7 +126,7 @@ export function restoreResumableFields(id: string, options?: RestoreOptions): vo
117126
if (document.dispatchEvent(resumeEvent)) {
118127
const field = document.getElementById(fieldId)
119128
if (field && (field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement)) {
120-
if (field instanceof HTMLInputElement && (field.type === 'checkbox' || field.type === 'radio')) {
129+
if (isHTMLCheckableInputElement(field)) {
121130
field.checked = !field.defaultChecked
122131
changedFields.push(field)
123132
} else if (field.value === field.defaultValue) {

test/test.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ describe('session-resume', function () {
9797
assert.deepEqual(fieldsRestored, {'my-first-field': 'test2'})
9898
})
9999

100-
it('fires off change for changed fields', function (done) {
101-
for (const input of document.querySelectorAll('input')) {
100+
it('fires off change for changed input[type=text] fields', function (done) {
101+
for (const input of document.querySelectorAll('input[type=text]')) {
102102
input.addEventListener('change', function (event) {
103103
done(assert.equal(event.target.id, 'my-first-field'))
104104
})
@@ -107,6 +107,20 @@ describe('session-resume', function () {
107107
sessionStorage.setItem('session-resume:test-persist', JSON.stringify([['my-first-field', 'test2']]))
108108
restoreResumableFields('test-persist')
109109
})
110+
111+
it('fires off change for changed input[type=checkbox] fields', function (done) {
112+
for (const input of document.querySelectorAll('input[type=checkbox]')) {
113+
input.addEventListener('change', function (event) {
114+
done(assert.equal(event.target.id, 'my-first-checkbox'))
115+
})
116+
}
117+
118+
sessionStorage.setItem(
119+
'session-resume:test-persist',
120+
JSON.stringify([['my-first-checkbox', 'first-checkbox-value']])
121+
)
122+
restoreResumableFields('test-persist')
123+
})
110124
})
111125

112126
describe('persistResumableFields', function () {

0 commit comments

Comments
 (0)