Spread.SheetsとInputManJSをReact上で連携させる
応用例として、Reactに組み込んだSpread.SheetsとInputManJSを、React上で連携させるサンプル(図4)を説明します。フォームに代表者名と人数を入力して反映ボタンをクリックすると、入力内容がスプレッドシートに追記されます。なお、人数欄の数値コントロールには、「人」の接尾辞や数値の範囲(1~10)を設定しています。詳細はサンプルコードを参照してください。
サンプルの要点を以下で説明します。まず、Appクラスのコンストラクターでは、リスト11の通りstateを初期設定します。(1)と(2)がInputManJSのコントロール、(3)がSpread.Sheetsのスプレッドシートに表示されます。なお、(3)には1件分のデータを初期設定しています。
this.state = { personName: '', // テキストコントロール(代表者)の値 ...(1) personCount: 1, // 数値コントロール(人数)の値 ...(2) data: [ // Spread.Sheetsに表示する値 ...(3) { personName: '山田太郎', personCount: 2, logTime: new Date() } ] };
入力フォームの反映ボタン押下時に実行する処理は、リスト12の通りです。
applyValueToSpreadSheets() { // 検証コントロール ...(1) if (!this.validator.validate()) { return; } // 既存データに行を追加 ...(2) var newData = [].concat(this.state.data, [ { personName: this.state.personName, personCount: this.state.personCount, logTime: new Date() } ]); // state更新 ...(3) this.setState({ data: newData, // データを更新 ...(4) personName: '', // InputManJSコントロールを初期値に戻す ...(5) personCount: 1, }); }
(1)で入力内容を検証後(詳細は後述)、(2)で、InputManJSコントロールの入力値と現在時刻をデータ配列(this.state.data)の末尾に追加した新しいデータ配列newDataを作成します。(3)はstate更新処理で、(4)でnewDataを設定してSpread.Sheetsを更新する一方、(5)でInputManJSコントロールを初期値に戻してフォームを初期化します。
図4のサンプルで利用されているSpread.SheetsやInputManJSの機能について、以下の補足も参考にしてください。
[補足]Spread.Sheetsに数式を設定
図4のサンプルでは、スプレッドシートの1行目右端に「累積人数」が表示されます。この処理は、リスト13の処理でセルに数式を設定して実現しています。
<SpreadSheets workbookInitialized={this.spreadSheetsWorkbookInitialized}> (略) spreadSheetsWorkbookInitialized(spread) { if (spread) { var sheet = spread.getActiveSheet(); // ワークシートを取得 ...(1) sheet.setFormula(0, 3, '=sum(C:C)'); // C列の合計を表す数式を設定 ...(2) } }
ワークシート初期化後に実行されるSpreadSheetsタグのworkbookInitializedイベントに設定したthis.spreadSheetsWorkbookInitializedメソッド内で、スプレッドシートに対応するspread変数から、(1)でワークシートを取得して、(2)のsetFormulaメソッドで(0, 3)=1行4列目のセルに、C列(人数)の合計値に対応する数式を設定します。
[補足]Spread.SheetsのautoGenerateColumns設定
図4のサンプルでは、Spread.Sheetsの<WorkSheets>タグで、autoGenerateColumnsをfalseに設定しています。
<Worksheet name="来訪者" dataSource={this.state.data} autoGenerateColumns={false}> <Column (略)/> (略) </Worksheet>
autoGenerateColumnsは、データ設定時に列を自動的に生成する設定です。デフォルトのtrueでは、setStateメソッドでデータが更新されてSpread.Sheetsに設定されるたび、<Column>タグで記述した列が消えて列が再生成されるため、最初に指定した列幅の設定が消えてしまいます。このサンプルではデータ更新時に列幅を維持するため、autoGenerateColumnsをfalseに設定しています。
[補足]InputManJSの検証コントロール
図4のサンプルでは、代表者のテキストコントロールに、入力必須の検証コントロールを設定しています。検証コントロールは2018年10月のアップデートで追加されたInputManJSの新機能です。詳細は過去記事を参照してください。
React環境でInputManJSの検証コントロールを利用するには、まず、検証するコントロールを参照する変数(ref)を作成します。Reactが提供するcreateRefメソッドで作成した変数を、コントロールに対応するタグのref属性に設定します(リスト15)。この場合、テキストコントロール(GcTextBox)を参照するthis.gcTextBox変数が作成されます。
this.gcTextBox = React.createRef(); (略) <GcTextBox ref={this.gcTextBox}(略)/>
次に、AppコンポーネントがDOMツリーに追加されたときに実行されるcomponentDidMountメソッドで、リスト16の通り検証コントロールを作成します。リスト15で作成したthis.gcTextBox変数の「current.imControl」プロパティを、検証対象としてcontrolに指定します(1)。「current」はcreateRefメソッドで作成した変数から参照先を取得するReactのプロパティ、「imControl」はコントロールを取得するInputManJSのプロパティです。
componentDidMount() { this.validator = new InputMan.GcValidator({ items: [ { control: this.gcTextBox.current.imControl, // ...(1) (略) }
ここで作成したthis.validatorを利用して、リスト12(1)で検証を行います。
まとめ
本記事では、グレープシティのJavaScriptライブラリSpreadJSとInputManJSを、Reactと組み合わせて利用する方法を説明しました。Reactと組み合わせることで、各ライブラリのコントロールをReactのコンポーネントとして活用できます。応用として、Reactを仲立ちとして、SpreadJSとInputManJSを連携して動作させるサンプルを紹介しました。