본문 바로가기

블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기

[30일차 복습2 / 숙제 ] node.js express서버 구축, 게시판 만들기 수정, 삭제, 조회수 올리기 - mysql DB연결

반응형

 

 

*{
    margin:0;
    padding:0;
    
}

a{
    text-decoration: none;
}

ul,li{
    list-style: none;
}

1. DB 연결부터 다시 해보기 

 

SQL by vs 

CREATE DATABASE homepage7;
use homepage7;

CREATE TABLE board(
    idx INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    subject VARCHAR(100) NOT NULL,
    writer VARCHAR(50) NOT NULL,
    content text,
    today datetime default CURRENT_TIMESTAMP,
    hit INT(11)
) AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

auto_increment - 자동으로 1++ 되도록 아래 설정함  -> 값을 추가할 필요가 없음 

(** auto_increment는 기본키 PK 만 ㄱ ㅏ 능하다.) 

primary key - pk로 설정 

not null - null값 받지 않는다. (a column은 원래 null 값도 가질 수 있음) 

 

not null : By default, a column can hold NULL values. The NOT NULL constraint enforces a column to NOT accept NULL values. This enforces a field to always contain a value, which means that you cannot insert a new record, or update a record without adding a value to this field.

 

charset=utf8 vs charset=utf8mb4;

charset=utf8은 emoji문자가 입력이 안된다고 함 

charset=utf8mb4는 업그레이드버젼으로 emoji사용가능 

 

* 마지막 hit INT(11) 뒤에 , 콤마 찍었더니 database create은 되었는데 table이 안들어가고 오류남. 

 

우여곡절끝에 만들엇다....

 

NULL 을 보면 NOT NULL 이라고 설정한 idx, subject, writer => NO 설정하지 않은 field는 YES라고 나왔다. 

 

DB완성 ! 

 

JS -> connection 부분 database:homepage1 으로 변경 (env 파일에 있어서 거기 변경함) 

 

----------------------------------------------------------어제꺼까지 복습 완료 ---------------------------------------------

js

require('dotenv').config();
const express=require('express');
const app=express();
const nunjucks=require('nunjucks');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const port = process.env.SERVER_PORT || 3000;

nunjucks.configure('views',{
    express:app,
})

app.use(bodyParser.urlencoded({extended:false}));
app.set('view engine', 'html');
app.use(express.static('public'));

let connection = mysql.createConnection({
    host:process.env.DB_HOST,
    user:process.env.DB_USER,
    password:process.env.DB_PASSWORD,
    database:process.env.DB_DATABASE,
})

connection.connect();

app.get('/',(req,res)=>{
    res.render('index.html');
})

app.get('/board',(req,res)=>{

    connection.query("select idx, subject, writer, content, date_format(today, '%H:%m %m-%d-%Y ') as today, hit from board", (error,results)=>{
        if(error){
            console.log(error);
        }else{
            console.log(results);
            res.render('board.html',{
                board_db:results,
            })
        }
    })
})

app.get('/write',(req,res)=>{
    res.render('write.html');
})

app.post('/writedone',(req,res)=>{
    res.redirect('/board');  //여기 url을 /board로 바꾼다 -> render('board') 하지 않는 이유? render로 board.html로 넘어가면 db가 없다. 
})


//------------------ V I E W -------------------//

app.get('/view',(req,res)=>{

    let idx = req.query.idx;

    connection.query(`select * from board where idx='${idx}'`,(error,results)=>{
        if(error){
            console.log(error)
        }else{
            console.log(results)
            res.render('view.html',{
                view_db:results[0],
            });
        }
    })
})

app.get('/modify',(req,res)=>{
    res.render('modify.html');
})


app.post('/modifydone',(req,res)=>{
    res.redirect('/board');
})


app.listen(3000,()=>{
    console.log('server start port : 3000')
})

 

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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    
    WELCOME! <br/>
    <br/>
<br/>
    <a href="/board" >게시판 구경하기</a>



</body>
</html>

board.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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <h2>게시판</h2>
    <div>
        <table>
            <tr>
                <td>번호</td>
                <td>제목</td>
                <td>작성자</td>
                <td>날짜</td>
                <td>조회수</td>
            </tr>
            <tr>{% for item in board_db %}
                <td>{{item.idx}}</td>
                <td><a href="/view?idx={{item.idx}}">{{item.subject}}</a></td>
                <td>{{item.writer}}</td>
                <td>{{item.today}}</td>
                <td>{{item.hit}}</td>
            </tr>{% endfor %}
        </table>
        <button><a href="/">돌아가기</a></button>
        <button><a href="/write">글쓰기</a></button>
    </div>
</body>
</html>

write.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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <form method="post" action="/writedone">
        <span>제목</span>
        <input type="text" name="subject"> <br/>
        <br/>
        <span>작성자</span>
        <input type="text" name="writer"> <br/>
        <br/>
        <spand>내용</span>
        <input type="text" name="content"> <br/>
        <button><a href="/board">돌아가기</a></button>
        <input type="submit" value="글작성">
    </form>
</body>
</html>

view.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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <ul>
        <li>
            <span>글제목 : </span>
            <span>{{view_db.subject}}</span>
        </li>
        <li>
            <span>작성자 : </span>
            <span>{{view_db.writer}}</span>
        </li>
        <li>
            <span>내용</span>  
            <span>{{view_db.content}}
            </span>
        </li>
    </ul>
    <button><a href="/board">목록으로 돌아가기</a></button>
    <button><a href="/modify">글 수정하기</a></button>
</body>
</html>

modify.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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <form method="post" action="/modifydone">
        <span>제목</span>
        <input type="text" name="subject"> <br/>
        <br/>
        <span>작성자</span>
        <input type="text" name="writer"> <br/>
        <br/>
        <spand>내용</span>
        <input type="text" name="content"> <br/>
        <button><a href="/board">돌아가기</a></button>
        <input type="submit" value="글 수정 완료">
    </form>
</body>
</html>

createTable.sql

CREATE DATABASE homepage1;
use homepage1;

CREATE TABLE board(
    idx INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    subject VARCHAR(100) NOT NULL,
    writer VARCHAR(50) NOT NULL,
    content text,
    today datetime default CURRENT_TIMESTAMP,
    hit INT(11)
) AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

index.css

*{
    margin:0;
    padding:0;
    
}

a{
    text-decoration: none;
}

ul,li{
    list-style: none;
}

.env

SERVER_PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=5353
DB_DATABASE=homepage1

 

 

---------------------------------------------------이번 주말 목표-------------------------------------------------

 

 

1. css 로 게시판 꾸미기ok 

오랜만에 css html 하니깐 뭔가 생소(?) 했다. 그래도 가장 처음 한거라 그런지 그나마 기억 더듬으면서 할 수 있엇다 

 

2. 조회수 클릭마다 올리기 

