JavaScript | 1 日 30 分 × 7 日アプリ学習超初級編:文字を表示するアプリ

JavaScript
スポンサーリンク

7日目のゴール

7日目のキーワードも変わらず
「画面を書き換える」 ですが、今日はまとめの日です。

ここまでであなたはすでに

入力した文字を表示する
ボタンでメッセージを切り替える
モードによって表示内容を変える
履歴を一覧として表示する
データと表示を分けて考える

というところまで来ています。

7日目では、これらをひとつにまとめて

「自分用の小さなメッセージビューアアプリ」を完成させる
コードを少し整理して「読みやすい形」に近づける

ここまで行きます。


今日作る最終ミニアプリのイメージ

「タグ付きメッセージビューア」

今日のアプリは、こんなイメージです。

メッセージと「タグ」(種類)を入力して追加する
タグは「メモ」「ポジティブ」「ネガティブ」などから選ぶ
履歴には「タグ+メッセージ」が一覧で表示される
表示モードで「全部」「ポジティブだけ」「ネガティブだけ」を切り替えられる

つまり、

データとしては「タグ付きメッセージの一覧」を持ち
画面では「どのタグを表示するか」を切り替える

という、かなり“アプリっぽい”構成になります。


HTML を組み立てる

入力欄・タグ選択・表示モード・履歴

まずは HTML 全体を用意します。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>文字を表示するアプリ 7日目</title>
</head>
<body>
    <h1>タグ付きメッセージビューア</h1>

    <h2>メッセージ入力</h2>
    <p>メッセージとタグを入力して「追加」ボタンを押してください。</p>

    <input id="messageInput" type="text" placeholder="メッセージを入力">

    <select id="tagSelect">
        <option value="memo">メモ</option>
        <option value="positive">ポジティブ</option>
        <option value="negative">ネガティブ</option>
    </select>

    <button id="addButton">追加</button>
    <button id="clearButton">全部消す</button>

    <h2>表示モード</h2>
    <p id="modeDisplay">現在のモード:すべて表示</p>
    <button id="showAllButton">すべて表示</button>
    <button id="showPositiveButton">ポジティブだけ</button>
    <button id="showNegativeButton">ネガティブだけ</button>

    <h2>メッセージ一覧</h2>
    <div id="historyArea">
        <p>まだメッセージはありません。</p>
    </div>

    <script src="app.js"></script>
</body>
</html>

ここで新しく出てきたのは <select><option> です。

タグを選ぶためのプルダウンメニューで
id="tagSelect" をつけているので、JavaScript から value を読めます。

表示モードは、6日目と同じように
「モード表示」と「モード切り替えボタン」で構成しています。


JavaScript の土台を作る

要素取得と「データの形」を決める

app.js に、まずは要素取得を書きます。

const messageInputElement = document.getElementById("messageInput");
const tagSelectElement = document.getElementById("tagSelect");
const addButtonElement = document.getElementById("addButton");
const clearButtonElement = document.getElementById("clearButton");

const modeDisplayElement = document.getElementById("modeDisplay");
const showAllButtonElement = document.getElementById("showAllButton");
const showPositiveButtonElement = document.getElementById("showPositiveButton");
const showNegativeButtonElement = document.getElementById("showNegativeButton");

const historyAreaElement = document.getElementById("historyArea");
JavaScript

次に、「データの形」を決めます。

7日目では、メッセージを「文字列」ではなく
「メッセージ+タグ」のセットとして扱います。

const messages = [];

// 表示モード
// "all" / "positive" / "negative"
let currentMode = "all";
JavaScript

messages 配列には、こんな形のオブジェクトを入れていきます。

{
    text: "メッセージの中身",
    tag: "positive"  // または "memo" / "negative"
}
JavaScript

この「オブジェクトの配列」という形が
現実のアプリにかなり近いデータの持ち方です。


「画面を描き直す」関数を作る

タグとモードを見て、表示するかどうかを決める

6日目と同じように、
「履歴を画面に描くのはこの関数だけ」という形にします。

