본문 바로가기

토이 프로젝트

[자바스크립트] 작은 도서관 프로그램 만들기 (MySQL, Express, Fetch API, Node.js) - Mysql, express, fetch api crud example (2)

2020/10/13 - [토이 프로젝트] - [자바스크립트] 작은 도서관 프로그램 만들기 (MySQL, Express, Fetch API, Node.js) - Mysql, express, fetch api crud example (1)

 

[자바스크립트] 작은 도서관 프로그램 만들기 (MySQL, Express, Fetch API, Node.js) - Mysql, express, fetch api cr

2020/10/08 - [토이 프로젝트] - [자바스크립트] 작은 도서관 프로그램 만들기 (MySQL, Express, ejs, Node.js) - Mysql, express, ejs crud example [자바스크립트] 작은 도서관 프로그램 만들기 (MySQL, Express..

ukcasso.tistory.com

  위 프로젝트에서는 수정 / 삭제 버튼이 각 책의 목록마다 나와있었는데 그것을 아래로 내려 한 버튼에 구현하게 하는 새로운 버전을 만들었다. 원래 이렇게 만드려고 했으나 시간상 윗 글처럼 만든건데 수정했다고 보면 될 것같다. 로컬스토리지로 만들었을 때와 같은 방식이다.

 

 


 

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>작은 도서관</title>
    </head>
    <style>
    </style>
    <link rel="stylesheet" href="./style.css">
    <body onload="startServer()">
        <div id="library">
            <center>
                <div id="logo"><br>
                    <center>
                        <a href="#"><img src="./vendit-logo-white.png" onclick="location.reload()" width="150px"></a>
                    </center>
                </div>
            </center>
            <center>
                <div id="search">
                    <center>
                        <!--<b>서적 검색</b><br>-->
                        <input type="search" id="searchInput" placeholder="제목, 내용, 저자로 검색">
                        <input class="dateSet" type="date" id="dateStart" >
                        ~
                        <input class="dateSet" type="date" id="dateEnd" >
                        <button id="searchBtn" type="submit" onclick="searchBook(document.getElementById('searchInput').value, 
                        new Date(document.getElementById('dateStart').value),
                        new Date(document.getElementById('dateEnd').value))">검색</button>
                    </center><br>
                </div>
            </center>
            <center>
                <div id="table">
                    <!--<b>찾은 서적 목록</b><br>-->
                    <center>
                        <table>
                            <thead>
                                <tr><th>순번</th><th>제목</th><th>내용</th><th>저자</th><th>출간날짜</th></tr>
                            </thead>
                            <tbody id="bTable"></tbody>
                        </table>
                    </center>    
                </div>
            </center>
            <center>
                <div id="newBooks">
                    <center><br>
                            <!--<b>새로운 서적 등록</b><br>-->
                            <input class="new" type="text" id="title" name="title" placeholder="제목">
                            <input class="new" type="text" id="author" name="author" placeholder="저자">
                            <input class="dateSet" type="date" id="date" name="date" placeholder="출간날짜"><br><br>
                            <textarea name="contents" type="text" id="content" name="content" placeholder="내용"></textarea><br>
                            <button id="putBtn" type="submit" onclick="inputEditBook()">등록 / 수정</button>
                            <button id="delBtn" type="submit" onclick="deleteBook()">삭제</button>
                    </center><br>
                </div>
            </center>
        </div>
        <script src="./library.js"></script>
    </body>
</html>

 

 

/server/index.js

'use strict';
const express = require('express');
const app = express();
const { Sequelize, DataTypes } = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = {
  "development": {
    "username": "root",
    "password": "****",
    "database": "library",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
}[env];

let cors = require('cors')
let http = require('http');
let bodyParser = require('body-parser');
let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

const books = sequelize.define('books', {
  title: {
    type: DataTypes.STRING(200),
    allowNull: true,
  },
  content: {
    type: DataTypes.STRING,
    allowNull: true,
  },
  author: {
    type: DataTypes.STRING,
    allowNull: true,
  },
  date: {
    type: DataTypes.STRING,
    allowNull: true,
  }
});


sequelize.sync({ force: false }).then( () => {
  console.log("DB connection is successful");
  
}).catch(err => {
  console.log("DB connection faild");
  console.log(err);
});


app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended : false}));

app.get('/get', async(req, res) => { 
  await books.findAll().then(result => {
    res.json(result)
  });
});

app.post('/inputBook', async (req, res) => {
  await books.create({
    title : req.body.title,
    content : req.body.content,
    author : req.body.author,
    date : req.body.date
  }).then(result => {
    console.log("Success input data" + result);
    res.redirect('/');
  }).catch(err => {
    console.log("Fail update data" + err);
  });
});

app.patch('/edit/', async(req, res) => {
  await books.update({
    title : req.body.title,
    content : req.body.content,
    author : req.body.author,
    date : req.body.date
  }, {
    where : {id: req.body.id}
  }).then(result => {
    console.log("Success update data" + result);
    res.redirect('/');
  }).catch(err => {
    console.log("Fail update data" + err)
  })
})

