トップへ戻る
BLOGS

プログラミングの設計をする練習2

プログラミングの設計をする練習2

前回のつづきです。

参考までにここまで記述した内容とやりたいことを並べておきます。

いわゆるプログラミング思考ってな考え方で、大事なことです。

何を作りたい?作るためにどうする?そのために何をする?

大切なことは逆算思考と分析能力ということ。

まずは箇条書きにしながらアプリ開発のやりたいことを書き出してみようと思う。

お題はこちら

TODOリストを作成する

ということで具体的に機能はこちら

  • インプットができる
  • インプットし、エンターを押したら入力したものを記憶している
  • 左クリックすると取り消し線が入る
  • 右クリックすとるTODOリストが削除される
  • インプットしたものをエンターでHTMLとして画面に出力する

さてさてそれでは作成開始!!

const form = document.getElementById("form");
const input = document.getElementById("input");
const ul = document.getElementById("ul");

form.addEventListener("submit",function(event){
  event.preventDefault();
  add();
});



function add() {
  let todotext = input.value;
  if (todotext) {
    const li = document.createElement("li");
    li.innerText = todotext;
    ul.appendChild(li);
    input.value = '';
  }
};

とここまで書いてきて、入力された値を受け取りliタグとして出力するところまではできましたが、このままでは出力されたliタグはエンターのリロードで消えてしまいます。

次はこれを回避したいのでブラウザのローカルストレージに保存をしたいと思います。

function savedate() {
}

この中でliに入力された値に対しての参照から書いていきます。

 const lists = document.querySelectorAll("li");

これで変数listsにはliタグの中身が配列として格納されました。ここからこの配列としてのデータをjsとして操作出来るようにこちらで用意する配列変数に格納したいと思います。

まず何も入っていないからの変数を用意します。

let todos = [];

そして先に準備し参照していた配列変数listsから配列用ループ文で値を全て取得し配列に格納します。

lists.forEach(list =>{
    todos.push(list.innerText);
  });

todos.push(list.innerText); でlist(全ての).innerTextを配列todosに.push(追加)することが出来るようになります。ではこの配列をつかってローカルストレージに保存したいと思います。

localStorage.setItem("todos",JSON.stringify(todos));

localStorage.setItem(“キー”,値);という形で記述するとこれを保存できます。

これで画面をリロードしてもローカルストレージに保存したliの内容は残り続けてくれます。しかし画面上からはliタグが消えてしまうので次はこれをリロードで取得しエンターキーが押されたときと同様に、liタグとして出力してやります。

まず取得するコードとしては、、

const todos = JSON.parse(localStorage.getItem("save_todos"));

これでtodosに配列としてデータを取得できたので次はこれに値があるか確認しあれば出力できるようにします。

if (todos.length > 0) {
  todos.forEach(todo => {
    add(todo);
  })
}

先に作成したadd()関数に引数を渡して同じように出力できるようにします。

add(todo)を←のように書き換えます。そして、、全体的には条件分岐を追加します。

function add(todo) {
  let todotext = input.value;
  if (todo) {
    todotext = todo;
  }
  if (todotext) {
    const li = document.createElement("li");
    li.innerText = todotext;
    ul.appendChild(li);
    input.value = '';
    savedate();
  }
};

if (todo) {
todotext = todo;
}これを追加することでリロード時にtodoがあるならばそれでliタグを生成するように、条件分岐を書きました。

次に画面に並べれるようになったTODOリストを削除出来る機能を実装します。

「右クリックすとるTODOリストが削除される」ということで具体的にはaddEventlistenerを使用しliタグが子要素として出力される前に仕込んでおきます。

コードはこちら、、

li.addEventListener("contextmenu",function(event) {
      event.preventDefault();
      li.remove();
      savedate();
    })

contextmenuこれが右クリックのアクション検知になります。さらにパソコンは基本的には右クリックしたらメニューが開くようになっていますのでこれをキャンセルするためにここでも、event.preventDefault();を仕込んでおきます。

li.remove();そしたらこのコードでliタグを消去するということが可能なので、

savedate();でローカルストレージにも反映されるようにしておきます。

後少し!liタグに取り消し線をつけます!

「左クリックすると取り消し線が入る」ということでこれはもともとCSSにスタイルを指定しておき、JSで左クリックに対してクラスを追加できるようにしておくことで実現可能です。

li.addEventListener("click",function() {
      li.classList.toggle("complete");
    })

これで左クリックするたびにcompleteというクラスがつけ外しができました。

しかしこの取り消し線(スタイル)は画面リロードとともに消えてしまいます。

これを保存しておくためにはオブジェクトとして「完了した」というデータを保存しておく必要があるようです。

function savedate() {
  const lists = document.querySelectorAll("li");
  let todos = [];
  lists.forEach(list =>{
    let todo = {
      text: list.innerText,
      completed: list.classList.contains("complete")
    };
    todos.push(todo);
  });
  localStorage.setItem("save_todos",JSON.stringify(todos));
}

ということでデータの型をオブジェクトにへんこうしてtodos.push(todo);としてローカルストレージに保存したいと思います。

let todo = {
text: list.innerText,
completed: list.classList.contains(“complete”)
};

こちらでオブジェクト、todoにそれぞれのデータを名前をつけて保存しておく事ができます。completed: list.classList.contains(“complete”)で指定しているものは、.classList.containsで()で指定したクラスを持っているかの真偽値を判定しています。

データ型が変更されたので修正が必要な部分が出てきました。

function add(todo) {
  let todotext = input.value;
  if (todo) {
    todotext = todo.text;
  }
  if (todotext) {
    const li = document.createElement("li");
    li.innerText = todotext;
    if (todo && todo.completed) {
      li.classList.add("complete");
    }
    li.addEventListener("contextmenu",function(event) {
      event.preventDefault();
      li.remove();
      savedate();
    })
    li.addEventListener("click",function() {
      li.classList.toggle("complete");
      savedate();
    })
    ul.appendChild(li);
    input.value = '';
    savedate();
  }
};

if (todo) {
todotext = todo.text;
}  この部分ですね。todoがオブジェクトになったのでtodo.textの値を代入するようにします。

if (todo && todo.completed) {
li.classList.add(“complete”);
}    またこちらの条件分岐でtodoに値があり、todo.completedがtrueの場合、

.classList.add(“complete”);でliタグにクラスcompleteを付与することが可能です。

長らくお疲れさまでした。無事完成ですね。次はこれにもっとオリジナルの機能を追加したいですね。

コメントをお待ちしております

お気軽にコメントをどうぞ。

CAPTCHA