반응형
To do 리스트 관리 애플리케이션
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://kit.fontawesome.com/833be080c6.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="./main.css">
<script type="module" defer src="./index.js"></script>
</head>
<body>
<h1>To Do</h1>
<!-- container -->
<div class="container">
<!-- To do -->
<div class="card">
<h2 style="background-color: rgb(124, 204, 177);">to do</h2>
<div class="list-box" id="1">
</div>
<button class="btn-add">
<i class="fas-fa-plus"></i>add item
</button>
</div>
<!-- in progress -->
<div class="card">
<h2 style="background-color: rgb(228, 191, 135);">In Progress</h2>
<div class="list-box" id="2">
</div>
<button class="btn-add">
<i class="fas-fa-plus"></i>add item
</button>
</div>
<!-- completed -->
<div class="card">
<h2 style="background-color: rgb(220, 78, 78);">Completed</h2>
<div class="list-box" id="3">
</div>
<button class="btn-add">
<i class="fas-fa-plus"></i>add item
</button>
</div>
<!-- on hold -->
<div class="card">
<h2 style="background-color: rgb(177, 214, 103);">on hold</h2>
<div class="list-box" id="4">
</div>
<button class="btn-add">
<i class="fas-fa-plus"></i>add item
</button>
</div>
</div>
</body>
</html>
main.css
@import url('https://fonts.googleapis.com/css?family=Poppins&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
height: 100vh;
display: flex;
flex-direction: column;
text-transform: capitalize;
font-family: 'Poppins';
background: linear-gradient(
90deg,
rgb(240, 244, 207) 50%,
rgb(245, 236, 207) 90%
);
}
/* title style */
h1 {
text-align: center;
margin: 20px;
text-transform: uppercase;
}
/* container style */
.container {
display: flex;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
}
/* card style */
.card {
height: 500px;
width: 300px;
display: flex;
justify-content: space-between;
flex-direction: column;
flex-shrink: 0;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 5px;
box-shadow: 2px 2px 1px 0 rgba(0, 0, 0, 0.4);
}
/* card title style */
h2 {
text-align: center;
padding: 15px;
margin: 10px;
border-radius: 5px;
box-shadow: 2px 2px 1px 0 rgba(0, 0, 0, 0.4);
}
/* list box style */
.list-box {
height: 100%;
display: flex;
flex-direction: column;
overflow: scroll;
}
::-webkit-scrollbar {
display: none;
}
input {
height: 40px;
margin: 10px;
border-radius: 5px;
padding: 0 10px;
font-size: 1.3rem;
flex-shrink: 0;
box-shadow: 2px 2px 1px 0 rgba(0, 0, 0, 0.4);
}
/* button style */
button {
height: 40px;
margin: 10px;
padding: 10px;
border-radius: 5px;
box-shadow: 2px 2px 1px 0 rgba(0, 0, 0, 0.4);
border: none;
background-color: rgb(152, 231, 152);
cursor: pointer;
transition: 0.3s ease;
text-transform: uppercase;
font-size: 1.2rem;
}
button:hover {
background-color: #fff;
cursor: pointer;
}
button:active {
transform: scale(0.98);
}
index.js
import { createId } from './id.creator.js'
// variables
const inputsEl = document.querySelectorAll('input')
const boxesEl = document.querySelectorAll('.list-box')
const btnAddsEl = document.querySelectorAll('.btn-add')
const listBoxesEl = document.querySelectorAll('.list-box')
let lists = []
let flag = false
// storage
if (localStorage.getItem('list')) {
lists = JSON.parse(localStorage.getItem('list'))
addNewList(lists)
}
// event handlers
inputsEl.forEach((input) => {
input.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('list', e.target.id)
})
})
boxesEl.forEach((box) => {
box.addEventListener('dragover', (e) => {
e.preventDefault()
})
})
boxesEl.forEach((box) => {
box.addEventListener('drop', (e) => {
let data = e.dataTransfer.getData('list')
box.appendChild(document.getElementById(data))
console.log(e.target.id)
console.log(data)
updateContainerId(data, e.target.id)
})
})
addNewList()
// functions
function addNewList(lists) {
if (typeof lists !== 'undefined') {
lists.forEach((list) => {
const newList = document.createElement('input')
newList.draggable = true
newList.readOnly = true
newList.id = list.id
newList.value = list.text
newList.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('list', e.target.id)
})
newList.addEventListener('click', (e) => {
newList.readOnly = false
})
newList.addEventListener('input', (e) => {
flag = true
newList.value = e.target.value
})
window.addEventListener('click', (e) => {
e.target === newList
? updateStatue(newList, false)
: updateStatue(newList, true, list.containerId)
})
listBoxesEl[list.containerId - 1].appendChild(newList)
})
}
btnAddsEl.forEach((btnAdd) => {
btnAdd.addEventListener('click', () => {
const newList = document.createElement('input')
newList.draggable = true
newList.readOnly = true
newList.id = createId()
newList.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('list', e.target.id)
})
newList.addEventListener('click', (e) => {
newList.readOnly = false
})
newList.addEventListener('input', (e) => {
flag = true
newList.value = e.target.value
})
window.addEventListener('click', (e) => {
e.target === newList
? updateStatue(newList, false)
: updateStatue(newList, true, btnAdd.previousElementSibling.id)
})
btnAdd.previousElementSibling.appendChild(newList)
})
})
}
function updateStatue(newList, isReadOnly, containerId) {
newList.readOnly = isReadOnly
if (flag && isReadOnly) {
lists.push({
id: newList.id,
text: newList.value,
containerId: containerId,
})
updateList()
flag = false
}
}
function updateContainerId(id, containerId) {
lists = lists.map((list) =>
list.id === id ? { ...list, containerId: containerId } : list
)
updateList()
}
function updateList() {
localStorage.setItem('list', JSON.stringify(lists))
}
id.creator.js
let idList = []
if (localStorage.getItem('idList')) {
idList = JSON.parse(localStorage.getItem('idList'))
}
function createId() {
const id = Math.floor(Math.random() * 100000)
console.log(id)
if (idList.includes(id)) return
idList.push(id)
localStorage.setItem('idList', JSON.stringify(idList))
return id
}
export {createId}
데모
728x90
반응형
'프론트엔드 > 자바스크립트' 카테고리의 다른 글
클라이언트 측 데이터 저장소 - 인덱스드 디비 (0) | 2022.12.29 |
---|---|
클라이언트 측 데이터 저장소 - 웹 스토리지 (Web Storage) (0) | 2022.12.29 |
프로젝트 - 뮤직 플레이어 (0) | 2022.12.28 |
요소 지우기 (0) | 2022.12.28 |
배열 안에 객체 밸류 바꾸기 (0) | 2022.12.27 |