app.delete('/delete/:id', async(req, res) => {
  await books.destroy({
    where: {id: req.params.id}
  }).then(result => {
    console.log(result)
    res.redirect('/');
  }).catch(err => {
    console.log("Fail delete data" + err);
  });
});

http.createServer(app).listen(3000, () => {'Server is running on port 3000...'})

 

 

library.js

const element = document.getElementById("bTable");
let db = [];
let temp = [];
function showHtml(i) {
  return  `
          <td>${i + 1}</td>
          <td><a href="#" id='${i}' onclick='popInfo(this.id);'>${db[i].title}</a></td>
          <td>${db[i].content}</td>
          <td>${db[i].author}</td>
          <td>${db[i].date}</td>
          `;
}

function startServer() {
  fetch("http://localhost:3000/get")
    .then((response) => response.json())
    .then((data) => {db = data; showTable();})
    .catch(err => {
      console.log('Fetch Error', err)
    })
}

function showTable() {
  for(let i = 0; i <= db.length - 1; i++) {
      element.innerHTML += showHtml(i);
  };
  for(let i = 0; i < 5 - db.length; i++) {
    element.innerHTML += `<td>-</td>
                          <td>-</td>
                          <td>-</td>
                          <td>-</td>
                          <td>-</td>
                          `;
  };
};

function inputEditBook() {
  if(temp.length === 0) {
    fetch("http://localhost:3000/inputBook", {
      method: "POST",
      body: JSON.stringify({
        title: document.getElementById("title").value,
        content: document.getElementById("content").value,
        author: document.getElementById("author").value,
        date: document.getElementById("date").value
      }),
      headers: {
        "Content-type": "application/json; charset=UTF-8"
      }
    })
    .then(response => response.json())
    .then(json => console.log(json))
    location.reload();
} else if(temp.length !== 0) {
    fetch("http://localhost:3000/edit/", {
      method: "PATCH",
      body: JSON.stringify({
        id: temp[temp.length - 1],
        title: document.getElementById("title").value,
        content: document.getElementById("content").value,
        author: document.getElementById("author").value,
        date: document.getElementById("date").value
      }),
      headers: {
        "Content-type": "application/json; charset=UTF-8"
      }
    })
    .then(response => response.json())
    .then(json => console.log(json))
    location.reload();
  }
}

function deleteBook(){
  fetch("http://localhost:3000/delete/" + temp[temp.length - 1], {
    method: "DELETE"
  })
  .then(response => response.json())
  .then(json => console.log(json))
  location.reload();
}

function popInfo(id) {
  document.getElementById("title").value = db[id].title;
  document.getElementById("content").value = db[id].content;
  document.getElementById("author").value = db[id].author;
  document.getElementById("date").value = db[id].date;
  temp.push(db[id].id);
};

function searchBook(data, sDate, eDate) {
  console.log(data, sDate, eDate)
  element.innerHTML = ``;
  if(!data && isNaN(sDate)) {
      location.reload();
  } else {
    for(let i = 0; i <= db.length - 1; i++) {
      let popData = (db[i].title.includes(data)) || (db[i].author.includes(data)) || (db[i].content.includes(data));
      if(!isNaN(sDate) ? popData && sDate <= new Date(db[i].date) && eDate >= new Date(db[i].date) : popData) {
        element.innerHTML += showHtml(i);
      };
    };
  };
};

 

 

style.css

.dateSet {
  width: 110px;
  height: 16px;
}
#logo {
  background-color: #5E6698;
  width: 950px;
  padding: 5px;
}
#search {
  background-color: #5E6698;
  width: 950px;
  padding: 5px;
}
#table {
  background-color: white;
  width: 950px;
  padding: 5px;
  height: 276px;
  overflow: auto;
}
#newBooks {
  background-color: #5E6698;
  width: 950px;
  padding: 5px;
}
#searchInput {
  width: 440px;
}
#searchBtn {
  width: 100px;
}
#putBtn {
  width: 400px;
  height: 50px;
}
#delBtn {
  width: 400px;
  height: 50px;
}
#title {
  width: 505px;
}
#content {
  width: 798px;
  height: 100px;
  resize: none;
}
table {
  background-color: white;
  width: 810px;
  table-layout: fixed;
  word-break: break-all;
}
tr {
  background-color: white;
  padding: 10px;
  border: 0px solid black;
}
th {
  padding: 10px;
  border: 0px solid black;
}
td {
  padding: 10px;
  border: 0px solid black;
  text-align: center;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}
a {
  color: black;
  text-decoration: none;
}
a:hover {
  color: rgb(74, 138, 211);
}

 

 

사실상 크게 변화를 준건 library.js밖에 없다.

 


아래 github 주소에서 정확한 소스코드 다운파일을 받을 수 있다.

 

github.com/ukcasso/library_git

 

ukcasso/library_git

Contribute to ukcasso/library_git development by creating an account on GitHub.

github.com