본문 바로가기

Web-Node.js/간단한 익명게시판 만들기

3. 각 화면 구성

레이아웃 엔진은 ejs를 사용하였습니다.

ejs는 views폴더안에  js파일은 js폴더안 css는 style폴더 안에 넣어줬습니다.

board.ejs - 글들을 보여주는 화면입니다.

<html>
    <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">
        <link rel="stylesheet" href="/style/board.css">
        <title>문의 게시판</title>

    </head>
    <body>
        <div class="head">
            <h2>예제 게시판!!</h2>
            <p>CRUD 예제 익명 게시판 입니다용!</p>
        </div>

        <div class="content">
            <table border='1' id="list">
                <colgroup>
                    <col style="width: 10%;">
                    <col style="width: 50%;">
                    <col style="width: 20%;">
                    <col style="width: 20%;">
                </colgroup>
                <thead>
                    <tr>
                        <th>순번</th>
                        <th>제목</th>
                        <th>작성자</th>
                        <th>작성일</th>
                    </tr>
                </thead>

                <tbody >

                    <% for(i = 0; i < list.length; i++) { %>
                        <tr>
                            <td name="order"><%=i+1 %></td>
                            <td>
                                <a href="/read/<%=list[i].id %>"><%=list[i].title %></a>
                            </td>
                            <td name="name"><%=list[i].writer%></td>
                            <td><%=list[i].date%>
                            </td>
                        </tr>
                    <% } %>
                </tbody>

            </table boader='1'>

            <button id="btn_write" onclick="location.href='../write'">글쓰기</button>
        </div>

        <script src="/js/board.js"></script>
    </body>
</html>

 

board.css

@import url('https://fonts.googleapis.com/css2?family=Nanum+Gothic:wght@800&display=swap');


.head {
    font-family: 'Nanum Gothic', sans-serif;
    border-top-left-radius: 20px;
    border-top-right-radius: 20px;
    color: white;
    background-color: #a7acf1;
    height: 250px;
    width: 1300px;
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: auto;
    padding: 0px;
    
}

.head h2 {
    padding-bottom: 10px;
    font-size: 40px;
    border-bottom: 2px solid white;
}
.head p {
    font-size: 30px;
}

.content {
    font-family: 'Nanum Gothic', sans-serif;
    height: 800px;
    background-color: rgb(220, 247, 255);
    width: 1300px;
    display: flex;
    margin: auto;
    flex-direction: column;
    align-items: center;
}

table {
    margin-top: 30px;
    font-size: 15px;
    font-weight: bold;
    width: 1200px;
    
}
tr{
    text-align: center;
}

#btn_write {
    border-radius: 20px;
    font-weight: bold;
    font-size: large;
    height: 50px;
    margin-top: 150px;
    width: 600px;
 
}
th{
    padding: 10px;
    font-size: 20px;
}
td{
    font-size: 15px;
}
td a{
    text-decoration: none;
}


@media(min-width: 320px) and (max-width: 480px){


    .head {
        border-top-left-radius: 20px;
        border-top-right-radius: 20px;
        color: white;
        background-color: #a7acf1;
        height: 250px;
        width: 412px;
        display: flex;
        flex-direction: column;
        align-items: center;
        margin: auto;
        padding: 0px;
        
    }
    
    .head h2 {
        padding-bottom: 10px;
        font-size: 40px;
        border-bottom: 2px solid white;
    }
    .head p {
        font-size: 25px;
    }
    
    .content {
        height: 800px;
        background-color: rgb(220, 247, 255);
        width: 412px;
        display: flex;
        margin: auto;
        flex-direction: column;
        align-items: center;
    }
    
    table {
        margin-top: 30px;
        font-size: 15px;
        font-weight: bold;
        width: 412px;
        
    }
    tr{
        text-align: center;
    }
    
    #btn_write {
        border-radius: 20px;
        font-weight: bold;
        font-size: large;
        height: 50px;
        margin-top: 150px;
        width: 400px;
     
    }
    th{
        padding: 10px;
        font-size: 20px;
    }
    td{
        font-size: 15px;
    }
    td a{
        text-decoration: none;
    }
    
}

 

 

write.ejs - 글쓰기 버튼을 눌럿을 시 글 작성 화면입니다.