-> 엄청 어려울 것 같았는데 app.get('view' 안에

    connection.query(`update board set hit=hit+1 where idx='${idx}'`);

요 한 줄로됏다. . 휴 

 

3. 게시글 보기(삭제, 수정) -> ok  

개선할 곳 -> 입력란에 글씨 안바꿔도 그대로 수정되게 ?

placeholder="{{modify_db.subject}} -> value="{{modify_db.subject}}"  수정 

수정 -> idx 그대로 만들기 -> 수정 idx 가 안나와서 고생햇다 ㅠㅠㅠㅠ

수정 시 글 번호는 block 시키기 ok/ readonly / disabled 만들기 ↓↓↓↓

blckchainetc.tistory.com/63

 

input type="text" 글 쓰지 못하게 막기 readonly disabled 차이

node.js 게시판 만들기 서버에 보내줄 modify.html readonly 여기서 넣은 요걸 수정하지 못하게 막는 방법 readonly 만 넣어주면 된다 그럼 다른건 수정이 되지만 "글 번호" text 부분은 text background 등이..

blckchainetc.tistory.com

 

 

ㅇ post ('/modifydone') 에서 한~~~~~~~~~~~~~~참 진행이 안됐다. 

idx 값을 못가지고 온다고 해서 console.log 찍었떠니 undefined.. 

 

a href="" vs action"" 의 차이인지 아니면 post 일때 의 차이인지? 왠지 action 일 때는 <form></form>안의 내용만 긇어서 객체로 전달해주는 거 같다. 그 안에 있는것만 console.log(req.body)에 찍히더라고.......... 그래서 idx 글번호를 만들어서 넣어줫더니 됐다 ㅠㅠㅠㅠㅠㅠㅠㅠ 

    <button><a href="/modify?idx={{view_db.idx}}">글 수정하기</a></button>

 

    <form method="post" action="/modifydone?idx={{modify_db.id}}">

요 위에 두개... 결국 action에 ?뒤로 uri를 다 빼고 

<!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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <h2> 글 수정하기 </h2>
    <form method="post" action="/modifydone">
        <span>글 번호</span>
        <input type="text" name="idx" value="{{modify_db.idx}}"> <br/>
        <br/>
        <span>제목</span>
        <input type="text" name="subject" value="{{modify_db.subject}}"> <br/>
        <br/>
        <span>작성자</span>
        <input type="text" name="writer" value="{{modify_db.writer}}"> <br/>
        <br/>
        <spand>내용</span>
        <input type="text" name="content" value="{{modify_db.content}}"> <br/>
        <button><a href="/board">돌아가기</a></button>
        <input type="submit" value="글 수정 완료">
    </form>
</body>
</html>

글 번호 idx 추가해서 JS에 console.log(idx)뜨나 봤더니 뜬다.. 

app.post('/modifydone',(req,res)=>{
    let idx = req.body.idx;
    console.log(req.body);
    let subject = req.body.subject;
    let writer = req.body.writer;
    let content = req.body.content;

    let sql = `update board set subject='${subject}', writer='${writer}', content='${content}', today=now() where idx='${idx}'`;

    connection.query(sql,(error,results)=> {
        if(error){
            console.log(error);
        }else{
            console.log(results);
            res.redirect('/board');
        }
    })
})

 

 

5. 게시글 작성(회원가입,이름,아이디,패스워드- > db저장) ok

 

 

<input type="text" > 으로 하니 input text 글자가 box의 중간에서 시작해서 

<textarea> </textarea> 로 바꿧다

그랬더니 mysql colomn 이 깨짐 - content 부분 textarea 는 뭔가 길어서 자리를 다 잡아 먹는 듯 다시 input type="text"로 바꿔주니 괜찮아짐 

 

@Tambo: yes, it's valid; if type is not supplied, or not recognised by the browser, then it defaults to type"=text". See: <input />. – David says reinstate Monica Sep 29 '14 at 11:57 

 

<input / > type="text" 를 넣지않아도 default값이 text 라는 걸 알게됨!!!굳 

 

 

 

6. check box로 한번에 삭제하기?

 

 

 

 

 

 

 

7. 글 수가 많아지면 pages 넘기기 ? 

참고해서 해보기 

gocoder.tistory.com/1064

 

Node.js - express 게시판 만들기 / 페이징 개발/ page

게시판 만들기 page 안녕하세요. 고코더 입니다. 이번 시간에는 게시판에 간단한 페이징을 구현합니다. 기존에 만든 리스트 페이지는 글이 추가되면 페이징 없이 아래로 노출되는 기본방식 입니

gocoder.tistory.com

 

 

 

 

 

8. 제목, 글쓴이, 내용에 null 값이면 글이 안써지도록 alert 띄우기 

JS 써야하는데그냥html 에 쓰면 되는것인가 ~~~~~~~~~~~~~~ 

잘 안되서 test.thtml 로 test해보기 

<!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>
</head>
<body>

    
    이름을 입력하세요 :  <input id="ad" class="dd" value="d">
    <button  onclick="aa()" >눌러쥬</button>

    <script type="text/javascript">
        function aa(){
            let content=document.getElementById("ad");
            console.log(content);

            if(content.value==""){
                // console.log(content.value);
                alert('입력해');        
            }
        
        }
    </script>
</body>
</html>

getElementByClassName 으로 가져옴
getElementById 로 가져옴

 

어찌저찌 성공

        function val (){
            let subject_tx = document.getElementById("subject_tx");
            let writer_tx = document.getElementById("writer_tx");
            let content_tx = document.getElementById("content_tx");

            if(subject_tx.value==""){
                alert("제목을 입력해주세요르레히호");
                event.preventDefault();
            } else if(writer_tx.value==""){
                alert("작성자를 입력해주세요");
                event.preventDefault();
            } else if(content_tx.value==""){
                alert("내용을 입력해주세요");
                event.preventDefault();
            }
        }
    </script>

 

배운 것 alert 이후 submit action 무력화시키기 ↓↓↓↓

blckchainetc.tistory.com/65

 

alert, confirm, prompt 이후 form submit action 제어하기 무력화 시키기

게시판 글쓰기에 제목, 작성자, 내용이 NULL 값, 빈값이라면 창을 띄워서 입력하라고 나오게 만들기 팝업창이 뜨고 확인버튼을 누르면 계속 뒤로 가기가 자동으로 되어서 (action="/writedone") 이 실행

blckchainetc.tistory.com

 

9. 글을 쓰면 db idx 가 123456 쭉 연결되서 뜨게 

 

node.js에 js함수, for문, html에 js넣기 등등 엄청 고민하다가 결국 검색함

mySQL에서 아래와 같은 어려운 명령어로 가상(?)의 필드명을 만드는 무언가를 만들었다. 

select *, @idx:=@idx+1 as idx2 from board,(select @idx:=0)A;

omg 

ㅠㅠㅠㅠㅠ

 ㅎ ㅏ 됐땅

 

server.js

app.get('/board',(req,res)=>{

    connection.query("select *, @idx:=@idx+1 as idx2, date_format(today, '%H:%m %m-%d-%Y ') as today, hit from board, (select @idx:=0)A", (error,results)=>{
        if(error){
            console.log(error);
        }else{
            res.render('board.html',{
                board_db:results,
            })
        }
    })
})

board.html

                    <table id="table1">
                        <tr id ="fields" class="tb">
                            <td class="td1">번호</td>
                            <td class="td2">제목</td>
                            <td class="td3">작성자</td>
                            <td class="td4">날짜</td>
                            <td class="td5">조회수</td>
                        </tr>
                        <tr class="tb">{% for item in board_db %}
                            <td class="td1">{{item.idx2}}</td>
                            <td  class="td2" id="aa"><a href="/view?idx={{item.idx}}">{{item.subject}}</a></td>
                            <td class="td3">{{item.writer}}</td>
                            <td class="td4">{{item.today}}</td>
                            <td class="td5">{{item.hit}}</td>
                        </tr>{% endfor %}
                    </table>

이렇게 하니까 중간 글을 삭제해도 1~부터 쭉 뜬다. 만세

 

 

 

 

10. 수정일, 등록일 따로따로 만들기 

먼저 column 1개 추가함

 

수정일, 등록일 따로 만들다가 분이 04 인걸 확인 

이상하다 싶어서 3시간동안 찾았는데 

분은 i였다.........................................................................

minute의 m 인줄알앗는데 생각해보니month도 m이야.....................................

 

i 문제만 아니면 생각보다 수월햇을거같다 

column 추가 하고 modify / write 부분만 intert query 명령문에 추가해주면되었음

 

 

11. checkbox 만들고 전체 선택 해제 가능하게 

여기서는

                 <span><input name="chk" type="checkbox" onclick="checkAll(this)"></span>

 

                        <tr class="tb">{% for item in board_db %}
                            <td class="td1"><input  name="chk" type="checkbox" ></td>
                            <td class="td1">{{item.idx2}}</td>
                            <td class="td2" id="aa"><a href="/view?idx={{item.idx}}">{{item.subject}}</a></td>
                            <td class="td3">{{item.writer}}</td>
                            <td class="td4">{{item.motoday}}</td>
                            <td class="td4">{{item.today}}</td>
                            <td class="td5">{{item.hit}}</td>
                        </tr>{% endfor %}

forEach로 돌아가는 td class 안에다가 name="chk"을 줘서 또 고생함. 

 

 

 

blckchainetc.tistory.com/66

 

input type checkbox 전체 선택 / 해제 JavaScript 로 만들기 getElementsByName 사용

Document 게시판 All 번호 제목 작성자 수정 날짜 작성 날짜 조회수 {% for item in board_db %} {{item.idx2}} {{item.subject}} {{item.writer}} {{item.motoday}} {{item.today}} {{item.hit}}..

blckchainetc.tistory.com

 

 

12. 체크박스에 체크된 rows 를 한번에 삭제하기 

-> 요거는 idx 오류가 해결되고 해야될거같음..

 

 

 

 

 

 

 

--------------------------------기능 구현 (삭제, 수정, db저장, 조회수 까지만) 한 소스----------------------

server.js

require('dotenv').config();
const express=require('express');
const app=express();
const nunjucks=require('nunjucks');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const port = process.env.SERVER_PORT || 3000;

nunjucks.configure('views',{
    express:app,
})

app.use(bodyParser.urlencoded({extended:false}));
app.set('view engine', 'html');
app.use(express.static('public'));

let connection = mysql.createConnection({
    host:process.env.DB_HOST,
    user:process.env.DB_USER,
    password:process.env.DB_PASSWORD,
    database:process.env.DB_DATABASE,
})

connection.connect();

app.get('/',(req,res)=>{
    res.render('index.html');
})

app.get('/board',(req,res)=>{

    connection.query("select idx, subject, writer, content, date_format(today, '%H:%m %m-%d-%Y ') as today, hit from board", (error,results)=>{
        if(error){
            console.log(error);
        }else{
            // console.log(results);
            res.render('board.html',{
                board_db:results,
            })
        }
    })
})

app.get('/write',(req,res)=>{
    res.render('write.html');
})

app.post('/writedone',(req,res)=>{
    let subject = req.body.subject;
    let writer=req.body.writer;
    let content=req.body.content;
    let sql=`insert into board (subject,writer,content, today, hit) values ('${subject}','${writer}','${content}', now(),0)`

    connection.query(sql,(error,results)=>{
        if(error){
            console.log(error);
        }else {
            // console.log(results);
            res.redirect('/board');  
        }
    })
    //여기 url을 /board로 바꾼다 -> render('board') 하지 않는 이유? render로 board.html로 넘어가면 db가 없다. 
})


//------------------ V I E W -------------------//

app.get('/view',(req,res)=>{
    let idx = req.query.idx;
    console.log(req.query);
    
    connection.query(`select * from board where idx='${idx}'`,(error,results)=>{
        if(error){
            console.log(error)
        }else{
            console.log(results)
            res.render('view.html',{
                view_db:results[0],
            });
        }
    })

    connection.query(`update board set hit=hit+1 where idx='${idx}'`);
    
})

app.get('/modify',(req,res)=>{

    let idx=req.query.idx;

    connection.query(`select * from board where idx=${idx}`,(error,results)=>{
        if(error){
            console.log(error)
        }else{
            console.log(results);
            res.render('modify.html',{
                modify_db:results[0],
            });
        }
    })
})

app.post('/modifydone',(req,res)=>{
    let idx = req.body.idx;
    console.log(req.body);
    let subject = req.body.subject;
    let writer = req.body.writer;
    let content = req.body.content;

    let sql = `update board set subject='${subject}', writer='${writer}', content='${content}', today=now() where idx='${idx}'`;

    connection.query(sql,(error,results)=> {
        if(error){
            console.log(error);
        }else{
            console.log(results);
            res.redirect('/board');
        }
    })
})

app.get('/delete',(req,res)=>{
    
    let idx=req.query.idx;
    let sql=`delete from board where idx='${idx}'`;
    connection.query(sql,(error,results)=>{
        if(error){
            console.log(error);
        }else{
            res.redirect('/board');
        }
    })
})



app.listen(3000,()=>{
    console.log('server start port : 3000')
})

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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>

    
    <h2>WELCOME! </h2>
    <a href="/board" >게시판 구경하기</a>





</body>
</html>

board.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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <h2>게시판</h2>
    <div>
        <table>
            <tr>
                <td>번호</td>
                <td>제목</td>
                <td>작성자</td>
                <td>날짜</td>
                <td>조회수</td>
            </tr>
            <tr>{% for item in board_db %}
                <td>{{item.idx}}</td>
                <td><a href="/view?idx={{item.idx}}">{{item.subject}}</a></td>
                <td>{{item.writer}}</td>
                <td>{{item.today}}</td>
                <td>{{item.hit}}</td>
            </tr>{% endfor %}
        </table>
        <button><a href="/">돌아가기</a></button>
        <button><a href="/write">글쓰기</a></button>
    </div>
</body>
</html>

modify.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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <h2> 글 수정하기 </h2>
    <form method="post" action="/modifydone">
        <span>글 번호</span>
        <input type="text" name="idx" value="{{modify_db.idx}}" readonly > <br/>
        <br/>
        <span>제목</span>
        <input type="text" name="subject" value="{{modify_db.subject}}"> <br/>
        <br/>
        <span>작성자</span>
        <input type="text" name="writer" value="{{modify_db.writer}}"> <br/>
        <br/>
        <spand>내용</span>
        <input type="text" name="content" value="{{modify_db.content}}"> <br/>
        <button><a href="/board">돌아가기</a></button>
        <input type="submit" value="글 수정 완료">
    </form>
</body>
</html>

view.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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <ul> <h2>VIEW PAGE </h2>
        <li>
            <span>글 번호 : </span>
            <span>{{view_db.idx}}</span>
        </li>
        <li>
            <span>글제목 : </span>
            <span>{{view_db.subject}}</span>
        </li>
        <li>
            <span>작성자 : </span>
            <span>{{view_db.writer}}</span>
        </li>
        <li>
            <span>내용</span>  
            <span>{{view_db.content}}</span>
        </li>
    </ul>
    <button><a href="/board">목록으로 돌아가기</a></button>
    <button><a href="/modify?idx={{view_db.idx}}">글 수정하기</a></button>
    <button><a href="/delete?idx={{view_db.idx}}">글 삭제하기</a></button>
</body>
</html>

write.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>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <ul> <h2>VIEW PAGE </h2>
        <li>
            <span>글 번호 : </span>
            <span>{{view_db.idx}}</span>
        </li>
        <li>
            <span>글제목 : </span>
            <span>{{view_db.subject}}</span>
        </li>
        <li>
            <span>작성자 : </span>
            <span>{{view_db.writer}}</span>
        </li>
        <li>
            <span>내용</span>  
            <span>{{view_db.content}}</span>
        </li>
    </ul>
    <button><a href="/board">목록으로 돌아가기</a></button>
    <button><a href="/modify?idx={{view_db.idx}}">글 수정하기</a></button>
    <button><a href="/delete?idx={{view_db.idx}}">글 삭제하기</a></button>
</body>
</html>

.env

SERVER_PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=5353
DB_DATABASE=homepage1

createTable.sql

CREATE DATABASE homepage1;
use homepage1;

CREATE TABLE board(
    idx INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    subject VARCHAR(100) NOT NULL,
    writer VARCHAR(50) NOT NULL,
    content text,
    today datetime default CURRENT_TIMESTAMP,
    hit INT(11)
) AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

 

 

 

-----------------------------------------          이 ㅈ  ㅔ C S S ㅎ ㅏ ㅈ ㅏ          ------------------------------------------

 

 

*{
    margin:0;
    padding:0;
    font-family: 'Gamja Flower', cursive;    

}



a{
    text-decoration: none;
    color:black;
    
}

a:hover{
    color:lightcoral;
}

ul,li{
    list-style: none;
}



/*         in COMMON         */




.wrap{
    width:100%;
    background-color: rgb(218, 157, 153);
}

.outerbox{
    width:100%;
    height:100%;
    
}

.innerbox{
    background-color: white;
    width:1000px;
    height:750px;
    border: 2px solid rgb(202, 202, 202);
    border-radius: 2px;
    position: absolute;
    left:50%;
    transform: translateX(-50%);
    top:8%;

}
#gogo{
    width:100px;
    height:50px;
    background-color: white;
    border-radius: 5px;
    padding:5px;
    box-sizing: border-box;
}

