LoginSignup
0
1

【JavaScript】買い出しメモアプリ

Last updated at Posted at 2023-11-26

localStorageを使用した、簡易メモアプリです。
個人的にスーパーでの食品買い出し用に使いたくて作成。
自分が欲しい機能のみなので、順序入れ替えや個数入力欄などはありません。

ss_.jpg

各項目左のチェックボックスは単にテキスト背景をグレー表示させるだけのもので特別な機能はありませんが、私は買い物中の購入済みチェック用に使っています。


動作デモ

index.html
<!DOCTYPE html>
<html lang='ja'>
<head>
<meta name='viewport' content='initial-scale=1'>
<meta charset='utf-8'>
<title>メモ</title>
<style>
#list {
  margin: 20px 0;
}
button {
  font-size: 18px;
}
[type=text] {
  font-size: 20px;
  margin: 8px;
  width: 220px;
}
[type=checkbox]:checked + input {
  background-color: #ccc;
}
</style>
</head>
<body>
<button id='allDel'>全削除</button>
<div id='list'></div>
<div><input type='text' id='addText'><button id='addBtn'>登録</button></div>
<template><div><input type='checkbox'><input type='text'><button>削除</button></div></template>
<script>
'use strict';

const list = document.getElementById('list');
const addText = document.getElementById('addText');
const template = document.querySelector('template').innerHTML;
const storageKey = 'memo';

document.addEventListener('DOMContentLoaded', () => {
  (JSON.parse(localStorage.getItem(storageKey)) ?? []).forEach(e => {
    if (e.text === '') return;
    list.insertAdjacentHTML('beforeend', template);
    const parent = list.querySelector('div:last-of-type');
    parent.querySelector('[type=text]').value = e.text;
    parent.querySelector('[type=checkbox]').checked = e.check;
  });
});

const addList = () => {
  if (addText.value.trim() === '') return;
  list.insertAdjacentHTML('beforeend', template);
  list.querySelector('div:last-of-type [type=text]').value = addText.value.trim();
  addText.value = '';
};

document.getElementById('addBtn').addEventListener('click', () => save());
addText.addEventListener('keydown', ev => ev.key === 'Enter' && save());

list.addEventListener('click', ev => {
  const target = ev.target;
  const parent = target.closest('div');
  if (target.tagName === 'BUTTON' && confirm(`${parent.querySelector('[type=text]').value}を削除しますか`)) {
    parent.remove();
    saveStorage();
  }
});

list.addEventListener('keydown', ev => {
  const target = ev.target;
  const parent = target.closest('div');
  if (target.tagName === 'INPUT' && ev.key === 'Enter' && target.value.trim() === '') {
    parent.remove();
    saveStorage();
  }
});

document.getElementById('allDel').addEventListener('click', () => {
  if (confirm('全てのリストを削除しますか')) {
    list.textContent = '';
    saveStorage();
  }
});

const saveStorage = () => {
  const listItems = [...list.querySelectorAll('div')];
  if (!listItems.length) {
    localStorage.removeItem(storageKey);
    return;
  }
  localStorage.setItem(storageKey,
    JSON.stringify(listItems.map(e => ({
      text: e.querySelector('[type=text]').value.trim(),
      check: e.querySelector('[type=checkbox]').checked,
    })))
  );
};

const save = () => {
  addList();
  saveStorage();
};

addEventListener('beforeunload', () => save());
addEventListener('pagehide', () => save());
</script>
</body>
</html>

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1