게시판 - Front End 개발

소스코드

이 게시물에는 코드작성이 포함되어 있습니다. 소스코드를 받으신 후 진행해 주세요. MEAN Stack/개발 환경 구축에서 설명된 프로그램들(git, npm, atom editor)이 있어야 아래의 명령어들을 실행할 수 있습니다.

이 게시물의 소스코드는 게시판 만들기 / 게시판 - Back End 개발에서 이어집니다.

board.git 을 clone 한 적이 있는 경우: 터미널에서 해당 폴더로 이동 후 아래 명령어들을 붙여넣기합니다. 폴더 내 모든 코드가 이 게시물의 코드로 교체됩니다. 이를 원치 않으시면 이 방법을 선택하지 마세요.

git reset --hard
git pull
git reset --hard 6e060a3
git reset --soft 2151499
npm install
atom .

board.git 을 clone 한 적이 없는 경우: 터미널에서 코드를 다운 받을 폴더로 이동한 후 아래 명령어들을 붙여넣기하여 board.git 을 clone 합니다.

git clone https://github.com/a-mean-blogger/board.git
cd board
git reset --hard 6e060a3
git reset --soft 2151499
npm install
atom .

- Github에서 소스코드 보기: https://github.com/a-mean-blogger/board/tree/6e060a38fe84963efecdaaa0fa694e3bdf09eeac


지난번 포스팅에 이어서 front end 개발을 해봅시다.

폴더구조

주황색은 변경된 파일, 녹색은 새로 생성된 파일, 회색은 변화가 없는 파일입니다.

코드 - ejs

<!-- views/partials/nav.ejs -->

<nav class="navbar navbar-default">
 <div class="container">
 <!-- <div class="navbar-header">... -->
  <div class="collapse navbar-collapse" id="myNavbar">
   <ul class="nav navbar-nav">
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/posts">게시판</a></li>
   </ul>
  </div>
 </div>
</nav>

...은 이전과 비교해서 변화가 없는 부분입니다.
세번째 메뉴 "게시판"이 추가되었습니다.

<!-- views/posts/partials/header.ejs -->

<h2>Board</h2>

페이지들 중에 게시판에서만 사용되는 header 코드입니다.

<!-- views/posts/index.ejs -->