<html>
    <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">
        <link rel="stylesheet" href="/style/write.css">
        <title>글쓰기</title>
    </head>
    <body>
        <form name ='write_form' action='/writeAf' method='post'>
            <div class="content">
                <h2>게시글 작성</h2>
            
                    <div class="input_type">  
                        <label id="label_title"> 제목</label>
                        <input id="input_title" name = "title" type="text"> 
                    </div>

                    <div class="input_type">  
                        <label> 작성자</label>
                        <input id="input_writer"  name = "writer" type="text"> 
                    </div>

                    <div class="input_type">  
                        <label> 내용</label>
                        <textarea id="input_text" style="font-size: 15px;" name="context" id="" cols="70" rows="20"></textarea>
                    
                    </div>

                    <div class="input_type">  
                        <label  > 비밀번호</label>
                        <input  id ="input_password" name = "password" type="password"> 
                    </div>

                    <p style="font-size: 10px;">나쁜말 작성 시 사전동의 없이 삭제 될 수 있습니다.</p>
                    <p style="font-size: 10px;">비밀번호 분실 시에는 전화주세욧!.</p>
                
                
                    <button type="button" id='btn_submit'>글쓰기</button>
            </div>
        </form>
        
      <script src="/js/write.js"></script>
    </body>
</html>

 

write.css

h2 {
    text-align: center;
    width: 100%;
    border-bottom: 2px solid lightgray;
    padding-bottom: 10px;
}

.content {
    font-family: 'Nanum Gothic', sans-serif;
    padding: 20px;
    border: rgb(88, 86, 86) solid 2px;
    font-size: 30px;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 700px;
    margin: auto;
    justify-content: space-evenly;
}

.input_type {
    border-bottom: 1px solid lightgray;
    width: 100%;
    padding-bottom: 10px;
    font-size: 20px;
    font-weight: bold;
    display: flex;
    align-items: center;
    margin-bottom: 30px;
    justify-content: flex-start;
}

#label_title {
    margin-right: 20px;
}

#input_password {
    margin-left: 120px;
}

.input_type input {
    font-size: 20px;
    width: 400px;
    margin-left: 140px;
}

.input_type textarea {
    font-family: 'Nanum Gothic', sans-serif;
    font-size: 20px;
    width: 400px;
    margin-left: 160px;
    resize: none;
}

#btn_submit {
    margin-top: 30px;
    border-radius: 20px;
    font-size: 20px;
    width: 100px;
}

@media(min-width: 320px) and (max-width: 480px) {

    h2 {
        text-align: center;
        width: 100%;
        border-bottom: 2px solid lightgray;
        padding-bottom: 10px;
    }

    .content {
        height: 100%;
        border: rgb(88, 86, 86) solid 2px;
        font-size: 30px;
        display: flex;
        flex-direction: column;
        align-items: center;
        width: 390px;
        margin: auto;
        justify-content: space-evenly;
    }

    .input_type {
        border-bottom: 1px solid lightgray;
        width: 412px;
        padding-bottom: 10px;
        font-size: 15px;
        font-weight: bold;
        display: flex;
        align-items: center;
        margin-bottom: 30px;

    }

    #label_title {
        margin-right: 20px;
    }

    .input_type input {
        font-size: 15px;
        width: 200px;
        margin-left: 50px;
    }

    .input_type textarea {
        font-weight: bold;
        font-size: 15px;
        width: 300px;
        margin-left: 30px;
        resize: none;
    }

    #btn_submit {
        margin-top: 30px;
        border-radius: 20px;
        font-size: 20px;
        width: 100px;

    }

}

write.js

const btn_submit =  document.getElementById("btn_submit");
const title = document.getElementById("input_title");
const writer = document.getElementById("input_writer");
const text = document.getElementById("input_text");
const password = document.getElementById('input_password');

btn_submit.addEventListener('click',function(){
    if(!text.value) {
        alert("내용을 입력해주세요");
    }
    else if(!title.value){
        alert("제목을 입력해주세요");
    }
    else if(!writer.value){
        alert("작성자을 입력해주세요");
    }
    else if(!password.value){
        alert("비밀번호를 입력해주세요");
    }
    else {
        document.write_form.submit();
    }

});




 

 