#gogo:hover{
    transition: .5s ease-in-out;
    background-color: darkseagreen;
    color:white;
}

.main{
    width:1000px;
    height:80px;
    text-align: center;
    font-size:50px;
    color:salmon;
    margin-top:30px;
}


.mainbox{
    width:1000px;
    height:550px;
    padding:20px;
}

.mainbox1{
    width:1000px;
    height:520px;
    padding:20px;
}

.btn{
    width:120px;
    height:40px;
    font-size: 16px;
    background-color: lightcoral;
    border-radius: 4px;
    border:1px solid lightcoral;
    color:white;
    align-items: center;
    margin-left: 20px;

}

.btn:hover{    
    color:lightcoral;
    background-color: white;
    border:2px solid lightcoral;
}

.btnbox{
    width:500px;
    height:50px;
    position: absolute;
    top: 660px;
    left: 54%;
    
}


.btn>a{
    padding:10px;
}



.subbox,.wribox{
    width:940px;
    height:40px;

}

.subsubbox{
    width:100px;
    height:40px;
    display: inline-block;
    float:left;
    text-align: center;
    padding: 0 0 0 7px;
    box-sizing: border-box;
}

.conbox{
    width:835px;
    height:400px;
    float:left;
    display: inline;
    border:1px solid darkslategray;
    text-align: left;
    padding:10px 0 0 7px;
    box-sizing: border-box;
}

