【初学者向けチュートリアル】JavaScriptでToDoリストを作成しよう

今回は初学者の方向けにToDoリストをJavaScriptで作成していきたいと思います。

1.対象者

 基本的なHTML、CSS、JavaScriptの文法の学習が完了している方

2.目的

 ToDoリストの作成によってJavaScriptのDOMを操作するプログラミングについて理解する

3.仕様

 ・入力欄にToDo項目を入力後追加ボタンをクリックすると、ToDoリストに追加される

 ・追加されたToDo項目には作成日時と完了ボタンが付帯する

 ・ToDo項目追加後には、入力欄の値はリセットされる

 ・完了ボタンをクリックすると、完了済みにToDo項目が移動する

 ・完了済みに追加された項目には完了ボタンが非表示になり、完了日時が追記される

詳細な動作については下記を確認してください。

5.準備

5-1.ファイル構成

ファイル構成は下記のようになります。

プロジェクトフォルダの直下にindex.html、main.js、style.cssを配置します。

5-2.HTML、CSSの実装

HTMLのソースコードは下記の通りです。

ToDoリストと完了済みリストはTableを使用しております。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header>
        <h1>ToDo List</h1>
    </header>
    <main>
        <div>
            <input type="text" id="input">
            <button id="addButton">追加</button>
        </div>
        
        <div>
            <div>
                <h2>ToDoリスト</h2>
                <table  border="1">
                    <thead>
                        <tr>
                            <td class="itemName">タスク名</td>
                            <td class="itemCreatedAt">作成日時</td>
                            <td class="itemComplete"></td>
                        </tr>
                    </thead>
                    <tbody id="todoList"></tbody>
                </table>
            </div>
            <div>
                <h2>完了済み</h2>
                <table  border="1">
                    <thead>
                        <tr>
                            <td class="itemName">タスク名</td>
                            <td class="itemCreatedAt">作成日時</td>
                            <td class="itemComplete">完了日時</td>
                        </tr>
                    </thead>
                    <tbody id="completedList"></tbody>
                </table>
            </div>
        </div>
    </main>
    <script src="main.js"></script>
</body>
</html>

CSSについては下記の通りになります。

リストがっぽく見えればいいかと思いますので、最低限下記のようなスタイリングをすればいいかと思います。

table{
    border-collapse: collapse;
}
.itemName{
    width: 300px;
}
.itemCreatedAt, .itemComplete{
    width: 200px;
}

6.JavaScriptの実装

ここから仕様に沿って、JavaScriptの実装を行っていきます。

6-1.ToDo項目の追加

まず、ToDo項目の追加の実装を進めていきます。

ToDoの追加といっても、プログラムを細かく分解すると下記のようになります。

1.追加ボタンを押した場合の処理を設定する

2.入力欄に入力された内容を取得する

3.作成日時を取得する

4.ToDo項目、作成日時、完了ボタンのHTMLタグを生成し、HTMLを配置する

6-1-1.追加ボタンを押した場合の処理の設定

追加ボタンを押した場合の処理を設定しましょう。

let addButton = document.getElementById("addButton");

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

まずは、追加ボタンのHTML要素を取得し、変数「addButton」に格納します。

documentというのは、表示されているwebページのHTMLドキュメントを表しています。

getElementByIdで表示されているHTMLの要素をidから検索してオブジェクトとして取得するプログラムになります。

そして、変数「addButton」に対して、「addEventListner」でクリックを行うと実行されるプログラムを記載していきます。

addEventListnerはHTML要素に対して何らかの操作を行った際のイベントを設定することができます。

今回はクリックですが、他にもポインターが指し示したら、ポインターが外れたら、キーボードでボタンを押したらなどの操作(イベント)を指定して処理内容を定義することができます。

これで追加ボタンのイベント設定は完了です。

6-1-2.入力欄に入力された内容を取得する

次は入力欄の入力内容の取得を行います。

let addButton = document.getElementById("addButton");
let input = document.getElementById("input");   //追加

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