<!DOCTYPE html>
<html>
 <head>
  <% include ../partials/head %>
 </head>
 <body>
  <% include ../partials/nav %>

  <div class="container post post-index">
   <% include ./partials/header %>

   <div class="buttons">
    <a class="btn btn-default" href="/posts/new">New</a>
   </div>

   <table class="table table-striped posts">
    <thead>
     <tr>
      <th class="title">Title</th>
      <th class="date">Date</th>
     </tr>
    </thead>
    <tbody>
     <% if(posts == null || posts.length == 0){ %>
      <tr>
       <td class="noData" colspan=100> There is no data to show :( </td>
      </tr>
     <% } %>
     <% posts.forEach(function(post) { %>
      <tr>
       <td class="title">
        <a href="/posts/<%= post._id %>"><div><%= post.title %></div></a>
       </td>
       <td class="date">
        <%= post.createdDate %>
       </td>
      </tr>
     <% }) %>
    </tbody>
   </table>
  </div> <!-- container end -->
 </body>
</html>

Index를 table로 표시합니다.

<!-- views/posts/new.ejs -->

<!DOCTYPE html>
<html>
 <head>
  <% include ../partials/head %>
 </head>
 <body>
  <% include ../partials/nav %>

  <div class="container post post-new">
   <% include ./partials/header %>

   <div class="buttons">
    <a class="btn btn-default" href="/posts">Back</a>
   </div>

   <form class="post-form form-horizontal" action="/posts" method="post">
    <div class="contentBox">
     <h3 class="contentBoxTop">New Post</h3>
     <fieldset>
      <div class="form-group">
       <label for="title" class="col-sm-2 control-label">Title</label>
       <div class="col-sm-10">
        <input class="form-control" type="text" id="title" name="title" value="">
       </div>
      </div>
      <div class="form-group">
       <label for="body" class="col-sm-2 control-label">Body</label>
       <div class="col-sm-10">
        <textarea class="form-control" id="body" name="body" rows="5"></textarea>
       </div>
      </div>
     </fieldset>
    </div>
    <div class="buttons">
     <button type="submit" class="btn btn-default">Submit</button>
    </div>
   </form>

  </div> <!-- container end -->
 </body>
</html>

form 구성을 bootstrap의 form-horizontal class로 했습니다. label과 input이 한줄에 표시되는 구성입니다.

<!-- views/posts/show.ejs -->

<!DOCTYPE html>
<html>
 <head>
  <% include ../partials/head %>
 </head>
 <body>
  <% include ../partials/nav %>

  <div class="container post post-show">
   <% include ./partials/header %>

   <div class="buttons">
    <a class="btn btn-default" href="/posts">Back</a>
    <a class="btn btn-default" href="/posts/<%= post._id %>/edit">Edit</a>
    <form action="/posts/<%= post._id %>?_method=delete" method="post">
     <a class="btn btn-default" href="#" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a>
    </form>
   </div>

   <div class="contentBox">
    <h3 class="contentBoxTop"><%= post.title %></h3>
    <div class="row">
     <div class="col-sm-4 col-sm-push-8">
      <div class="post-info">
       <div><span>Created</span> : <%= post.createdDate %> <%= post.createdTime %></div>
       <% if(post.updatedAt) { %>
        <div><span>Updated</span> : <%= post.updatedDate %> <%= post.updatedTime %></div>
       <% } %>
      </div> <!-- post-info end -->
     </div> <!-- col end-->
     <div class="col-sm-8 col-sm-pull-4">
      <div class="post-body"><%= post.body %></div>
     </div> <!-- col end-->
    </div> <!-- row end -->
   </div> <!-- post-container end -->

  </div> <!-- container end -->
 </body>
</html>

bootstrp의 row와 col- class를 이용해 grid를 구성하고 있습니다.
화면이 클 경우에는 post-body와 post-info가 같은 줄(row)에 표시되지만, 화면이 작을 경우에는 post-body가 밑으로 내려가게 됩니다.

col-화면크기-push-숫자, col-화면크기-pull-숫자 class는 순서를 순서를 바꿔주는 기능을 합니다.
post-info 코드가 위에 있지만 큰화면에서 post-body 다음에 표시되게 됩니다.

<!-- views/posts/edit.ejs -->

<!DOCTYPE html>
<html>
 <head>
  <% include ../partials/head %>
 </head>
 <body>
  <% include ../partials/nav %>

  <div class="container post post-edit">
   <% include ./partials/header %>

   <div class="buttons">
    <a class="btn btn-default" href="/posts">Back</a>
   </div>

   <form class="post-form form-horizontal" action="/posts/<%= post._id %>?_method=put" method="post">
    <div class="contentBox">
     <h3 class="contentBoxTop">Edit Post</h3>
     <fieldset>
      <div class="form-group">
       <label for="title" class="col-sm-2 control-label">Title</label>
       <div class="col-sm-10">
        <input class="form-control" type="text" id="title" name="title" value="<%= post.title %>">
       </div>
      </div>
      <div class="form-group">
       <label for="body" class="col-sm-2 control-label">Body</label>
       <div class="col-sm-10">
        <textarea class="form-control" id="body" name="body" rows="5"><%= post.body %></textarea>
       </div>
      </div>
     </fieldset>
    </div>
    <div class="buttons">
     <button type="submit" class="btn btn-default">Submit</button>
    </div>
   </form>

  </div> <!-- container end -->
 </body>
</html>

edit은 역시 new와 구성이 비슷합니다. form action에 ?_method=put 넣는 것을 잊지 마세요.

코드 - css

/* public/css/master.css */

/* global style */
.buttons form{
 display: inline-block;
}

/* home style */
.home h1{
 color: darkseagreen;
}

/* post style */
.post h2 {
 color: tomato;
 text-align: center;
}
.post .post-body{
 white-space: pre-line; /* 1 */
}
.post .posts .date{
 width: 100px;
}

1. 이 css가 없으면 post-body에 줄바꿈이 있어도 줄바꿈을 표시하지 않습니다. 이는 data 상의 줄바꿈(\n)과 html의 줄바꿈(<br>)이 다르기 때문입니다.

실행결과

form-horizontal class를 사용했기 때문에 label이 왼쪽에, input이 오른쪽에 표시됩니다.

화면이 큰 경우 post-body는 왼쪽에, post-info는 오른쪽에 표시됩니다.

화면이 작을 경우 post-info가 윗줄에 표시되고, 본문은 다음줄에 표시됩니다.

마치며...

지금까지 CRUD가능한 게시판을 만들어봤습니다. 복습이였는데 잘 이해가 되셨는지..
bootstrap은 하나하나 다 설명드릴 순 없고, http://getbootstrap.com에 예제들이 있으니 필요할때 가져다가 쓰면 됩니다.
저도 모든 class를 정확하게 이해하고 쓰는 것은 아니고 예제를 보면서 써보고 싶은게 있으면 가져다가 쓰고 있습니다.

댓글

G
GS 2018.09.10
항상 잘 보고있습니다. 다름이 아니라, 새 글쓰기나 글 수정할 때 작성버튼만 따로 가운데정렬하고 싶은데.. 여러가지 적용해봐도 잘 안되는데 좋은 방법이 있을까요..? 이 submit 버튼만 따로 div를 하나 더 만들어 감싸고 css 적용을 해보려고하는데 쉽지가 않네요ㅠㅠ 특히 홈페이지 크기를 모바일용이나 웹용으로 줄이고 늘려도 항상 가운데 정렬만 하는 방법이 있을까요?
I
Ian H 2018.09.10
@GS,
위 강의 코드에서 submit 버튼의 부모 태그에 class를 추가하고 css에 text-align:center 수정해 주면 되겠습니다.
HTML
<div class="buttons submit-container"> //submit-container class 추가   <button type="submit" class="btn btn-default">Submit</button> </div>
CSS
.submit-container{   text-align:center; }
댓글쓰기

이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기

UP