.sub,.wri,.con{
    font-size: 20px;
    line-height: 35px;
    text-align: center;
}

.txbox{
    width:835px;
    height:35px;
    border:1px solid darkslategray;
    padding:5px;
    box-sizing: border-box;
    
}


input{
    width:100%;
    
}







/*          index            */

.welcome{
    width:1000px;
    height:200px;
    color:darkseagreen;
    text-align: center;
    padding:90px 0 0 0 ;
    font-size:70px;
    display:inline-block;
}

#gogobox{
    width:1000px;
    height:400px;
    padding:250px 0 0 550px;
    display:inline-block;
    box-sizing: border-box;
}

#gogo{
    font-size: 40px;
    text-align:center;
    color:darkslategray;

}





/*          board           */

#table1{
    border:1px solid rgba(221, 220, 220, 0.994);
    box-sizing: border-box;
    border-collapse:collapse;
}

#fields{
    color:rgb(48, 48, 48);
    font-size: 20px;
    text-align: center;
    background-color: rgb(255, 227, 232);
    font-weight: bold;
}   



td{
    text-align: center;
    border:1px solid rgba(221, 220, 220, 0.994);
    box-sizing: border-box;
}

#aa{
    text-align:center;
}

.td1{
    width:70px;
    height:40px;
    
}

.td2{
    width:400px;
    height:40px;
}

.td3{
    width:150px;
    height:40px;
}

.td4{
    width:200px;
    height:40px;
}

.td5{
    width:100px;
    height:40px;
}

 

JS

 

require('dotenv').config();
const express=require('express');
const app=express();
const nunjucks=require('nunjucks');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const port = process.env.SERVER_PORT || 3000;

nunjucks.configure('views',{
    express:app,
})

app.use(bodyParser.urlencoded({extended:false}));
app.set('view engine', 'html');
app.use(express.static('public'));

let connection = mysql.createConnection({
    host:process.env.DB_HOST,
    user:process.env.DB_USER,
    password:process.env.DB_PASSWORD,
    database:process.env.DB_DATABASE,
})

connection.connect();

app.get('/',(req,res)=>{
    res.render('index.html');
})

app.get('/board',(req,res)=>{

    connection.query("select idx, subject, writer, content, date_format(today, '%H:%m %m-%d-%Y ') as today, hit from board", (error,results)=>{
        if(error){
            console.log(error);
        }else{
            // console.log(results);
            res.render('board.html',{
                board_db:results,
            })
        }
    })
})

app.get('/write',(req,res)=>{
    res.render('write.html');
})

app.post('/writedone',(req,res)=>{
    let subject = req.body.subject;
    let writer=req.body.writer;
    let content=req.body.content;
    let sql=`insert into board (subject,writer,content, today, hit) values ('${subject}','${writer}','${content}', now(),0)`

    connection.query(sql,(error,results)=>{
        if(error){
            console.log(error);
        }else {
            // console.log(results);
            res.redirect('/board');  
        }
    })
    //여기 url을 /board로 바꾼다 -> render('board') 하지 않는 이유? render로 board.html로 넘어가면 db가 없다. 
})


//------------------ V I E W -------------------//