//以下追加
function createTodoItem(){
    let inputValue = input.value;

}

先ほどと同様に「document.getElementById」でidがinputであるHTML要素(今回の場合はinputタグ)を取得します。

そして、createTodoItemが実行されたタイミングで、inputタグの値を取得します。

これで、入力欄の入力内容の取得は完了です。

6−1-3.作成日時を取得する

次に作成日時の取得を行います。

let addButton = document.getElementById("addButton");
let input = document.getElementById("input");   

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

function createTodoItem(){
    let inputValue = input.value;
    let createdAt = new Date().toLocaleString();   //追加
}

6-1-4.ToDo項目、作成日時、完了ボタンのHTMLタグを生成する実装

次にToDo項目、作成日時、完了ボタンのHTMLタグを生成します。

まず、空欄の項目が作成されるのを防ぐために、ToDo項目の値が何も入力されていない場合は、処理を実行は行いません。

let addButton = document.getElementById("addButton");
let input = document.getElementById("input");   

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

function createTodoItem(){
    let inputValue = input.value;
    let createdAt = new Date().toLocaleString();
    
    //以下追加
    if(inputValue != ""){

    }
}

続いて、ToDoの項目が入力されている場合の処理を書いていきます。

HTMLのToDoリストテーブルのtbodyタグ内にtrタグを追加(①)し、その後、追加したtrタグにToDo項目が記載されたtdタグ(②)の追加、作成日時が記載されたtdタグ(③)の追加、完了ボタンの追加(④)を行っていきます。

let addButton = document.getElementById("addButton");
let input = document.getElementById("input");   
let todoList = document.getElementById("todoList"); // 追加

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

function createTodoItem(){
    let inputValue = input.value;
    let createdAt = new Date().toLocaleString();
    
    if(inputValue != ""){

        // 以下追加
        // ①
        let itemRowTag = document.createElement("tr");
        todoList.appendChild(itemRowTag);
        
        // ②
        let listItem = document.createElement("td");
        let itemContent = document.createTextNode(inputValue);
        listItem.appendChild(itemContent); 
        itemRowTag.appendChild(listItem);    
        
        // ③
        let itemCreatedTag = document.createElement("td");
        let itemCreated = document.createTextNode(createdAt);
        itemCreatedTag.appendChild(itemCreated); 
        itemRowTag.appendChild(itemCreatedTag);

     // ④
        let completeTag = document.createElement("td");
        let completedButton = document.createElement("button");
        let completedButtonText = document.createTextNode("完了");
        completedButton.appendChild(completedButtonText);
        completeTag.appendChild(completedButton); 
        itemRowTag.appendChild(completeTag);
        // 追加ここまで
    
    }
}

まず、tbody要素を取得し変数「todoList」に格納します。

次に上述した①〜④の処理を記載していきます。

①については、「document.createElement」によってHTML要素を生成し、「todoList.appendchild()」で変数「todoList」の子要素として生成したHTMLを配置します。

②については、tdタグを生成、tdタグのテキスト要素を「document.createTextNode()」で生成した後、tdタグの要素として配置するために、「appendChild()」を行います。その後、tdタグを①で生成したtrタグの子要素として配置します。

③、④についても②と同様、それぞれtd要素を作成し、tr要素の子要素として配置します。

6-2.ToDo項目追加後、入力欄の値をリセットする実装

let input = document.getElementById("input");
let addButton = document.getElementById("addButton");
let todoList = document.getElementById("todoList");

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

function createTodoItem(){
    let inputValue = input.value;
    let createdAt = new Date().toLocaleString();

    if(inputValue != ""){
        let itemRowTag = document.createElement("tr");
        todoList.appendChild(itemRowTag);

        let listItem = document.createElement("td");
        let itemContent = document.createTextNode(inputValue);
        listItem.appendChild(itemContent); 
        itemRowTag.appendChild(listItem);    

        let itemCreatedTag = document.createElement("td");
        let itemCreated = document.createTextNode(createdAt);
        itemCreatedTag.appendChild(itemCreated); 
        itemRowTag.appendChild(itemCreatedTag);

        let completeTag = document.createElement("td");
        let completedButton = document.createElement("button");
        let completedButtonText = document.createTextNode("完了");
        completedButton.appendChild(completedButtonText);
        completeTag.appendChild(completedButton); 
        itemRowTag.appendChild(completeTag);

        input.value = '';  // 追加
    }
}