read.ejs - 글을 클릭 했을 시 상세 내용을 보여줄 화면입니다. footer태그로 댓글들을 보여줄 show.ejs를 포함시켜주었습니다.

<html>
    <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">
        <link rel="stylesheet" href="/style/read.css">
        <title>글쓰기</title>
    </head>
    <body>
        <div id="list" ,="," class="<%=list[0].password%>"></div>
        <div class="content">
            <h2>게시물 보기</h2>

            <div class="input_type">
                <label id="label_title">
                    제목</label>
                <input readonly="readonly" type='text' name="title" value="<%=list[0].title%>">
            </div>

            <div class="input_type">
                <label >
                    작성자</label>
                <input readonly="readonly" type='text' name="name" value="<%=list[0].writer%>">
            </div>

            <div class="input_type">
                <label >
                    내용</label>
                <textarea readonly="readonly" name="content" id="content" cols="70" rows="20"><%=list[0].context%></textarea>
            </div>

            <div class="btn">
                <button class='<%=list[0].id%>' id="update" name="123">수정</button>
                <button id="delete">삭제</button>
            </div>
        </div>

        <footer>
            <%- include('show')%>
            </footer>

            <script src="/js/read.js"></script>

        </body>
    </html>

 

read.css

h2 {
    text-align: center;
    width: 100%;
    border-bottom: 2px solid lightgray;
    padding-bottom: 10px;
}

.content {
    padding: 20px;
    border: rgb(88, 86, 86) solid 2px;
    font-size: 30px;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 700px;
    margin: auto;
    justify-content: space-evenly;
}

.input_type {
    border-bottom: 1px solid lightgray;
    width: 100%;
    padding-bottom: 10px;
    font-size: 20px;
    font-weight: bold;
    display: flex;
    align-items: center;
    margin-bottom: 30px;
    justify-content: flex-start;
}

#label_title {
    margin-right: 20px;
}

.input_type input{
    font-size: 20px;
    width: 400px;
    margin-left: 140px ;
}

.input_type textarea{
    font-weight: bold;
    font-size: 20px;
    width: 400px;
    margin-left: 160px;
    resize: none;
}



#btn_submit{
    margin-top: 30px;
    border-radius: 20px;
    font-size: 20px;
    width: 100px;
    
}


@media(min-width: 320px) and (max-width: 480px){


    h2 {
        text-align: center;
        width: 100%;
        border-bottom: 2px solid lightgray;
        padding-bottom: 10px;
    }
    
    .content {
        height: 100%;
        border: rgb(88, 86, 86) solid 2px;
        font-size: 30px;
        display: flex;
        flex-direction: column;
        align-items: center;
        width: 390px;
        margin: auto;
        justify-content: space-evenly;
    }
    
    .input_type {
        border-bottom: 1px solid lightgray;
        width: 412px;
        padding-bottom: 10px;
        font-size: 15px;
        font-weight: bold;
        display: flex;
        align-items: center;
        margin-bottom: 30px;
        
    }
  
    
    #label_title {
        margin-right: 20px;
    }
    
    .input_type input{
        font-size: 15px;
        width: 200px;
        margin-left: 50px ;
    }
    
    .input_type textarea{
        font-weight: bold;
        font-size: 15px;
        width: 300px;
        margin-left: 30px;
        resize: none;
    }
    
    
    
    #btn_submit{
        margin-top: 30px;
        border-radius: 20px;
        font-size: 20px;
        width: 100px;
        
    }
    
    


}

 

read.js

const btn_update = document.getElementById('update');
const btn_delete = document.getElementById('delete');
const list = document.getElementById('list');
let number = btn_update.className;
const db_password =list.className;


btn_update.addEventListener('click',function(){
    if(db_password === null){
    alert("수정하시겠습니까?");
    let url='/read/update/'+number;
    location.href=url;
    }
    else if(db_password !==null) {
        let password = prompt("비밀번호를 입력해주세요");
    
        if(password == db_password) {
            let url='/read/update/'+number;
            location.href=url;
        }

        else {
            alert("비밀번호가 맞지 않습니다 다시 입력해주세요");
        }
    
        }
});

