前回は「Hello World」や基本的なDOM操作を学びました。今回はその続きとして、業務っぽいフォーム画面を題材に、実際に動くミニアプリ(フォーム+一覧)を作ってみます。
- HTMLとJavaScriptを分離(実務っぽい構成)
- 関数を整理して見通しよくする
- 入力チェック(必須・日付・範囲・整合性)
- 自動計算(残日数)・状態連動(完了日自動入力)
- 期限超過の行を赤表示(できるだけ業務感)
今回作る画面イメージ
画面はシンプルに、上が入力フォーム、下が一覧テーブルです。
- 登録日(デフォルトで今日)
- 作業内容(必須)
- 期限日(必須)
- 進捗率(%)(0〜100)
- ステータス(未着手/進行中/完了)
- 完了日(完了を選ぶと空なら自動で今日)
- 残日数(期限日−今日を自動計算)
- 期限超過(期限日が過ぎて未完了なら行を赤表示)
※編集・削除は次回以降に回します(今回は追加と表示に集中)。
ファイル構成(HTML/JS分離)
index.html:画面(フォーム+一覧)style.css:見た目(余白・表・赤表示など)app.js:動き(イベント、入力チェック、描画)
「HTMLに全部書く」のではなく、画面はHTML、動きはJSで分けておくと見通しが良くなります。業務でもこの形が多いので、練習としてもおすすめです。
Step1:まずはHTMLで“形”だけ作る(フォーム+一覧)
最初に、画面の部品(入力欄やテーブル)をHTMLで配置します。この時点では「動き」は不要で、見た目の箱だけ作るイメージです。
ポイントは、JavaScriptから操作しやすいように、各入力欄に id を付けておくことです(例:createdAt、title、dueDateなど)。
Step2:CSS/JSをHTMLから分離する(deferの意味)
次に、style.css と app.js を読み込みます。ここでのポイントが defer です。
<link rel="stylesheet" href="style.css" /> <script src="app.js" defer></script>
defer を付けると、HTMLの読み込みが完了してからJavaScriptが実行されます。DOM要素(入力欄など)がまだ無い状態で document.getElementById() を呼んでエラーになるのを避けやすいです。
Step3:初期化処理(init)で“最初の状態”を作る
実務っぽいコードにするため、まず init() という初期化関数を用意しました。ページを開いた瞬間にやりたい処理(初期値セット、イベント登録、初期描画)をここにまとめるイメージです。
- 登録日を今日にする
- ボタンや入力変更のイベントを登録する
- 一覧を初期描画する
「何がいつ動くか」が一箇所にまとまるので、あとで見返したときも理解しやすいです。
Step4:追加ボタンで“フォームの値を取得→チェック→一覧表示”する
今回のメインはここです。追加ボタンが押されたら、次の流れで処理します。
- フォームの値を取得(getFormValue)
- 自動入力・整形(normalizeTask)
- 入力チェック(validate)
- 問題なければ配列に追加(tasks.push)
- 一覧を再描画(renderTable)
- フォームを初期化(resetForm)
最初は「全部onAddに書けばよくない?」と思いましたが、関数を分けた方が読みやすく、あとから機能追加もしやすいと感じました(次回の編集・削除にも繋げやすいです)。
Step5:入力チェック(validate)を“1つの関数にまとめる”
業務画面っぽくするなら、入力チェックは必須です。今回は validate() が エラーメッセージ配列を返す方式にしました。
チェックした内容は次の通りです。
- 必須チェック:作業内容、期限日
- 日付チェック:登録日、期限日、完了日(YYYY-MM-DD)
- 期間チェック:登録日 ≤ 期限日
- 数値チェック:進捗率は0〜100の整数
- 整合性チェック:完了なら完了日が必要、未完了なら完了日は空
エラーがある場合は一覧に追加せず、エラー欄にまとめて表示するようにしました。実際の業務でも「エラーが1件ずつ出るより、まとめて出た方が直しやすい」ケースが多い気がします。
Step6:自動入力・自動計算(完了日・残日数)
ここが「業務っぽさ」を出すポイントでした。
ステータスが完了なら完了日を自動入力
ステータスを「完了」にしたとき、完了日が空なら今日を自動セットします。逆に未完了に戻したら完了日を空にします(仕様としてそうしました)。
期限日から残日数を自動計算
期限日が入力されたら、期限日−今日で残日数を計算して表示します。期限が過ぎている場合はマイナスになります。
このあたりは「JavaScriptで計算して画面に反映する」という練習にもなりました。
Step7:期限超過の行を赤表示にする
業務画面だと「期限超過」を目立たせたい場面が多いので、今回は 期限日が過ぎていて、完了ではない行を赤くしました。
実装としては、期限超過判定(isOverdue())を作って、該当する行に overdue クラスを付け、CSSで背景色を変えています。
tr.overdue { background: #ffe8e8; }
「条件を判定してCSSクラスを付ける」だけで、それっぽい業務UIになるのが面白かったです。
完成ソース(コピペ用)
ソースファイル githubのソースリンク
まとめ
- HTML/JS分離でコードが見やすくなった
- 追加処理を関数分割して整理できた
- 業務っぽい入力チェック(必須・日付・範囲・整合性)ができた
- 完了日自動入力や残日数計算で、画面が“それっぽく”なった
- 期限超過を赤表示にすると分かりやすい
次回やりたいこと
- 一覧の「編集」「削除」機能を追加する
- LocalStorageに保存してページを更新しても残す
- 期限日やステータスでフィルタ・ソートを付ける


コメント