こちらは全ての処理が完了した後にinputタグのvalueを空欄にしてあげる処理で十分かと思います。

6-3.完了ボタンをクリックした後の処理の実装

最後に、完了ボタンをクリックした後の処理の実装になります。

実装する内容としては、

1.完了ボタンをクリックした場合の処理を設定する

2.完了したToDo項目を完了済みに移動する

3.完了ボタンを非表示にする

4.完了日時を追加する

それぞれ見ていきましょう。

6-3-1.完了ボタンをクリックした場合の処理を設定する

let input = document.getElementById("input");
let addButton = document.getElementById("addButton");
let todoList = document.getElementById("todoList");

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

function createTodoItem(){
    let inputValue = input.value;
    let createdAt = new Date().toLocaleString();

    if(inputValue != ""){
        let itemRowTag = document.createElement("tr");
        todoList.appendChild(itemRowTag);

        let listItem = document.createElement("td");
        let itemContent = document.createTextNode(inputValue);
        listItem.appendChild(itemContent); 
        itemRowTag.appendChild(listItem);    

        let itemCreatedTag = document.createElement("td");
        let itemCreated = document.createTextNode(createdAt);
        itemCreatedTag.appendChild(itemCreated); 
        itemRowTag.appendChild(itemCreatedTag);

        let completeTag = document.createElement("td");
        let completedButton = document.createElement("button");
        let completedButtonText = document.createTextNode("完了");
        completedButton.appendChild(completedButtonText);
        completeTag.appendChild(completedButton); 
        itemRowTag.appendChild(completeTag);
     
     // 以下追加
        completedButton.addEventListener("click", ()=>{
        })
        // 追加ここまで

        input.value = '';
    }
}

追加ボタンのイベントを実装した時と同様、完了ボタンのクリックイベントに対して「addEventListener」を設定します。

6-3-2.完了したToDo項目を完了済みに移動する

次に完了したToDo項目を完了済みに移動します。

let input = document.getElementById("input");
let addButton = document.getElementById("addButton");
let todoList = document.getElementById("todoList");
let completedList = document.getElementById("completedList"); // 追加

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

function createTodoItem(){
    let inputValue = input.value;
    let createdAt = new Date().toLocaleString();

    if(inputValue != ""){
        let itemRowTag = document.createElement("tr");
        todoList.appendChild(itemRowTag);

        let listItem = document.createElement("td");
        let itemContent = document.createTextNode(inputValue);
        listItem.appendChild(itemContent); 
        itemRowTag.appendChild(listItem);    

        let itemCreatedTag = document.createElement("td");
        let itemCreated = document.createTextNode(createdAt);
        itemCreatedTag.appendChild(itemCreated); 
        itemRowTag.appendChild(itemCreatedTag);

        let completeTag = document.createElement("td");
        let completedButton = document.createElement("button");
        let completedButtonText = document.createTextNode("完了");
        completedButton.appendChild(completedButtonText);
        completeTag.appendChild(completedButton); 
        itemRowTag.appendChild(completeTag);

        completedButton.addEventListener("click", ()=>{
            completedList.appendChild(itemRowTag); // 追加
        })

        input.value = '';
    }
}

まず、完了済みのtbodyの要素を取得し、completedListに格納します。

上記の6-1-4で作成したtrタグが格納されている、itemRowTagをcompletedListへ移動するため、appendChildをします。

これで、ToDo項目が完了済みに移動します。

6-3-4.完了ボタンを非表示にする

let input = document.getElementById("input");
let addButton = document.getElementById("addButton");
let todoList = document.getElementById("todoList");
let completedList = document.getElementById("completedList");

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

