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/examples/index.html b/examples/index.html
new file mode 100644
index 0000000..bfa0126
--- /dev/null
+++ b/examples/index.html
@@ -0,0 +1,87 @@
+
+
+
+
+ session-resume demo
+
+
+
+ session-resume
+
+ Test by filling out the form and then refreshing the page or navigating away and back.
+
+
+
+
+
+
diff --git a/src/index.ts b/src/index.ts
index 2852d45..4cab310 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -6,7 +6,11 @@ function shouldResumeField(field: HTMLInputElement | HTMLTextAreaElement, filter
}
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
@@ -29,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
@@ -112,7 +126,10 @@ 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.value === field.defaultValue) {
+ if (isHTMLCheckableInputElement(field)) {
+ field.checked = !field.defaultChecked
+ changedFields.push(field)
+ } else if (field.value === field.defaultValue) {
field.value = value
changedFields.push(field)
}
diff --git a/test/test.js b/test/test.js
index adcf236..cd91d95 100644
--- a/test/test.js
+++ b/test/test.js
@@ -6,8 +6,11 @@ describe('session-resume', function () {
// eslint-disable-next-line github/no-inner-html
document.body.innerHTML = `
`
window.addEventListener('submit', sessionStorage.setForm, {capture: true})
@@ -15,11 +18,21 @@ describe('session-resume', function () {
describe('restoreResumableFields', function () {
it('restores fields values from session storage by default', function () {
- sessionStorage.setItem('session-resume:test-persist', JSON.stringify([['my-first-field', 'test2']]))
+ sessionStorage.setItem(
+ 'session-resume:test-persist',
+ JSON.stringify([
+ ['my-first-field', 'test2'],
+ ['my-first-checkbox', 'first-checkbox-value'],
+ ['my-checked-checkbox', 'checked-checkbox-value']
+ ])
+ )
restoreResumableFields('test-persist')
assert.equal(document.querySelector('#my-first-field').value, 'test2')
assert.equal(document.querySelector('#my-second-field').value, 'second-field-value')
+ assert.equal(document.querySelector('#my-first-checkbox').checked, true)
+ assert.equal(document.querySelector('#my-second-checkbox').checked, false)
+ assert.equal(document.querySelector('#my-checked-checkbox').checked, false)
})
it('uses a Storage object when provided as an option', function () {
@@ -84,8 +97,8 @@ describe('session-resume', function () {
assert.deepEqual(fieldsRestored, {'my-first-field': 'test2'})
})
- it('fires off change for changed fields', function (done) {
- for (const input of document.querySelectorAll('input')) {
+ it('fires off change for changed input[type=text] fields', function (done) {
+ for (const input of document.querySelectorAll('input[type=text]')) {
input.addEventListener('change', function (event) {
done(assert.equal(event.target.id, 'my-first-field'))
})
@@ -94,6 +107,20 @@ describe('session-resume', function () {
sessionStorage.setItem('session-resume:test-persist', JSON.stringify([['my-first-field', 'test2']]))
restoreResumableFields('test-persist')
})
+
+ it('fires off change for changed input[type=checkbox] fields', function (done) {
+ for (const input of document.querySelectorAll('input[type=checkbox]')) {
+ input.addEventListener('change', function (event) {
+ done(assert.equal(event.target.id, 'my-first-checkbox'))
+ })
+ }
+
+ sessionStorage.setItem(
+ 'session-resume:test-persist',
+ JSON.stringify([['my-first-checkbox', 'first-checkbox-value']])
+ )
+ restoreResumableFields('test-persist')
+ })
})
describe('persistResumableFields', function () {
@@ -102,7 +129,7 @@ describe('session-resume', function () {
document.querySelector('#my-second-field').value = 'test2'
persistResumableFields('test-persist')
- assert.deepEqual(JSON.parse(sessionStorage.getItem('session-resume:test-persist')), [
+ assert.includeDeepMembers(JSON.parse(sessionStorage.getItem('session-resume:test-persist')), [
['my-first-field', 'test1'],
['my-second-field', 'test2']
])
@@ -124,7 +151,7 @@ describe('session-resume', function () {
persistResumableFields('test-persist', {storage: fakeStorage})
- assert.deepEqual(JSON.parse(fakeStorage.getItem('session-resume:test-persist')), [
+ assert.includeDeepMembers(JSON.parse(fakeStorage.getItem('session-resume:test-persist')), [
['my-first-field', 'test1'],
['my-second-field', 'test2']
])
@@ -137,7 +164,7 @@ describe('session-resume', function () {
persistResumableFields('test-persist')
- assert.deepEqual(JSON.parse(sessionStorage.getItem('session-resume:test-persist')), [
+ assert.includeDeepMembers(JSON.parse(sessionStorage.getItem('session-resume:test-persist')), [
['my-first-field', 'test1'],
['my-second-field', 'test2'],
['non-existant-field', 'test3']
@@ -151,7 +178,7 @@ describe('session-resume', function () {
persistResumableFields('test-persist')
- assert.deepEqual(JSON.parse(sessionStorage.getItem('session-resume:test-persist')), [
+ assert.includeDeepMembers(JSON.parse(sessionStorage.getItem('session-resume:test-persist')), [
['my-first-field', 'test1'],
['my-second-field', 'test2']
])