app.get('/view',(req,res)=>{
    let idx = req.query.idx;
    console.log(req.query);
    
    connection.query(`select * from board where idx='${idx}'`,(error,results)=>{
        if(error){
            console.log(error)
        }else{
            console.log(results)
            res.render('view.html',{
                view_db:results[0],
            });
        }
    })

    connection.query(`update board set hit=hit+1 where idx='${idx}'`);
    
})

app.get('/modify',(req,res)=>{

    let idx=req.query.idx;

    connection.query(`select * from board where idx=${idx}`,(error,results)=>{
        if(error){
            console.log(error)
        }else{
            console.log(results);
            res.render('modify.html',{
                modify_db:results[0],
            });
        }
    })
})

app.post('/modifydone',(req,res)=>{
    let idx = req.body.idx;
    console.log(req.body);
    let subject = req.body.subject;
    let writer = req.body.writer;
    let content = req.body.content;

    let sql = `update board set subject='${subject}', writer='${writer}', content='${content}', today=now() where idx='${idx}'`;

    connection.query(sql,(error,results)=> {
        if(error){
            console.log(error);
        }else{
            console.log(results);
            res.redirect('/board');
        }
    })
})

app.get('/delete',(req,res)=>{
    
    let idx=req.query.idx;
    let sql=`delete from board where idx='${idx}'`;
    connection.query(sql,(error,results)=>{
        if(error){
            console.log(error);
        }else{
            res.redirect('/board');
        }
    })
})



app.listen(3000,()=>{
    console.log('server start port : 3000')
})

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>
    <link rel="stylesheet" href="./index.css">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">
                <h2 class="welcome">WELCOME!</h2> 
                <div id = "gogobox">
                    <a  id="gogo" href="/board" >게시판 구경하기</a>
                </div>
            </div>
        </div>
    </div>


</body>
</html>

board.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>
    <link rel="stylesheet" href="./index.css">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">
                <h2 class="main">게시판</h2>
                <div class="mainbox">
                    <table id="table1">
                        <tr id ="fields" class="tb">
                            <td class="td1">번호</td>
                            <td class="td2">제목</td>
                            <td class="td3">작성자</td>
                            <td class="td4">날짜</td>
                            <td class="td5">조회수</td>
                        </tr>
                        <tr class="tb">{% for item in board_db %}
                            <td class="td1">{{item.idx}}</td>
                            <td  class="td2" id="aa"><a href="/view?idx={{item.idx}}">{{item.subject}}</a></td>
                            <td class="td3">{{item.writer}}</td>
                            <td class="td4">{{item.today}}</td>
                            <td class="td5">{{item.hit}}</td>
                        </tr>{% endfor %}
                    </table>
                    <div class="btnbox">
                        <button class="btn"><a href="/">돌아가기</a></button>
                        <button class="btn"><a href="/write">글쓰기</a></button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

 

write.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>
    <link rel="stylesheet" href="./index.css">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">
                <h2 class="main"> 글 작성하기</h2>
                <form method="post" action="/writedone">

                    <div class="mainbox">
                        <div class="subbox">
                            <div class="subsubbox">
                                <span class="sub">제목 :</span>
                            </div>
                            <input class ="txbox" type="text" name="subject"> 

                        </div>
                        <div class="wribox">
                                <div class="subsubbox">
                            <span class="wri">작성자 :</span>
                                </div>
                            <input class = "txbox" type="text" name="writer">
                            <br/>
                        </div>
                        <div class="d">
                            <div class="subsubbox">
                                <span class="con">내용 :</span>
                            </div>
                            <input class = "conbox" type="text" name="content"> 
                                    
                        </div>
                    </div>

                    <div class="btnbox">       
                        <button class="btn"><a href="/board">돌아가기</a></button>
                        <input class ="btn" type="submit" value="글작성">
                    </div> 
                </form>
            </div>
        </div>
    </div>
</body>
</html>

 

view.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>
    <link rel="stylesheet" href="./index.css">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">

                    <h2 class="main">VIEW PAGE </h2>
                    <div class="mainbox1">
                            <div class="subbox">
                                <div class="subsubbox">
                                    <span class="sub">글 번호 :</span>
                                </div>
                                <input class ="txbox" type="text" name="subject" readonly value="{{view_db.idx}}"> 
    
                            </div>
                            <div class="subbox">
                                <div class="subsubbox">
                                    <span class="sub">제목 :</span>
                                </div>
                                <input class ="txbox" type="text" name="subject" readonly  value="{{view_db.subject}}"> 
    
                            </div>
                            <div class="wribox">
                                    <div class="subsubbox">
                                <span class="wri">작성자 :</span>
                                    </div>
                                <input class = "txbox" type="text" name="writer" readonly  value="{{view_db.writer}}">
                                <br/>
                            </div>
                            <div class="d">
                                <div class="subsubbox">
                                    <span class="con">내용 :</span>
                                </div>
                                <textarea class = "conbox" type="text"  readonly  name="content">{{view_db.content}} 
                                    </textarea>    
                            </div>
                    </div>

                <div class="btnbox" class="btnbox3">   
                    <button class="btn"><a href="/board">뒤로가기</a></button>
                    <button class="btn"><a href="/modify?idx={{view_db.idx}}">글 수정하기</a></button>
                    <button class="btn"><a href="/delete?idx={{view_db.idx}}">글 삭제하기</a></button>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

modify.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>
    <link rel="stylesheet" href="./index.css">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
</head>
<body>
    <h2> 글 수정하기 </h2>
    <form method="post" action="/modifydone">
        <span>글 번호</span>
        <input type="text" name="idx" value="{{modify_db.idx}}" readonly > <br/>
        <br/>
        <span>제목</span>
        <input type="text" name="subject" value="{{modify_db.subject}}"> <br/>
        <br/>
        <span>작성자</span>
        <input type="text" name="writer" value="{{modify_db.writer}}"> <br/>
        <br/>
        <spand>내용</span>
        <input type="text" name="content" value="{{modify_db.content}}"> <br/>
        <button><a href="/board">돌아가기</a></button>
        <input type="submit" value="글 수정 완료">
    </form>
</body>
</html>

 

 

.env, createTable.sql 는 위와 동일함

 

 

 

 

=====================다른 기능 추가한 최종 결과========================

추가한 기능 :

1.  게시판 번호 순서대로(삭제해도 순서대로 나오게) 

2. 제목, 작성자, 내용을 안쓰면 alert 떠서 입력해야 글이 저장 및 수정되게 

3. write, modify 페이지에서 enter 누르면 바로 submit안되게

기타등등...

 

require('dotenv').config();
const express=require('express');
const app=express();
const nunjucks=require('nunjucks');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const port = process.env.SERVER_PORT || 3000;

nunjucks.configure('views',{
    express:app,
})

app.use(bodyParser.urlencoded({extended:false}));
app.set('view engine', 'html');
app.use(express.static('public'));

let connection = mysql.createConnection({
    host:process.env.DB_HOST,
    user:process.env.DB_USER,
    password:process.env.DB_PASSWORD,
    database:process.env.DB_DATABASE,
})

connection.connect();

app.get('/',(req,res)=>{
    res.render('index.html');
})