function createTodoItem(){
    let inputValue = input.value;
    let createdAt = new Date().toLocaleString();

    if(inputValue != ""){
        let itemRowTag = document.createElement("tr");
        todoList.appendChild(itemRowTag);

        let listItem = document.createElement("td");
        let itemContent = document.createTextNode(inputValue);
        listItem.appendChild(itemContent); 
        itemRowTag.appendChild(listItem);    

        let itemCreatedTag = document.createElement("td");
        let itemCreated = document.createTextNode(createdAt);
        itemCreatedTag.appendChild(itemCreated); 
        itemRowTag.appendChild(itemCreatedTag);

        let completeTag = document.createElement("td");
        let completedButton = document.createElement("button");
        let completedButtonText = document.createTextNode("完了");
        completedButton.appendChild(completedButtonText);
        completeTag.appendChild(completedButton); 
        itemRowTag.appendChild(completeTag);

        completedButton.addEventListener("click", ()=>{
            completedList.appendChild(itemRowTag);
            completeTag.remove(); // 追加 
        })

        input.value = '';
    }
}

完了したToDo項目の完了ボタンの非表示については6-1-4で生成したボタンが格納されている、td要素であるcompleteTagに対してremoveを行うことで、指定した要素を非表示にすることができます。

6-3-4.完了日時を追加する

let input = document.getElementById("input");
let addButton = document.getElementById("addButton");
let todoList = document.getElementById("todoList");
let completedList = document.getElementById("completedList");

addButton.addEventListener("click", ()=>{
    createTodoItem();
})

function createTodoItem(){
    let inputValue = input.value;
    let createdAt = new Date().toLocaleString();

    if(inputValue != ""){
        let itemRowTag = document.createElement("tr");
        todoList.appendChild(itemRowTag);

        let listItem = document.createElement("td");
        let itemContent = document.createTextNode(inputValue);
        listItem.appendChild(itemContent); 
        itemRowTag.appendChild(listItem);    

        let itemCreatedTag = document.createElement("td");
        let itemCreated = document.createTextNode(createdAt);
        itemCreatedTag.appendChild(itemCreated); 
        itemRowTag.appendChild(itemCreatedTag);

        let completeTag = document.createElement("td");
        let completedButton = document.createElement("button");
        let completedButtonText = document.createTextNode("完了");
        completedButton.appendChild(completedButtonText);
        completeTag.appendChild(completedButton); 
        itemRowTag.appendChild(completeTag);

        completedButton.addEventListener("click", ()=>{
            completedList.appendChild(itemRowTag);
            completeTag.remove();

            // 以下追加
            let itemCompletedTag = document.createElement("td");
            let completedAt = new Date().toLocaleString()
            let itemCompletedAt = document.createTextNode(completedAt);
            itemCompletedTag.appendChild(itemCompletedAt); 
            itemNumTag.appendChild(itemCompletedTag);
            // 追加

        })

        input.value = '';
    }
}

こちらは、完了日時を記載したtdタグを6-1-4と同様のやり方で完了済みに追加します。

これでToDoリストの作成は完了です。

7.終わりに

今回はJavaScriptで簡単なToDoリストを作成しました。

DOMの操作をすることでJavaScriptのプログラムからHTMLの要素を生成したり、削除したりすることができました。

今回は行いませんでしたが、CSSをJavaScriptからプログラムから操作することも可能で、プログラムでユーザーが操作した際に画面の変化をつけるのが、フロントエンドの役割になります。

しかし、このToDoリストですが、更新ボタンを押したり、他のページに遷移した後、戻ってきたりすると完了済みはおろか、ToDoも消えてしまいます。

これは、フロントエンドのDOMの操作だけでToDoリストを作成しましたが、データベース(もしくは、ファイル)への書き込みを行っていないため、データが保存することができません。

ここでバックエンドの実装が必要になっていきます。

次回は、JavaScriptで作成したToDoリストをPHPで作成して、サーバーサイドの役割を確認していきましょう。

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