제목: 목록 페이지 구성 (Client)

최초작성일: 2014-12-26

최종수정일: 2014-12-26

자 이제 목록 페이지를 개발해 보겠습니다. 목록 페이지는 서버에서 데이터를 조회해와서 List 형태로 화면에 출력하는 역할을 담당합니다. 하지만 우리는 서버는 나중에 개발해보기로 하였으니 먼저 단말에서 강제로 데이터를 생성해서 List에 올바르게 Bind 하는지까지만 확인해보도록 하겠습니다. 그럼 이제부터 목록 페이지 만들기를 시작해 보겠습니다.
1. 기본 HTML 구조 작성
목록 페이지 뿐만 아니라, 모든 페이지를 위해서는 기본 구조가 필요합니다. 우리는 간단하게 모바일에서 늘 보던 방식인 [헤더] - [본문] - [푸터]로 구분하여 [본문] 영역만 Scroll 되는 구조로 개발해 보겠습니다. Scroll은 별도의 Open Source Library를 사용하지 않고 브라우저에서 지원하는 DIV Scroll을 사용할 예정이므로 Android 4.0 이하의 버전에서는 사용할 수 없습니다. 하지만 Android Developer 사이트에서 제공하는 현재 OS 점유율을 보면 4.0 이하의 OS는 점유율이 낮고 차차 없어질 부분이므로 일반적으로 크게 문제가 되지 않습니다. OS 버전 별 점유율은 아래 Link를 참고하시면 됩니다. http://developer.android.com/about/dashboards/index.html 그럼 위 방법대로 HTML을 간단히 구성해보도록 하겠습니다. 아래 소스 코드를 참고하여 bbs_list.html을 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta http-equiv="content-type" content="text/html;charset=UTF-8">
        <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, width=device-width">
        <title>Mobile BBS</title>
        <link rel="stylesheet" type="text/css" href="./css/common.css" />
    </head>
    <body>
        <header>
            <h1>Mobile BBS</h1>
        </header>
         
        <div class="wrap">
            <ul id="bbsListArea"></ul>
        </div>
         
        <footer>
            <button id="btnWrite">글쓰기</button>
        </footer>
    </body>
    <script type="text/javascript" charset="utf-8" src="./scripts/jquery-1.10.2.min.js"></script>