app.get('/board',(req,res)=>{

    connection.query("select *, date_format(today, '%H:%i %d.%m.%Y') as today, date_format(motoday, '%H:%i %d.%m.%Y') as motoday, @idx:=@idx+1 as idx2 from board, (select @idx:=0)A", (error,results)=>{
        if(error){
            console.log(error);
        }else{
            res.render('board.html',{
                board_db:results,
            })
        }
    })
})

app.get('/write',(req,res)=>{
    res.render('write.html');
})

app.post('/writedone',(req,res)=>{
    let subject = req.body.subject;
    let writer=req.body.writer;
    let content=req.body.content;
    let sql=`insert into board (subject,writer,content, today, hit) values ('${subject}','${writer}','${content}', now(),0)`

    connection.query(sql,(error,results)=>{
        if(error){
            console.log(error);
        }else {
            // console.log(results);
            res.redirect('/board');  
        }
    })
    //여기 url을 /board로 바꾼다 -> render('board') 하지 않는 이유? render로 board.html로 넘어가면 db가 없다. 
})


//------------------ V I E W -------------------//

app.get('/view',(req,res)=>{
    let idx = req.query.idx;
    console.log(idx);
    
    connection.query(`select * from board where idx='${idx}'`,(error,results)=>{
        if(error){
            console.log(error)
        }else{
            console.log(results)
            res.render('view.html',{
                view_db:results[0],
                
            });
        }
    })

    connection.query(`update board set hit=hit+1 where idx='${idx}'`);
    
})

app.get('/modify',(req,res)=>{

    let idx=req.query.idx;

    connection.query(`select * from board where idx=${idx}`,(error,results)=>{
        if(error){
            console.log(error)
        }else{
            console.log(results);
            res.render('modify.html',{
                modify_db:results[0],
            });
        }
    })
})

app.post('/modifydone',(req,res)=>{
    let idx = req.body.idx;
    console.log(req.body);
    let subject = req.body.subject;
    let writer = req.body.writer;
    let content = req.body.content;

    let sql = `update board set subject='${subject}', writer='${writer}', content='${content}', motoday=now() where idx='${idx}'`;

    connection.query(sql,(error,results)=> {
        if(error){
            console.log(error);
        }else{
            console.log(results);
            res.redirect('/board');
        }
    })
})

app.get('/delete',(req,res)=>{
    
    let idx=req.query.idx;
    let sql=`delete from board where idx='${idx}'`;
    connection.query(sql,(error,results)=>{
        if(error){
            console.log(error);
        }else{
            res.redirect('/board');
        }
    })
})



app.listen(3000,()=>{
    console.log('server start port : 3000')
})

 

 

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>
    <link rel="stylesheet" href="./index.css">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">
                <h2 class="welcome">WELCOME!</h2> 
                <div id = "gogobox">
                    <a  id="gogo" href="/board" >게시판 구경하기</a>
                </div>
            </div>
        </div>
    </div>


</body>
</html>

 

 

 

board.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>
    <link rel="stylesheet" href="./index.css">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">

</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">
                <h2 class="main">게시판</h2>
                <div class="mainbox">
                    <table id="table1">
                        <tr id ="fields" class="tb">
                            <td class="td0">
                                <span>All</span>
                                <span><input name="chk" type="checkbox" onclick="checkAll(this)"></span>
                                
                            </td>
                            <td class="td1">번호</td>
                            <td class="td2">제목</td>
                            <td class="td3">작성자</td>
                            <td class="td4">수정 날짜</td>
                            <td class="td4">작성 날짜</td>
                            <td class="td5">조회수</td>
                        </tr>
                        <tr class="tb">{% for item in board_db %}
                            <td class="td0"><input  name="chk" type="checkbox" ></td>
                            <td class="td1">{{item.idx2}}</td>
                            <td class="td2" id="aa"><a href="/view?idx={{item.idx}}">{{item.subject}}</a></td>
                            <td class="td3">{{item.writer}}</td>
                            <td class="td4">{{item.motoday}}</td>
                            <td class="td4">{{item.today}}</td>
                            <td class="td5">{{item.hit}}</td>
                        </tr>{% endfor %}
                    </table>
                    <div class="btnbox">
                        <button class="btn"><a href="/">돌아가기</a></button>
                        <button class="btn"><a href="/write">글쓰기</a></button>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script type="text/javascript">
        let check = false;
        // function checkAll(){
        //     let chk = document.getElementsByName("chk[]");
        //     console.log(chk);
        //     if(check==false){
        //         check=true;
        //         for(let i=0; i<chk.length; i++){
        //             chk[i].checked=true;
        //         }
        //     }else{
        //         check=false;
        //         for(let i=0; i<chk.length; i++){
        //             chi[i].checked=false;
        //         }
        //     }
        // }

        function checkAll(checkAll){
            let checkboxes=document.getElementsByName("chk");
            console.log(checkboxes);
            checkboxes.forEach((checkbox)=>{
                checkbox.checked=checkAll.checked;
            })
        }
    
    </script>
</body>
</html>

 

 

view.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>
    <link rel="stylesheet" href="./index.css">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">

                    <h2 class="main">VIEW PAGE </h2>
                    <div class="mainbox1">
                            <div class="subbox">
                                <div class="subsubbox">
                                    <span class="sub">글 번호 :</span>
                                </div>
                                <input class ="txbox" type="text" name="subject" disabled value="{{view_db.idx}}"> 
    
                            </div>
                            <div class="subbox">
                                <div class="subsubbox">
                                    <span class="sub">제목 :</span>
                                </div>
                                <input class ="txbox" type="text" name="subject"  disabled  value="{{view_db.subject}}"> 
    
                            </div>
                            <div class="wribox">
                                    <div class="subsubbox">
                                <span class="wri">작성자 :</span>
                                    </div>
                                <input class = "txbox" type="text" name="writer"  disabled  value="{{view_db.writer}}">
                                <br/>
                            </div>
                            <div class="d">
                                <div class="subsubbox">
                                    <span class="con">내용 :</span>
                                </div>
                                <input class = "conbox" type="text"   disabled  name="content" value="{{view_db.content}} ">
                                   
                            </div>
                    </div>

                <div class="btnbox" class="btnbox3">   
                    <button class="btn"><a href="/board">뒤로가기</a></button>
                    <button class="btn"><a href="/modify?idx={{view_db.idx}}">글 수정하기</a></button>
                    <button class="btn"><a href="/delete?idx={{view_db.idx}}">글 삭제하기</a></button>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

 

 

modify.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>
    <link rel="stylesheet" href="./index.css">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
    <script type="text/javascript">
        function val (){
            let subject_tx = document.getElementById("subject_tx");
            let writer_tx = document.getElementById("writer_tx");
            let content_tx = document.getElementById("content_tx");

            if(subject_tx.value==""){
                alert("제목을 입력해주세요르레히호");
                event.preventDefault();
            } else if(writer_tx.value==""){
                alert("작성자를 입력해주세요");
                event.preventDefault();
            } else if(content_tx.value==""){
                alert("내용을 입력해주세요");
                event.preventDefault();
            }
        }
    </script>