btn_delete.addEventListener('click',function() {

    if(db_password === null){
        alert("삭제되었습니다.");
        let url='/read/remove/'+number;
        location.href=url;
    }
    else if(db_password !==null) {
    let password = prompt("비밀번호를 입력해주세요");

    if(password == db_password) {
        alert("삭제되었습니다.");
        let url='/read/remove/'+number;
        location.href=url;
    }

    else {
        alert("비밀번호가 맞지 않습니다 다시 입력해주세요");
    }

    }
   

});

update.ejs - read.ejs에서 수정 버튼을 누를 시 글 수정화면으로 이동하여 보여줄 화면입니다.

<html>
    <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">
        <link rel="stylesheet" href="/style/update.css">
        <title>글쓰기</title>
    </head>
    <body>
        <form action='/updateAf' method='post'>
            <div class="content">
                <h2>게시글 작성</h2>
            
                    <div class="input_type">  
                        <label id="label_title"> 제목</label>
                        <input  name = "title" type="text" value="<%=list[0].title%>"> 
                    </div>

                    <div class="input_type">  
                        <label>닉네임</label>
                        <input readonly name = "writer" value="<%=list[0].writer%>" type="text"> 
                    </div>

                    <div class="input_type">  
                        <label >내용</label>
                        <textarea  name="context" id="" cols="70" rows="20"><%=list[0].context%></textarea>
                    
                    </div>

                    <button name="id" value="<%=list[0].id%>" id='btn_submit' type='submit'>수정하기</button>
            </div>
        </form>
        
      <script src="/js/update.js"></script>
    </body>
</html>

update.css

h2 {
    text-align: center;
    width: 100%;
    border-bottom: 2px solid lightgray;
    padding-bottom: 10px;
}

.content {
    padding: 20px;
    border: rgb(88, 86, 86) solid 2px;
    font-size: 30px;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 700px;
    margin: auto;
    justify-content: space-evenly;
}

.input_type {
    border-bottom: 1px solid lightgray;
    width: 100%;
    padding-bottom: 10px;
    font-size: 20px;
    font-weight: bold;
    display: flex;
    align-items: center;
    margin-bottom: 30px;
    justify-content: flex-start;
}

#label_title {
    margin-right: 20px;
}

.input_type input {
    font-size: 20px;
    width: 400px;
    margin-left: 140px;
}

.input_type textarea {
    font-weight: bold;
    font-size: 20px;
    width: 400px;
    margin-left: 160px;
    resize: none;
}

#input_number {
    display: none;
}

#btn_submit {
    margin-top: 30px;
    border-radius: 20px;
    font-size: 20px;
    width: 100px;

}

@media(min-width: 320px) and (max-width: 480px) {

    h2 {
        text-align: center;
        width: 100%;
        border-bottom: 2px solid lightgray;
        padding-bottom: 10px;
    }

    .content {
        height: 100%;
        border: rgb(88, 86, 86) solid 2px;
        font-size: 30px;
        display: flex;
        flex-direction: column;
        align-items: center;
        width: 390px;
        margin: auto;
        justify-content: space-evenly;
    }

    .input_type {
        border-bottom: 1px solid lightgray;
        width: 412px;
        padding-bottom: 10px;
        font-size: 15px;
        font-weight: bold;
        display: flex;
        align-items: center;
        margin-bottom: 30px;

    }

    #label_title {
        margin-right: 20px;
    }

    .input_type input {
        font-size: 15px;
        width: 200px;
        margin-left: 50px;
    }

    .input_type textarea {
        font-weight: bold;
        font-size: 15px;
        width: 300px;
        margin-left: 30px;
        resize: none;
    }

    #btn_submit {
        margin-top: 30px;
        border-radius: 20px;
        font-size: 20px;
        width: 100px;

    }

}

 

 

show.ejs - 댓글들을 보여줄 화면입니다.

