
トップデベロッパーになるために作成したいアプリ8選 - Qiita
こちらの記事は、Indrek Lasn 氏により2017年 12月に公開された『 The Secret to Being a Top Developer Is Building Things! Here’s a List of Fun Apps to Build! 』の和...
上のページでは、ToDoアプリを作る時にreduceとfilterを使ってやってと書いてあるので3個めはこの縛りに従って作ってみました。
挙動について
こちらでは、activeのみを表示させた時にステータスを変更したときは、ステータスを変更すると消えてしまうという使用。activeのみ表示のときに追加するとALLへ移動、削除するときはactiveのみの表示から移動せず、そのまま削除される仕様。やっぱり1個めの挙動が自然だなと感じるので、課題感を感じるけどギブアップしました。
ToDoApp3 - JSFiddle - Code Playground
JSFiddle - Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle.
コード
html
<div class="container">
<div class="row justify-content-center">
<div class="col-md-9">
<h1>ToDo</h1>
<div class="todo-app">
<input id="todo-title3" class="todo-input3" type="text" name="" value="">
<button id="button3" type="button" name="button">追加</button>
<ul id="todo-list">
</ul>
<div>
<input type="radio" id="all3" name="todo" value="all" checked>
<label for="all">all</label>
</div>
<div>
<input type="radio" id="active3" name="todo" value="active">
<label for="active">active</label>
</div>
<div>
<input type="radio" id="completed3" name="todo" value="completed">
<label for="completed">completed</label>
</div>
</div>
</div>
</div>
</div>
css
ul {
list-style: none;
}
.template-none {
display: none;
}
.completed {
text-decoration: line-through;
}
.none {
display: none;
}
javascript
var arr = [];
for (var i = 0; i < 1000; i++) {
arr.push(i);
}
var alltodo = [];
var index = function(todos) {
// console.log('index');
var todoList = '';
if (!todos) {
return;
}
for (var i = 0; i < todos.length; i++) {
todoList += '<li class="' + todos[i]['display'] + '" data-id="' + todos[i]['id'] + '"><input class="comp3" type="checkbox" name="" value=""><span class="' + todos[i]['status'] + '">' + todos[i]['title'] + '</span><button class="delete3" type="button" name="button">削除</button></li>'; // = ではなく += を使う
}
document.getElementById('todo-list').innerHTML = todoList;
// ToDoを削除する
var btnEl = document.querySelectorAll('.delete3');
for (var i = 0; i < btnEl.length; i++) {
(function(j) {
btnEl[j].addEventListener('click', function() {
// console.log('削除ボタン押した番目', j);
var element = document.getElementById("completed3");
if (element.checked) {
// チェックされている
var todostatus = groupBy(alltodo, 'status');
// console.log('削除ボタン押したID', todostatus.completed[j].id);
alltodo = alltodo.filter(x => x.id != todostatus.completed[j].id);
todostatus = groupBy(alltodo, 'status');
// console.log(todostatus.completed);
if (!todostatus.completed) {
index([]);
}
index(todostatus.completed);
}
var element = document.getElementById("active3");
if (element.checked) {
// チェックされている
var todostatus = groupBy(alltodo, 'status');
// console.log('削除ボタン押したID', todostatus.active[j].id);
alltodo = alltodo.filter(x => x.id != todostatus.active[j].id);
todostatus = groupBy(alltodo, 'status');
if (!todostatus.active) {
index([]);
}
index(todostatus.active);
}
var element = document.getElementById("all3");
if (element.checked) {
// チェックされている
alltodo = alltodo.filter(x => x.id != alltodo[j].id);
index(alltodo);
//ラジオボタンをAllに
var element = document.getElementById("all3");
// 選択状態にする
element.checked = true;
}
});
})(i);
}
// ToDoのstatusを切り替える
var checkEl = document.querySelectorAll('.comp3');
for (var k = 0; k < checkEl.length; k++) {
(function(l) {
checkEl[l].addEventListener('change', function() {
// console.log(l);
var element = document.getElementById("completed3");
if (element.checked) {
// チェックされている
var todostatus = groupBy(alltodo, 'status');
if (!todostatus.active) {
todostatus.active = [];
}
for (var a = 0; a < alltodo.length; a++) {
if (alltodo[a].id == todostatus.completed[l].id) {
alltodo[a].status = 'active';
}
}
todostatus = groupBy(alltodo, 'status');
if (!todostatus.completed) {
index([]);
}
index(todostatus.completed);
}
var element = document.getElementById("active3");
if (element.checked) {
// チェックされている
var todostatus = groupBy(alltodo, 'status');
if (!todostatus.completed) {
todostatus.completed = [];
}
for (var a = 0; a < alltodo.length; a++) {
if (alltodo[a].id == todostatus.active[l].id) {
alltodo[a].status = 'completed';
}
}
todostatus = groupBy(alltodo, 'status');
if (!todostatus.active) {
index([]);
}
index(todostatus.active);
}
var element = document.getElementById("all3");
if (element.checked) {
if (alltodo[l]['status'] == 'active') {
alltodo[l]['status'] = 'completed';
} else {
alltodo[l]['status'] = 'active';
}
index(alltodo);
//ラジオボタンをAllに
var element = document.getElementById("all3");
// 選択状態にする
element.checked = true;
}
});
})(k);
}
}
function groupBy(objectArray, property) {
return objectArray.reduce(function(acc, obj) {
var key = obj[property];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
}
//ToDoのタイトル
var title = document.getElementById('todo-title3');
//ToDoを追加する
document.getElementById("button3").addEventListener('click', function() {
//タイトル未記入時はアラート
if (!title.value) {
alert("ToDoが未記入です");
return;
}
alltodo.push({
title: title.value,
status: 'active',
display: 'on',
id: arr[0]
});
arr.splice(0, 1);
// すべてdisplayをonに
for (var i = 0; i < alltodo.length; i++) {
if (alltodo[i].display == "none") {
alltodo[i].display = "on";
// console.log(i);
}
}
index(alltodo);
//ラジオボタンをAllに
var element = document.getElementById("all3");
// 選択状態にする
element.checked = true;
// titleの値を空に
title.value = '';
});
//ToDoの表示All
document.getElementById("all3").addEventListener('change', function() {
// console.log(alltodo);
for (var i = 0; i < alltodo.length; i++) {
if (alltodo[i].display == "none") {
alltodo[i].display = "on";
// console.log(i);
}
}
// console.log(todos);
index(alltodo);
});
//ToDoのactiveのみ表示
document.getElementById("active3").addEventListener('change', function() {
// console.log(alltodo);
var todostatus = groupBy(alltodo, 'status');
// console.log(todostatus);
if (!todostatus.active) {
index([]);
}
index(todostatus.active);
});
//ToDoのcompletedのみ表示
document.getElementById("completed3").addEventListener('change', function() {
var todostatus = groupBy(alltodo, 'status');
// console.log(todostatus);
if (!todostatus.completed) {
index([]);
}
index(todostatus.completed);
});
index(alltodo);

コメント