</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">
                <h2 class="main"> 글 수정하기 </h2>
                <form method="post" action="/modifydone">
                    <button disabled type=submit onclick="return flase;" style="display:none;"></button> <!--enter하면 입력되지 않도록 방지-->
                    <div class="mainbox">
                        <div class="subbox">
                            <div class="subsubbox">
                                <span class="sub">글 번호 :</span>
                            </div>
                            <input class="txbox" type="text" name="idx" value="{{modify_db.idx}}" readonly >
                        </div>
                        <div class="subbox">
                            <div class="subsubbox">
                                <span class="sub">제목 :</span>
                            </div>
                            <input id ="subject_tx" class="txbox" type="text" name="subject" value="{{modify_db.subject}}"> 
                        </div>
                        <div class="wribox">
                            <div class="subsubbox">
                                <span class="wri">작성자 :</span>
                            </div>
                            <input id="writer_tx" class="txbox" type="text" name="writer" value="{{modify_db.writer}}"> 
                        </div>
                        <div class="d">
                            <div class="subsubbox">
                                <span class="con">내용 :</span>
                            </div>
                            <input id="content_tx" class="conbox" type="text" name="content" value="{{modify_db.content}}"> 
                        </div>
                    </div>


                    <div class ="btnbox">
                        <button class ="btn"><a href="/board">돌아가기</a></button>
                        <input class ="btn" type="submit" value="글 수정 완료" onclick="val()">
                    </div>
                    </form>
                </div>

            </div>
        </div>
    </div>
</body>
</html>

 

 

write.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>
    <link rel="stylesheet" href="./index.css">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
    <script type="text/javascript">
        function val (){
            let subject_tx = document.getElementById("subject_tx");
            let writer_tx = document.getElementById("writer_tx");
            let content_tx = document.getElementById("content_tx");

            if(subject_tx.value==""){
                alert("제목을 입력해주세요르레히호");
                event.preventDefault();
            } else if(writer_tx.value==""){
                alert("작성자를 입력해주세요");
                event.preventDefault();
            } else if(content_tx.value==""){
                alert("내용을 입력해주세요");
                event.preventDefault();
            }
        }
        function enter(){
            if(window.event.keyCode ==13){
                alert("d");
            document.getElementsByName("content").innerHTML+="<br/>";
        }
    }
    </script>
</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">
                <h2 class="main"> 글 작성하기</h2>
                <form method="post"  action="/writedone">
                    <button type=submit name = "name" disabled onclick="enter()"; style="display:none;"></button> enter하면 입력되지 않도록 방지
                    <div class="mainbox">
                        <div class="subbox">
                            <div class="subsubbox">
                                <span class="sub">제목 :</span>
                            </div>
                            <input id="subject_tx" class ="txbox" type="text" name="subject"> 

                        </div>
                        <div class="wribox">
                                <div class="subsubbox">
                            <span class="wri">작성자 :</span>
                                </div>
                            <input id="writer_tx" class = "txbox" type="text" name="writer">
                            <br/>
                        </div>
                        <div class="d">
                            <div class="subsubbox">
                                <span class="con">내용 :</span>
                            </div>
                            <input id="content_tx" onckeyup="enter()" class = "conbox" type="textbox" name="content"> 
                                    
                        </div>
                    </div>

                    <div class="btnbox">       
                        <button class="btn"><a href="/board">돌아가기</a></button>
                        <input class ="btn" type="submit" value="글작성" onclick="val()">
                    </div> 
                </form>
            </div>
        </div>
    </div>

</body>
</html>

 

index.css

*{
    margin:0;
    padding:0;
    font-family: 'Gamja Flower', cursive;    

}



a{
    text-decoration: none;
    color:black;
    
}

a:hover{
    color:lightcoral;
}

ul,li{
    list-style: none;
}



/*         in COMMON         */




.wrap{
    width:100%;
    background-color: rgb(218, 157, 153);
}

.outerbox{
    width:100%;
    height:100%;
    
}

.innerbox{
    background-color: white;
    width:1080px;
    height:750px;
    border: 2px solid rgb(202, 202, 202);
    border-radius: 2px;
    position: absolute;
    left:50%;
    transform: translateX(-50%);
    top:8%;

}
#gogo{
    width:100px;
    height:50px;
    background-color: white;
    border-radius: 5px;
    padding:5px;
    box-sizing: border-box;
}

#gogo:hover{
    transition: .5s ease-in-out;
    background-color: darkseagreen;
    color:white;
}

.main{
    width:1080px;
    height:80px;
    text-align: center;
    font-size:50px;
    color:salmon;
    margin-top:30px;
}


.mainbox{
    width:1000px;
    height:550px;
    padding:20px 20px 20px 38px;
}

.mainbox1{
    width:1000px;
    height:520px;
    padding:20px;
}

.btn{
    width:120px;
    height:40px;
    font-size: 16px;
    background-color: lightcoral;
    border-radius: 4px;
    border:1px solid lightcoral;
    color:white;
    align-items: center;
    margin-left: 20px;

}

.btn:hover{    
    color:lightcoral;
    background-color: white;
    border:2px solid lightcoral;
}

.btnbox{
    width:500px;
    height:50px;
    position: absolute;
    top: 660px;
    left: 54%;
    
}


.btn>a{
    padding:10px;
}



.subbox,.wribox{
    width:940px;
    height:40px;

}

.subsubbox{
    width:100px;
    height:40px;
    display: inline-block;
    float:left;
    text-align: center;
    padding: 0 0 0 7px;
    box-sizing: border-box;
}

.conbox{
    width:835px;
    /* height:400px; */
    float:left;
    display: inline;
    border:1px solid darkslategray;
    text-align: left;
    padding:10px 0 350px 7px;
    box-sizing: border-box;
}

.sub,.wri,.con{
    font-size: 20px;
    line-height: 35px;
    text-align: center;
}

.txbox{
    width:835px;
    height:35px;
    border:1px solid darkslategray;
    padding:5px;
    box-sizing: border-box;
    
}


input{
    width:100%;
    
}







/*          index            */

.welcome{
    width:1000px;
    height:200px;
    color:darkseagreen;
    text-align: center;
    padding:90px 0 0 0 ;
    font-size:70px;
    display:inline-block;
}

#gogobox{
    width:1000px;
    height:400px;
    padding:250px 0 0 550px;
    display:inline-block;
    box-sizing: border-box;
}

#gogo{
    font-size: 40px;
    text-align:center;
    color:darkslategray;

}





/*          board           */

#table1{
    border:1px solid rgba(221, 220, 220, 0.994);
    box-sizing: border-box;
    border-collapse:collapse;
}

#fields{
    color:rgb(48, 48, 48);
    font-size: 20px;
    text-align: center;
    background-color: rgb(255, 227, 232);
    font-weight: bold;
}   



td{
    text-align: center;
    border:1px solid rgba(221, 220, 220, 0.994);
    box-sizing: border-box;
}

#aa{
    text-align:center;
}


.td0{
    width:100px;
    height:40px;
    padding:9px 0;
}
.td0>span>input{
    width:15px;

}

.td1{
    width:70px;
    height:40px;
    
}


.td2{
    width:400px;
    height:40px;
}

.td3{
    width:150px;
    height:40px;
}

.td4{
    width:200px;
    height:40px;
}

.td5{
    width:100px;
    height:40px;
}




/*                       */










/*                       */









/*                       */










/*                       */

 

.env

SERVER_PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=5353
DB_DATABASE=homepage1

 

createTable.sql

CREATE DATABASE homepage1;
use homepage1;

