InputManJSでは、フォームデータを永続化して、再読み込みしてもフォームデータが失われないようにするクラスGcFormPersistenceを提供しています。
フォームの永続化
GcFormPersistenceクラスに永続化したいフォーム要素を指定し、persistメソッドを実行します。
GcFormPersistenceクラスではInputManJSが提供しているコントロールに加えて、以下のHTML標準の要素をサポートしています。
要素名
備考
input要素
type属性が以下の要素は保存されません button、file、password、reset、submit
select要素
textarea要素
またInputManJSのテキストコントロール(GcTextBox)でパスワード表示となっている時、データは保存されません。
保存のタイミングと保存先の設定
GcFormPersistenceクラスでは、saveModeプロパティを指定することで、データを保存するタイミングを設定することができます。
値
説明
SaveMode.SaveOnRefresh
ブラウザ更新時に保存します。
SaveMode.SaveOnSubmit
ブラウザ更新時とデータ送信時に保存します。
また、storageModeプロパティを指定することで、データの保存先を設定することができます。
値
説明
StorageMode.LocalStorage
ローカルストレージにデータを保存します。
StorageMode.SessionStorage
セッションストレージにデータを保存します。
サードパーティ製ライブラリのデータの永続化
GcFormPersistenceクラスではIThirdpartyEditorを設定することで、サードパーティ製ライブラリのデータを永続化することができます。
このデモでは一例としてWijmoのInputNumberのデータを永続化する方法を紹介しています。
またはサードパーティ製のライブラリのデータを保存したくない・保存する必要がない場合は、明示的にskipメソッドを実行する必要があります。
import * as React from "react";
import * as ReactDom from "react-dom";
import { GcDateTime, GcMask, GcNumber, GcTextBox } from "@mescius/inputman.react";
import { InputMan } from "@mescius/inputman";
import * as wjInput from '@mescius/wijmo.input';
import '@mescius/wijmo.styles/wijmo.css';
import '@mescius/inputman/CSS/gc.inputman-js.css';
import './license';
import './wijmoRule';
class App extends React.Component {
constructor() {
InputMan.appearanceStyle = InputMan.AppearanceStyle.Modern;
super();
}
get saveMode() { return this._saveMode }
set saveMode(newVal) {
this._saveMode = newVal;
this.fp.saveMode = newVal;
this.op.saveMode = newVal;
this.htmlfp.saveMode = newVal;
this.wjfp.saveMode = newVal;
}
get storageMode() { return this._storageMode }
set storageMode(newVal) {
this._storageMode = newVal;
this.fp.storageMode = newVal;
this.htmlfp.storageMode = newVal;
this.wjfp.storageMode = newVal;
}
componentDidMount() {
const theNumber = new wjInput.InputNumber('#theNumber');
//オプション要素の永続化を実行する
this.op = new GC.InputMan.GcFormPersistence(document.getElementById('op'));
this.op.persist();
this._saveMode = document.getElementById('onSubmit').checked ? InputMan.SaveMode.SaveOnSubmit : InputMan.SaveMode.SaveOnRefresh;
this._storageMode = document.getElementById('session').checked ? InputMan.StorageMode.SessionStorage : InputMan.StorageMode.LocalStorage;
//InputManJSフォームの永続化を実行する
this.fp = new GC.InputMan.GcFormPersistence(document.getElementById('imfm'), {
saveMode: this.saveMode,
storageMode: this.storageMode
});
this.fp.persist();
//wijmoフォームの永続化を実行する
this.wjfp = new GC.InputMan.GcFormPersistence(document.getElementById('wjfm'), {
saveMode: this.saveMode,
storageMode: this.storageMode
});
this.wjfp.persist();
//標準のHTML要素の永続化を実行する
this.htmlfp = new GC.InputMan.GcFormPersistence(document.getElementById('htmlfm'), {
saveMode: this.saveMode,
storageMode: this.storageMode
});
this.htmlfp.persist();
}
render() {
return <React.Fragment>
InputManJSコントロール:
<form id="imfm" action="" target="_parent">
<div class="flexbox">
<div>
テキストコントロール<br />
<GcTextBox name="gcTextBox" />
</div>
<div>
マスクコントロール<br />
<GcMask name="gcMask" formatPattern={"〒\\D{3}-\\D{4}"} />
</div>
<div>
数値コントロール<br />
<GcNumber name="gcNumber" />
</div>
<div>
日付時刻コントロール<br />
<GcDateTime name="gcDateTime" />
</div>
</div>
</form>
Wijmoコントロール:
<form id="wjfm">
InputNumber<br />
<div id="theNumber" name="number"></div>
</form>
<br />HTML入力要素:
<form id="htmlfm">
<input id="input" />
</form>
<form id="op">
<table class="sample">
<tr>
<th>保存するタイミング</th>
<td>
<label><input type="radio" id="onReload" value="0" name="saveMode" checked onChange={() => this.saveMode = InputMan.SaveMode.SaveOnRefresh} />ブラウザ更新時に保存する</label>
<label><input type="radio" id="onSubmit" value="1" name="saveMode" onChange={() => this.saveMode = InputMan.SaveMode.SaveOnSubmit} />データ送信時にも保存する</label>
</td>
</tr>
<tr>
<th>データの保存先</th>
<td>
<label><input type="radio" id="local" value="0" name="storageMode" checked onChange={() => this.storageMode = InputMan.StorageMode.LocalStorage} />ローカルストレージ</label>
<label><input type="radio" id="session" value="1" name="storageMode" onChange={() => this.storageMode = InputMan.StorageMode.SessionStorage} />セッションストレージ</label>
</td>
</tr>
</table>
</form>
<br />
<button type="button" onClick={() => window.parent.location.reload()}>ブラウザを更新する</button>
<input type="submit" form="imfm" value="フォームデータを送信する"></input>
</React.Fragment>
}
}
ReactDom.render(<App />, document.getElementById("app"));
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>基本機能 - フォーム永続化</title>
<!-- SystemJS -->
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
window.onload = function() {
System.import('./src/app');
}
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
//Wijmoの永続化を行うためのルール(IThirdpartyEditor)を設定します。
import * as wjcCore from '@mescius/wijmo';
import { InputMan } from '@mescius/inputman';
function WijmoRule() { }
WijmoRule.prototype = {
/**
* 要素をスキップする際の処理を設定します。
* @param {HTMLElement} element ホスト要素からのHtml要素
*/
skip: function (ele) {
//今回はスキップしたい要素はないのでfalseを設定します。
return false;
},
/**
* 要素がサードパーティのコントロールかどうかを判断し、
* そうである場合にストレージキーの利用するnameを設定する処理を定義します。
* @param {HTMLElement} element ホスト要素からのHtml要素
*/
checker: function (ele) {
//wijmoは常に最も外側の要素にクラスに「wj-control」を追加するため、
//以下の条件で要素がwijmoコントロールかどうかを確認できます。
if (ele.classList.contains("wj-control")) {
return ele.getAttribute("name");
}
return "";
},
/**
* ページの更新やフォームの送信時にコントロールの値をストレージに保存する際の処理を定義します。
* @param {ElementContext} context 現在のGcFormPersistence、現在の要素、要素名の情報
* interface ElementContext {
* formPersistence: GcFormPersistence;
* element: HTMLElement;
* name: string;
* }
*/
save: function (context) {
//最初にcontent.elementによってコントロールインスタンスを取得します。
var wijmo_control = wjcCore.Control.getControl(context.element);
//次にGcFormPersistenceのインスタンスを利用して、setValueメソッドで値を保存します。
//setValueの第1引数にはcheckerメソッドで設定したストレージキー名、
//第2引数はストレージに保存する値をそれぞれ指定します。
context.formPersistence.setValue(context.name, wijmo_control.value);
},
/**
* ページがロードされたときにストレージからコントロールの値を復元する際の処理を定義します。
* @param {ElementContext} context 現在のGcFormPersistence、現在の要素、要素名の情報
* interface ElementContext {
* formPersistence: GcFormPersistence;
* element: HTMLElement;
* name: string;
* }
*/
restore: function (context) {
//最初にcontent.elementによってコントロールインスタンスを取得します。
var wijmo_control = wjcCore.Control.getControl(context.element);
//次にGcFormPersistenceのインスタンスを利用して、getValueメソッドで値を取得します。
//getValueメソッドの引数は保存時に設定したストレージキー名を指定し、
//戻り値を復元したいコントロールインスタンスのプロパティに設定します。
wijmo_control.value = Number(context.formPersistence.getValue(context.name));
},
};
//registerEditorメソッドにWijmo永続化のルールを設定する
InputMan.GcFormPersistence.registerEditor(new WijmoRule());
(function (global) {
System.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true,
react: true,
},
meta: {
'*.css': { loader: 'css' },
},
paths: {
// paths serve as alias
'npm:': 'node_modules/',
},
// map tells the System loader where to look for things
map: {
'@mescius/inputman': 'npm:@mescius/inputman/index.js',
'@mescius/inputman.react': 'npm:@mescius/inputman.react/GcInputMan.component.js',
'@mescius/inputman/CSS': 'npm:@mescius/inputman/CSS',
'@mescius/inputman.comment': 'npm:@mescius/inputman.comment/index.js',
'@mescius/inputman.comment.react': 'npm:@mescius/inputman.comment.react/GcInputMan.component.js',
'@mescius/inputman.comment/CSS': 'npm:@mescius/inputman.comment/CSS',
'@mescius/inputman.richtexteditor': 'npm:@mescius/inputman.richtexteditor/index.js',
'@mescius/inputman.richtexteditor.react': 'npm:@mescius/inputman.richtexteditor.react/GcInputMan.component.js',
'@mescius/inputman.richtexteditor/CSS': 'npm:@mescius/inputman.richtexteditor/CSS',
'@mescius/inputman.richtexteditor/JS/plugins/advlist': 'npm:@mescius/inputman.richtexteditor/JS/plugins/advlist/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/all': 'npm:@mescius/inputman.richtexteditor/JS/plugins/all/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/autosave': 'npm:@mescius/inputman.richtexteditor/JS/plugins/autosave/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/charmap': 'npm:@mescius/inputman.richtexteditor/JS/plugins/charmap/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/directionality': 'npm:@mescius/inputman.richtexteditor/JS/plugins/directionality/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/emoticons': 'npm:@mescius/inputman.richtexteditor/JS/plugins/emoticons/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/fullscreen': 'npm:@mescius/inputman.richtexteditor/JS/plugins/fullscreen/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/htmlcode': 'npm:@mescius/inputman.richtexteditor/JS/plugins/htmlcode/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/image': 'npm:@mescius/inputman.richtexteditor/JS/plugins/image/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/link': 'npm:@mescius/inputman.richtexteditor/JS/plugins/link/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/lists': 'npm:@mescius/inputman.richtexteditor/JS/plugins/lists/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/media': 'npm:@mescius/inputman.richtexteditor/JS/plugins/media/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/pagebreak': 'npm:@mescius/inputman.richtexteditor/JS/plugins/pagebreak/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/preview': 'npm:@mescius/inputman.richtexteditor/JS/plugins/preview/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/save': 'npm:@mescius/inputman.richtexteditor/JS/plugins/save/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/searchreplace': 'npm:@mescius/inputman.richtexteditor/JS/plugins/searchreplace/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/table': 'npm:@mescius/inputman.richtexteditor/JS/plugins/table/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/template': 'npm:@mescius/inputman.richtexteditor/JS/plugins/template/plugin.js',
'@mescius/inputman.richtexteditor/JS/plugins/wordcount': 'npm:@mescius/inputman.richtexteditor/JS/plugins/wordcount/plugin.js',
'@mescius/wijmo.styles': 'npm:@mescius/wijmo.styles',
'@mescius/wijmo.cultures': 'npm:@mescius/wijmo.cultures',
'@mescius/wijmo.input': 'npm:@mescius/wijmo.input/index.js',
'@mescius/wijmo': 'npm:@mescius/wijmo/index.js',
'@mescius/wijmo.grid': 'npm:@mescius/wijmo.grid/index.js',
'@mescius/wijmo.nav': 'npm:@mescius/wijmo.nav/index.js',
'@mescius/wijmo.interop.grid': 'npm:@mescius/wijmo.interop.grid/index.js',
'@mescius/wijmo.react.grid': 'npm:@mescius/wijmo.react.grid/index.js',
'@mescius/wijmo.react.base': 'npm:@mescius/wijmo.react.base/index.js',
'@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js',
'@mescius/spread-sheets-resources-ja': 'npm:@mescius/spread-sheets-resources-ja/index.js',
'@mescius/spread-sheets/styles': 'npm:@mescius/spread-sheets/styles',
'react': 'npm:react/umd/react.production.min.js',
'react-dom': 'npm:react-dom/umd/react-dom.production.min.js',
'react-dom/client': 'npm:react-dom/umd/react-dom.production.min.js',
'css': 'npm:systemjs-plugin-css/css.js',
'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js',
'systemjs-babel-build': 'npm:systemjs-plugin-babel/systemjs-babel-browser.js',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
src: {
defaultExtension: 'jsx',
},
'node_modules': {
defaultExtension: 'js',
},
},
});
})(this);