function renderHistory() {
    if (messages.length === 0) {
        historyAreaElement.innerHTML = "<p>まだメッセージはありません。</p>";
        return;
    }

    historyAreaElement.textContent = "";

    for (let i = 0; i < messages.length; i++) {
        const message = messages[i];

        if (currentMode === "positive" && message.tag !== "positive") {
            continue;
        }

        if (currentMode === "negative" && message.tag !== "negative") {
            continue;
        }

        const p = document.createElement("p");

        let tagLabel = "";
        if (message.tag === "memo") {
            tagLabel = "[メモ]";
        } else if (message.tag === "positive") {
            tagLabel = "[ポジティブ]";
        } else if (message.tag === "negative") {
            tagLabel = "[ネガティブ]";
        }

        p.textContent = tagLabel + " " + message.text;

        historyAreaElement.appendChild(p);
    }
}
JavaScript

ここでの流れを丁寧に見ていきます。

messages.length が 0 のとき
まだ何もないので、いつもの「まだメッセージはありません。」を表示して終わりです。

historyAreaElement.textContent = “”
いったん中身を全部消してから、
今のモードに合わせて描き直します。

for ループで messages を先頭から順に見る
const message = messages[i];
「i番目のメッセージオブジェクト」を取り出しています。

currentMode が “positive” のとき
タグが “positive” 以外のものは continue; でスキップします。
つまり、「ポジティブ以外は表示しない」ということです。

currentMode が “negative” のときも同様に
“negative” 以外はスキップします。

currentMode が “all” のときは
どのタグでもスキップされないので、全部表示されます。

タグのラベルを作る部分では
tag の値に応じて [メモ] などの文字を決めています。

最後に p.textContent
「タグラベル+メッセージ本文」を入れて
historyArea に appendChild しています。

ここで重要なのは、

データ(messages 配列)は一切削らない
「今のモードで表示すべきものだけを画面に出す」

という考え方です。


メッセージを追加する処理を書く

入力欄とタグ選択からオブジェクトを作る

次に、「追加」ボタンの処理を書きます。

addButtonElement.addEventListener("click", function () {
    const text = messageInputElement.value;
    const tag = tagSelectElement.value;

    if (text === "") {
        alert("メッセージが空です。何か入力してください。");
        return;
    }

    const message = {
        text: text,
        tag: tag
    };

    messages.push(message);

    messageInputElement.value = "";
    messageInputElement.focus();

    renderHistory();
});
JavaScript

ここでのポイントは「オブジェクトを作る」部分です。

text は入力欄から
tag は <select> の value から

それぞれ取り出して、
{ text: text, tag: tag } という形のオブジェクトにしています。

このオブジェクトを messages 配列に push してから
renderHistory で画面を描き直します。


「全部消す」処理を書く

データも画面も初期状態に戻す

「全部消す」ボタンの処理はシンプルです。

clearButtonElement.addEventListener("click", function () {
    messages.length = 0;
    renderHistory();
});
JavaScript

messages 配列を空にしてから
renderHistory を呼ぶことで、
画面も「まだメッセージはありません。」に戻ります。


表示モードを切り替える処理を書く

状態を変えてから、画面を描き直す

4日目・6日目と同じパターンで
表示モードの切り替えを書きます。

まずはモード表示を更新する関数です。

function updateModeDisplay() {
    if (currentMode === "all") {
        modeDisplayElement.textContent = "現在のモード:すべて表示";
    } else if (currentMode === "positive") {
        modeDisplayElement.textContent = "現在のモード:ポジティブだけ";
    } else if (currentMode === "negative") {
        modeDisplayElement.textContent = "現在のモード:ネガティブだけ";
    }
}
JavaScript

次に、ボタンのイベントを登録します。

showAllButtonElement.addEventListener("click", function () {
    currentMode = "all";
    updateModeDisplay();
    renderHistory();
});

showPositiveButtonElement.addEventListener("click", function () {
    currentMode = "positive";
    updateModeDisplay();
    renderHistory();
});

showNegativeButtonElement.addEventListener("click", function () {
    currentMode = "negative";
    updateModeDisplay();
    renderHistory();
});
JavaScript

これで、

モードボタンを押す
currentMode が変わる
モード表示が変わる
renderHistory で「そのモードに合うメッセージだけ」が表示される

という流れになります。


7日目の app.js をまとめて見る

全体像を通して確認する

ここまでのコードを一つにまとめると、こうなります。

const messageInputElement = document.getElementById("messageInput");
const tagSelectElement = document.getElementById("tagSelect");
const addButtonElement = document.getElementById("addButton");
const clearButtonElement = document.getElementById("clearButton");