<html>
    <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">
        <link rel="stylesheet" href="/style/show.css">
        <title>글쓰기</title>
    </head>
    <body>
        <form name= "sub_form" action="/read/sub/insert" method="POST">
            <div class="sub_content">
                    <h3>댓글</h3>
                    <div class="input">
                            <label> 작성자</label>
                            <input  name ="sub_writer" type="text">

                            <label > 내용</label>
                            <input name = "sub_context" type="text">

                            <label > 비밀번호</label>
                            <input  id="sub_password" name = "sub_password" type="password">

                            <button id="btn_sub_insert" type="button">댓글 달기</button>
                    </div>

                    <div class="sub_board">

                        <% for(i = 0; i < sub_list.length ; i++) { %>
                            <div class="show_sub_board">
                                <label class="<%=sub_list[i].spassword%>" id="sub_writer" ><%=sub_list[i].swriter%></label>
                                <p id="sub_text"><%=sub_list[i].scontext%></p>
                                <div class="btn">
                                    <button  id="<%=sub_list[i].spassword%>"onclick="sub_update(this.id,<%=sub_list[i].sid%>)" type="button" >수정</button>
                                    <button id ="<%=sub_list[i].spassword%>"onclick="sub_delete(this.id,<%=sub_list[i].sid%>)" type="button">삭제</button>
                                </div>
                            </div>
                        <% } %>
                    </div>
            </div>
        </form>

      <script src="/js/show.js"></script>  
      
    </body>
</html>

 

show.css

.sub_content {
    padding: 20px;
    border: rgb(88, 86, 86) solid 2px;
    font-size: 30px;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 700px;
    margin: auto;
    justify-content: space-evenly;

}
label {
    font-size: 15px;
}

#text {
    margin-top: 20px;
    font-size: 20px;
    font-weight: bold;
}

.show_sub_board {
    width: 100%;
    display: flex;
    flex-direction: column;
    border-top: lightgray 1px solid;
    border-bottom: lightgray 1px solid;
    margin-bottom: 10px;
}

.sub_board {
    margin-top: 20px;
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;

}
#sub_writer {
    margin-top: 10px;
}
#sub_text {
    font-size: 20px;
}
.sub_content input {
    width: 130px;
}

.btn {
    margin-top: 20px;
    display: flex;

}
#btn_delete {
    margin-left: 20px;
}
@media(min-width: 320px) and (max-width: 480px) {
    }

 

show.js

const btn_sub_insert = document.getElementById('btn_sub_insert');
const sub_password = document.getElementById('sub_password');

btn_sub_insert.addEventListener('click', function () {

    if (!sub_password.value) {

        alert("비밀번호를 입력해주세요.");
    } else {
        alert("댓글이 입력되었습니다.");
        document
            .sub_form
            .submit();
    }
});

function sub_delete(sub_pwd, sub_id) {

    let pwd = prompt("비밀번호를 입력해주세요");
    if (pwd == sub_pwd) {
        alert("삭제되었습니다.");
        let url = '/read/sub/remove/' + sub_id;
        location.href = url;
    } else {
        alert("비밀번호를 다시 입력해주세요");
    }

}

function sub_update(sub_pwd,sub_id) {
    
    let pwd = prompt("비밀번호를 입력해주세요");
    if (pwd == sub_pwd) {
        let url = "/read/sub/update/"+sub_id;
        let name = "popup test";
        let option = "width = 500, height = 500, top = 100, left = 200, location = no"
        window.open(url, name, option);
    
    }
    else {
        alert("비밀번호를 다시 입력해주세요");
    }
}

 

sub_update.ejs - 댓글 수정 버튼을 누를시 보여질 화면입니다.

<!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">
        <link rel="stylesheet" href="/style/sub_update.css">
        <title>댓글 수정</title>
    </head>
    <body>
        <form name = 'sub_update_form' action='/sub_updateAf' method="POST">
            
            <div class="input">
                <h2>수정할 댓글을 입력해주세요.</h2>
            
                <textarea name="sub_context"><%=sub_list[0].scontext%></textarea>
                <input type="hidden" value ="<%=sub_list[0].sid%>" name ="number">
                <div class="btn"> 

                    <button  type="button" onclick="update()">수정하기</button>
                    <button  type="button">취소</button>

                </div>
            </div>
        </form>

        <script src="/js/sub.update.js"></script>
    </body>
</html>

sub_update.css

.input {
    display: flex;
    flex-direction: column;
}

.btn {
    margin : 20px;
    display: flex;

}

sub_update.js



function update(){
   
    sub_update_form.submit();
    opener.location.reload();
    
 
};


null.ejs - 댓글 수정 후 창 닫기 위한 ejs 추후에 설명 하겠습니다!

<script>
 setTimeout(function() {
 self.close();
}, 1000);
 </script>