CREATE TABLE board(
    idx INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    subject VARCHAR(100) NOT NULL,
    writer VARCHAR(50) NOT NULL,
    content text,
    today datetime default CURRENT_TIMESTAMP,
    hit INT(11)
) AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

 

 

 

------------------------------------------------------------주말끗---------------------------------------------------------

pages , idx오류, 등 아직 고칠게 있다

글쓴걸 보면 어디서 고생햇는지 나온다

최종 결과물

 

 

 

 

--------------------------------------------------------------------------------------------------------------------

 

node.js 가벼운 웹서버 구축 ? 콜백 기반이라 커지면 유지개발이 어려워지는 듯? 

API 가 자주 바뀌는게 risk? 

node.js 에 대해 이해 필요함 

 

aws.amazon.com/ko/microservices/

 

마이크로서비스란 무엇입니까? | AWS

마이크로서비스의 경우 각 서비스가 지원하는 애플리케이션 기능의 수요를 충족하도록 해당 서비스를 독립적으로 확장할 수 있습니다. 따라서 팀은 필요한 인프라의 규모를 적절히 조절하고,

aws.amazon.com

 

 

---------------------------------------------------질문------------------------------------------------

 

1. JS 가 head쪽에 쓰일 때 언제 안되는거지? 무슨 함수같은걸 써서 head에서 썼는데 왜 안썼는데도 ㅇ되는건지 궁금 

<!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>
    <link rel="stylesheet" href="./index.css">
    <link href="https://fonts.googleapis.com/css2?family=Gaegu&family=Gamja+Flower&display=swap" rel="stylesheet">
    <script type="text/javascript">
        function val (){
            let subject_tx = document.getElementById("subject_tx");
            let writer_tx = document.getElementById("writer_tx");
            let content_tx = document.getElementById("content_tx");

            if(subject_tx.value==""){
                alert("제목을 입력해주세요르레히호");
                event.preventDefault();
            } else if(writer_tx.value==""){
                alert("작성자를 입력해주세요");
                event.preventDefault();
            } else if(content_tx.value==""){
                alert("내용을 입력해주세요");
                event.preventDefault();
            }
        }
    </script>
</head>
<body>
    <div class="wrap">
        <div class="outerbox" >
            <div class="innerbox">
                <h2 class="main"> 글 작성하기</h2>
                <form method="post"  action="/writedone">

                    <div class="mainbox">
                        <div class="subbox">

-> 함수라서 된거였음 

 

 

2. date_format(today, '%H:%m %m-%d-%Y ') as today, 

해석 ? 

today라는 colomn 의 데이터포멧을 '%H....'으로 하고 이름은 today이다. 

-> today column 이 변하는게 아닌 그냥 sub coulmn 을 만드는거같은데 맞는지 

 

 

3.  select *, @idx:=@idx+1 as idx2 from board,(select @idx:=0)A; 

뜻 점검 -> idx라는 field 에 1씩 추가해 그리고 이름은 idx2로 만들고 @idx 는 0부터 시작이야 A는 뭐야. .

idx 값은  글 번호 로 쓰기엔 좀 그럼. 글 번호는 z-> a 로 해야.. 

 

 

 

 

4. board.index 의 checkbox 함수 (this) 

 

this -> parameter? 의 기능 은? ? 

this 자리에 아무거나 써도 되고 function checkbox(checkbox) 괄호 안 인자값으로  놓겠다. >?

 

 

 

5. textbox안에 엔터가 안됨 write.html, modify.html

왜 일 까

textbox, text, textarea 다 안됨 

textarea 된다.. 

 

 

 

6. view.html에서, modify.html에서 index 이전 index 수정 -> new로 안됨. 

난관..

 

 

 

7. mysql export 명령어 다 안됨

 

Enter password: ****
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 24
Server version: 10.5.9-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> Ctrl-C -- exit!
Bye

C:\Windows\system32>
C:\Windows\system32>
C:\Windows\system32>mysqldump -uroot -p5353 -no-create homepage1 board > insert.sql
'mysqldump'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는
배치 파일이 아닙니다.

C:\Windows\system32>cd C:
C:\Windows\System32

C:\Windows\system32>cd "C:\Program Files"

C:\Program Files>cd "MariaDB 10.5"

C:\Program Files\MariaDB 10.5>cd bin

C:\Program Files\MariaDB 10.5\bin>mysqldump -uroot -p5353 -no-create homepage1 board > insert.sql
mysqldump: unknown option '-o'

C:\Program Files\MariaDB 10.5\bin>mysqldump -uroot -p5353 homepage1 board > insert.sql

C:\Program Files\MariaDB 10.5\bin>

 

 

 mysql 작업관리자로 열어서 파일 경로 지정을 한후 위의 명령어 입력하ㅣ면 해당 경로에 .slq 파일이 저장되어 있음

 

아래는 export 한 sql 파일

 

-- MariaDB dump 10.19  Distrib 10.5.9-MariaDB, for Win64 (AMD64)
--
-- Host: localhost    Database: homepage1
-- ------------------------------------------------------
-- Server version	10.5.9-MariaDB

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `board`
--

DROP TABLE IF EXISTS `board`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `board` (
  `idx` int(11) NOT NULL AUTO_INCREMENT,
  `subject` varchar(100) NOT NULL,
  `writer` varchar(50) NOT NULL,
  `content` text DEFAULT NULL,
  `motoday` datetime DEFAULT NULL,
  `today` datetime DEFAULT current_timestamp(),
  `hit` int(11) DEFAULT NULL,
  PRIMARY KEY (`idx`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `board`
--

LOCK TABLES `board` WRITE;
/*!40000 ALTER TABLE `board` DISABLE KEYS */;
INSERT INTO `board` VALUES (1,'공지사항입니다.','주인장','구라입니다.','2021-04-26 09:31:25','2021-04-26 09:29:42',1),(4,'월욜 아침이다.','졸리다','ㅠㅠ',NULL,'2021-04-26 09:31:00',1),(5,'또 공지사항입니다.','그만','그만~~~~~~~',NULL,'2021-04-26 09:31:55',2),(6,'공지사항있다규','ㅠㅠ','수정이닷 ','2021-04-26 10:25:16','2021-04-26 09:32:17',2),(7,'졸립니다.','졸리다','졸리다규','2021-04-26 10:25:23','2021-04-26 09:32:29',10),(8,'페이징','은','어떻게하지',NULL,'2021-04-26 09:32:40',2),(9,'테스트 할거야','테스트인','얏호',NULL,'2021-04-26 11:43:04',0),(10,'ㅇㅇ','ㅇㅇ','ㅇㅇㅇㅇㅇㅇ','2021-04-26 11:44:02','2021-04-26 11:43:56',1),(11,'이건 write console.log를 위한 ','글이다.',' 곧 점심이닷 ',NULL,'2021-04-26 11:49:55',0),(12,'몇번쨰야','대체','그만',NULL,'2021-04-26 12:11:20',1),(13,'ㅇ','ㄷㅇ','ㅇ ㅇㅇㅇㅇ',NULL,'2021-04-26 12:37:54',0);
/*!40000 ALTER TABLE `board` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2021-04-26 12:45:48

 

여기서 저기 insert 긴 글을 입력하면 됨 

 

 

 

 

 

 

 

 

 

 

 

 

반응형