const modeDisplayElement = document.getElementById("modeDisplay");
const showAllButtonElement = document.getElementById("showAllButton");
const showPositiveButtonElement = document.getElementById("showPositiveButton");
const showNegativeButtonElement = document.getElementById("showNegativeButton");

const historyAreaElement = document.getElementById("historyArea");

// メッセージの配列(text と tag を持つオブジェクト)
const messages = [];

// 表示モード:"all" / "positive" / "negative"
let currentMode = "all";

// 履歴を画面に描き直す
function renderHistory() {
    if (messages.length === 0) {
        historyAreaElement.innerHTML = "<p>まだメッセージはありません。</p>";
        return;
    }

    historyAreaElement.textContent = "";

    for (let i = 0; i < messages.length; i++) {
        const message = messages[i];

        if (currentMode === "positive" && message.tag !== "positive") {
            continue;
        }

        if (currentMode === "negative" && message.tag !== "negative") {
            continue;
        }

        const p = document.createElement("p");

        let tagLabel = "";
        if (message.tag === "memo") {
            tagLabel = "[メモ]";
        } else if (message.tag === "positive") {
            tagLabel = "[ポジティブ]";
        } else if (message.tag === "negative") {
            tagLabel = "[ネガティブ]";
        }

        p.textContent = tagLabel + " " + message.text;

        historyAreaElement.appendChild(p);
    }
}

// モード表示を更新する
function updateModeDisplay() {
    if (currentMode === "all") {
        modeDisplayElement.textContent = "現在のモード:すべて表示";
    } else if (currentMode === "positive") {
        modeDisplayElement.textContent = "現在のモード:ポジティブだけ";
    } else if (currentMode === "negative") {
        modeDisplayElement.textContent = "現在のモード:ネガティブだけ";
    }
}

// メッセージ追加
addButtonElement.addEventListener("click", function () {
    const text = messageInputElement.value;
    const tag = tagSelectElement.value;

    if (text === "") {
        alert("メッセージが空です。何か入力してください。");
        return;
    }

    const message = {
        text: text,
        tag: tag
    };

    messages.push(message);

    messageInputElement.value = "";
    messageInputElement.focus();

    renderHistory();
});

// 全部消す
clearButtonElement.addEventListener("click", function () {
    messages.length = 0;
    renderHistory();
});

// 表示モード切り替え
showAllButtonElement.addEventListener("click", function () {
    currentMode = "all";
    updateModeDisplay();
    renderHistory();
});

showPositiveButtonElement.addEventListener("click", function () {
    currentMode = "positive";
    updateModeDisplay();
    renderHistory();
});

showNegativeButtonElement.addEventListener("click", function () {
    currentMode = "negative";
    updateModeDisplay();
    renderHistory();
});

// 最初の表示を整える
updateModeDisplay();
renderHistory();
JavaScript

この状態で動かすと、

メッセージとタグを入力して追加する
一覧には「[タグ] メッセージ」が並ぶ
表示モードを切り替えると、ポジティブだけ・ネガティブだけが見られる

という、「ちょっとした自分用メッセージ管理アプリ」になります。


7日目で押さえておきたい本質

「画面を書き換える」はここまで来る

7日間を通して、あなたが身につけたのは

一つの場所の文字を書き換える
入力欄から文字を読み取る
ボタンのクリックに反応して処理を実行する
モード(状態)を変数で持ち、状態に応じて表示を変える
履歴を一覧として表示する
データ(配列)と表示(renderHistory)を分けて考える
データの中身に「種類(タグ)」を持たせて、表示を絞り込む

という、一連の流れです。

どれも「画面を書き換える」のバリエーションですが
ここまで来ると、もう立派に

「自分の考えたルールで画面を動かせる人」

になっています。


この先へのつながり

ここから何を足してもいい

今作った「タグ付きメッセージビューア」に対して

日付や時刻も一緒に保存する
タグを自分で追加できるようにする
ローカルストレージに保存して、ページを閉じても残るようにする

など、いくらでも機能を足していけます。

大事なのは、

新しい機能を考えるときに
「データはどう持つか」
「画面はどう描き直すか」

という二つの視点で考えられるようになっていることです。

それができているなら、
もう「JavaScript を勉強している人」ではなく
「JavaScript で自分の道具を作っている人」です。

もし「ここをもっと発展させたい」「別のパターンもやりたい」と思ったら
どの部分を広げたいか教えてくれれば、
そこから先の一歩も一緒に設計していけます。

タイトルとURLをコピーしました