Reactの入力フォームを仮想ウインドウ化する
ユーザ入力用のUIの位置決めが面倒くさい
フロントエンドのUIを作る際、ユーザ入力を行うための場所をわざわざ作るのはそれなりに手間のかかる作業です。特に配置場所を作るのがそれなりに面倒です。今回はこれをできる限り簡単に解決する方法を解説していきたいと思います。
こちらの記事でToDoを入力するためのアプリケーションを作ったので、その入力フォームを改造していきます。
React-Reduxが難しい? それは過去の話だ! ~ ToDoアプリを最小限の労力で記述する ~
今回必要とするコンポーネント
https://www.npmjs.com/package/@jswf/react
インストールの方法
npm -D i @jswf/react
仮想ウインドウを利用する上でやるべき事
フォームの該当箇所をJSWindowで囲む
<JSWindow>~</JSWindow>
以上で入力フォームの仮想ウインドウ化は完了しました。お疲れ様です。
前回のプログラムを変更するとこんな感じです。
function FormComponent() {
const todoModule = useModule(TodoModule);
return (
<JSWindow>{/*←追加*/}
<div style={{ textAlign: "center" }}>
<div>
<div>タイトル</div>
<input
style={{ width: "20em" }}
value={todoModule.getState("input", "title")!}
onChange={e => todoModule.setState(e.target.value, "input", "title")}
/>
<div>説明</div>
<textarea
style={{ width: "20em", height: "5em" }}
value={todoModule.getState("input", "desc")!}
onChange={e => todoModule.setState(e.target.value, "input", "desc")}
/>
<div>
<button onClick={() => todoModule.addTodo()}>Todoを作成</button>
</div>
</div>
</div>
<JSWindow>{/*←追加*/}
);
}
足したのはJSWindowだけです。これによって、以下のように仮想ウインドウ上にコンテンツが表示されるようになりました。この仮想ウインドウはサイズが可変、移動、最大化、最小化の機能がデフォルトで付いています。
この仮想ウインドウ、閉じるボタンが搭載されているので押したら消えます。そして二度とToDOを書き込むことは出来なくなるという自由が手に出来てしまいます。
流石にそれでは困るので、閉じたウインドウを再び開けるようにします。
interface TodoState {
//入力中データの保持
input: {
title: string;
desc: string;
};
//TODOリスト
todos: {
id: number;
title: string;
desc: string;
done: boolean;
}[];
//TODOのID附番表index
index: number;
//ウインドウの状態
windowState: WindowState; //<----- 追加
}
//初期値
protected static defaultState: TodoState = {
todos: [],
input: { title: "", desc: "" },
index: 0,
windowState: WindowState.HIDE //<----- 初期状態の追加
};
function FormComponent() {
const todoModule = useModule(TodoModule);
return (
<>
{/* ボタンの追加 */}
<button
onClick={()=>todoModule.setState({ WindowState: WindowState.NORMAL })}
>
ウインドウの表示
</button>
{/* タイトルとウインドウ状態設定を追加 */}
<JSWindow title="ToDoの入力" windowState={todoModule.getState("WindowState")!}>
<div style={{ textAlign: "center" }}>
<div>
<div>タイトル</div>
<input
style={{ width: "20em" }}
value={todoModule.getState("input", "title")!}
onChange={e =>
todoModule.setState(e.target.value, "input", "title")
}
/>
<div>説明</div>
<textarea
style={{ width: "20em", height: "5em" }}
value={todoModule.getState("input", "desc")!}
onChange={e =>
todoModule.setState(e.target.value, "input", "desc")
}
/>
<div>
<button onClick={() => todoModule.addTodo()}>Todoを作成</button>
</div>
</div>
</div>
</JSWindow>
</>
);
}
windowStateを設定すると、仮想ウインドウの状態を変更することが出来ます。ということで、ボタンを押したらステータスをNORMALに戻し再表示出来るようになりました。
まとめ
この仮想ウインドウコンポーネントは複数表示やネストも可能です。詳細な機能に関しては
Reactで超簡単、タグで挟み込むだけの仮想ウインドウの実装
の記事で説明しています。