2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[JavaScript] フォームの内容を文字列化⇔復元する

Last updated at Posted at 2021-04-16

HTMLのフォームの内容を文字列化したり、その文字列を元にフォームの内容を復元する知見。

ソースコード

フォーム文字列化

第1引数にフォーム要素を渡します。戻り値はJSON文字列です。
idがある要素のみ文字列化されます。

文字列化
function form_toJSON(form){
    const json = {}

    for(const el of form.querySelectorAll('[id]')){
        if(['file','submit','reset'].includes(el.type)){
            continue
        }
        else if(el.type === 'checkbox' || el.type === 'radio'){
            json[el.id] = el.checked
        }
        else if(el.tagName === 'SELECT'){
            json[el.id] = {}
            for(const option of el.options){
                json[el.id][option.value] = option.selected
            }
        }
        else{
            json[el.id] = el.value
        }
    }

    return JSON.stringify(json)
}

フォーム復元化

第1引数にフォーム要素、第2引数にフォーム内容を文字列化したものを渡します。

復元化
function form_restore(form, json){
    json = JSON.parse(json ?? '{}')

    for(const el of form.querySelectorAll('[id]')){
        const value = json[el.id]

        if(value === undefined || ['file','submit','reset'].includes(el.type)){
            continue
        }
        else if(el.type === 'checkbox' || el.type === 'radio'){
            el.checked = value
        }
        else if(el.tagName === 'SELECT'){
            for(const option of el.options){
                if(option.value in value){
                    option.selected = value[option.value]
                }
            }
        }
        else{
            el.value = value
        }
    }
}

※主要なフォーム部品には対応したつもりですが、フォーム部品は多すぎて全てに対応できているかは不明です。非対応の部品があれば教えてくれると有難いです。

使用例

ページ離脱時にフォーム内容をセッションストレージに保存し、ページ読み込み時に復元するサンプル。

addEventListener('beforeunload', event => sessionStorage.setItem('sample', form_toJSON(form)))
addEventListener('DOMContentLoaded', event => form_restore(form, sessionStorage.getItem('sample')))

メモ

フォームの文字列化にあたって最初はFormDataを使っていたが、checkedやselectedがfalseの場合に文字列化されないという欠点があった。文字列化時と復元時でHTMLが同じならFormDataで十分だと思うけど、異なる場合を考慮すると現行の方が良いかなという感じです。

2
3
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?