</html>
큰 내용은 없습니다. 페이지 구조를 크게 [헤더] - [본문] - [푸터]로 분리하였고, 공통 StyleSheet 파일을 하나 포함하도록 설정하였고, Open Source Library인 jQuery 사용을 위해 Script를 load 하였습니다.
2. StyleSheet 작성
모든 페이지에 공통으로 사용할 StyleSheet를 작성해 보겠습니다. 일단은 목록 페이지에서 사용할 부분만 작성하고 나머지 부분은 차차 페이지를 개발하는대로 추가해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
@charset "utf-8";
/* default */
html, body{height:100%;}
body{position:relative;margin:0;padding:0;}
ul, ol{list-style:none;padding:0;margin:0;}
a{text-decoration:none;}
button{height:30px;background-color:#FFF;border:1px solid #CCC;border-radius:3px;}
header{position:absolute;left:0;top:0;width:100%;z-index:2;height:45px;background-color:#333;border-bottom:2px solid #cc0000;}
header h1{left:0;top:0;width:100%;height:45px;color:#FFF;font-weight:bold;text-align:center;box-shadow:inset 0px 7px 20px rgba(0, 0, 0, 0.2);margin:0;line-height:45px;font-size:1.1em;}
footer{position:absolute;left:0;bottom:0;width:100%;z-index:2;height:45px;line-height:45px;text-align:center;background-color:#EEE;border-top:1px solid #CCC;}
 
.wrap{position:absolute;top:45px;bottom:45px;width:100%;overflow-y:scroll;}
CSS는 별도로 설명하지 않도록 하겠습니다. 그저 현재까지는 화면에서 영역을 나누고 [헤더], [푸터]를 고정한 후 남는 영역을 [본문] 영역으로 할당한 것이 전체 내용입니다.
3. JavaScript 작성
그럼 이제 JavaScript를 작성해 볼까요? 서버가 없으니 필요한 데이터를 단말에서 JSON 형태로 하드코딩하여 만들어 보도록 하겠습니다. JavaScript는 bbs 라는 Namespace 안에 별도의 Object 생성이 필요없도록 Static Function으로 구현하도록 하겠습니다.
일단 게시판 목록에 필요한 데이터의 Layout은 아래와 같이 정의하겠습니다. 추후 서버 개발할 때, 아래 Layout 대로 데이터를 단말로 return 하면 됩니다.
1
2
3
4
5
6
7
8
9
[{
    idx: 1,
    subject: '',
    readCount: 0,
    content: '',
    inputUserName: '',
    inputDate: 'YYYY-MM-DD',
    updateDate: 'YYYY-MM-DD'
}]
그럼 이제 위 Layout 대로 테스트데이터를 생성하여 목록에 Bind하는 부분을 개발해보도록 하겠습니다. function은 데이터를 생성하는 function과 목록에 Bind하는 부분을 구분하여 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var BBS = {};
 
BBS.getTestData = function() {
    var rows = [], row = {};
    row.idx = 1;
    row.subject = '테스트 게시물 입니다.';
    row.readCount = 1;
    row.content = '테스트 게시물 본문 입니다.';
    row.inputUserName = '홍길동';
    row.inputDate = '2015-01-01';
    row.updateDate = '2015-01-01';
     
    rows.push(row);
    rows.push(row);
     
    return rows;
}
 
BBS.display = function(rows) {
    var li = null, a = null, row1 = null, row2 = null;
    var listArea = $('#bbsListArea');
     
    for (var inx=0; inx<rows.length; inx++) {
        li = $('<li>');
        a = $('<a>');
        row1 = $('<div>');
        row1.text(rows[inx].subject + ' (' + rows[inx].updateDate + ')');
        row2 = $('<div>');
        row2.text(rows[inx].inputUserName + ' (' + rows[inx].readCount + ')');
        a.append(row1);
        a.append(row2);
        li.append(a);
         
        listArea.append(li);
    }
}
 
$(document).ready(function() {
    BBS.display(BBS.getTestData());
});
위 코드를 작성하여 ./scripts/bbs_list.js 파일로 저장합니다. 저장한 후 html 파일에 js를 아래와 같이 추가합니다.
1
<script type="text/javascript" charset="utf-8" src="./scripts/bbs_list.js"></script>
위 과정까지 마친 후 Google Chrome에서 bbs_list.html 파일을 열면 아래와 같은 모습으로 실행됩니다. 목록에는 별도의 디자인을 입히지 않았기 때문에 좀 많이 추리(?)하게 나옵니다. 비속어 양해 바랍니다.


4. Templates 만들기
이제 디자인을 입혀보려고 하니, 코드가 좀 마음에 들지 않습니다. 이것저것 추가하려면 목록을 만드는 BBS.display function 부분이 많이 복잡해질 것 같습니다. 그럼 목록에서 반복되는 부분의 Layout을 JavaScript에서 생성하지 말고 별도의 HTML Template을 만들어 읽어오는 방법으로 만들어 보겠습니다.
그럼 ./templates/ 라는 폴더를 하나 생성하고 bbs_list_line.html 파일을 하나 생성하여 아래 코드처럼 작성합니다.
1
2
3
4
5
6
7
8
9
10
<li>
    <a href="#" class="bbs_list_txt">
        <div>
            <span>{subject}</span>
        </div>
        <div>
            <span>{inputUserName} | {updateDate} | 조회 ({readCount})</span>
        </div>
    </a>
</li>
위 코드는 목록의 한 줄의 Layout을 의미하며, 위 코드를 읽어서 목록의 개수만큼 Bind 하는 방식으로 화면을 구성합니다. 코드 상에 있는 {}로 표시한 부분은 변수로 사용하여, 실제 목록에 Bind 할 때는 해당 변수를 실제 값으로 치환하게 됩니다. 그럼 실제로 이 부분을 코드로 작성해보도록 하겠습니다. 이 기능은 이 화면 뿐 아니라 다른 화면에서도 많이 사용하게 될 기능인 것 같으니 별도의 공통 JavaScript 파일을 하나 만들어서 저장하도록 하겠습니다.
아래 코드를 작성한 후 ./scripts/common.js 파일로 저장합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var COMM = {
    templates: []
};
 
COMM.loadTemplate = function(templateId, callback) {
    $.get('./templates/' + templateId + '.html', function(data) {
        COMM.templates[templateId] = data;
        if (callback) callback();
    });
}
 
COMM.getHTMLObj = function(templateId, input) {
    var html = COMM.templates[templateId];
    html = COMM.dynamicExpression(html, input);
    return $(html);
}
 
COMM.dynamicExpression = function(str, params) {
    var retStr = str;
    for (var key in params) {
        var regex = new RegExp('{' + key + '}', 'g');
        var value = params[key];
        if (value == null || value == 'null' || value == undefined || value == 'undefined') {
            value = '';
        }
        retStr = retStr.replace(regex, value);
    }
    return retStr;
}
자. 공통으로 작성한 function은 3가지 입니다. COMM.loadTemplate function은 사용할 template HTML 파일을 COMM Namespace의 변수에 저장합니다. 두 번째로 COMM.getHTMLObj function은 template HTML과 치환할 데이터를 Parameter로 받아서 실제 화면에 Rendering할 HTML을 생성합니다. 이 HTML 생성에 필요한 function이 COMM.dynamicExpression 입니다.
COMM.dynamicExpression function은 text 형태의 HTML와 치환할 데이터를 Parameter로 입력받아 정규 표현식을 사용하여 실제 화면에 Rendering할 형태의 HTML을 생성합니다.
5. Templates 사용하기

그럼 이제 template을 사용하여 BBS.display function을 수정해보도록 하겠습니다. 기존에 JavaScript로 DOM을 생성하는 방식이 아닌 template을 통해 바로 HTML Object를 생성하여 target에 append하는 형태로 수정해 보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
BBS.display = function(rows) {
    var listArea = $('#bbsListArea');
    var html = null;
     
    COMM.loadTemplate('bbs_list_line', function() {
        for (var inx=0; inx<rows.length; inx++) {
            html = COMM.getHTMLObj('bbs_list_line', rows[inx]);
            listArea.append(html);
        }
    });
}
더 복잡해 졌나요?. 물론 목록에 표시해야 하는 HTML Element가 단순하다면 굳이 이런 방법을 쓰지 않고 function 안에서 HTML Code를 생성해도 봐줄만 하겠지만, 실제로 프로젝트에서 사용하는 Layout은 그렇게 단순한 경우가 거의 없습니다. 더하여 코딩 표준을 잡고 프로젝트를 진행한다는 점에서도 이런 방식이 더 효율적으로 작용할 수 있으니 지금 당장은 좀 복잡해 보인다고 해도, 이해하고 넘어가는 편이 좋습니다.
위 코드까지 작성하여 저장하였으면, HTML 파일에 위 js 파일을 적용합니다.
1
<script type="text/javascript" charset="utf-8" src="./scripts/common.js"></script>
그 다음은 목록의 각 행에 적용할 StyleSheet를 common.css 에 추가합니다. 아래 코드를 참고합니다.
1
2
3
4
.wrap ul li{padding:14px 10px;border-bottom:1px solid #d7d7d7;background:-webkit-gradient(linear,left top,left bottom,color-stop(0.00,#fefefe),color-stop(1.00,#f1f1f1));}
.wrap ul li a{display:inline-block;width:100%;}
.wrap ul li span {color:#999;font-size:0.9em;}
.wrap ul li span strong{color:#000;font-size:1.1em;}
위 코드까지 적용하면 아래와 같은 모습의 목록화면이 완성됩니다.

다들 잘 나오나요? 파일 하나에 개발하던 방법에 비해서 파일을 분할해 놓은 탓에 처음보는 오류들이 발생할 수도 있습니다. 하지만 우리가 사용하는 Google Chrome에서는 쉽게 Debugging 할 수 있어 어렵지 않게 따라오셨을거라 믿을게요. 다음에는 "상세보기" 페이지를 같이 진행해보도록 하겠습니다.

300x250

+ Recent posts