ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [WebPage] 실전 웹 프로젝트 구축 !!(Client Part 2) - 웹 페이지 제작 강좌
    Web/WebPage 2015. 7. 11. 15:13

    이전 장에 이어서 이번 장에서는 타임라인(Timeline) 서비스에 대해 클라이언트를 구현하겠습니다.





    연결된 강좌이므로 아래 링크대로 따라주시면 이해가 더 쉬우실 것 입니다.

    ===========================================


    1. 개발환경설정

    2. CSS & Bootstrap 

    3. CSS 선택자(Selector)

    4. CSS 요소(Element)

    5. Bootstrap Part. 1

    6. Bootstrap Part. 2

    7. 실전 예제 - 개인용 포트폴리오 페이지 제작

    8. Python & Django

    9. Django

    10. 장고(Django) 프로젝트

    11. JavaScript & jQuery

    12. 실전 웹 프로젝트(예제)


    13. 실전 웹 프로젝트(Timeline) Server Part.1


    ===========================================







    1. template.html을 복사하여 timeline.html을 작성합니다. 




     base64.js를 추가해주는 것도 잊지 마세요.


    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 charset="utf-8"/>
            <title>Timeline Example</title>
            <link href="bootstrap/css/bootstrap.css" rel="stylesheet"/>
            <link href="timeline.css" rel="stylesheet"/>
            <link href="bootstrap/css/bootstrap-responsive.css" rel="stylesheet"/>
        </head>
        <body>
            <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
            <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
            <script src="bootstrap/js/bootstrap.js"></script>
            <script src="timeline.js"></script>
            <script src="base64.js"></script>
            <script>
                $(document).ready(function() {
     
                });
           </script>
        </body>
    </html>
    cs










    2. 상단 Navbar를 작성합니다. 




    body 태그 안에 작성해주세요.


    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
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="navbar-inner">
            <div class="container">
                <a class="btn btn-navbar" data-toggle="collapse" data-target="#navMenu"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </a>
                <a class="brand" href="#">TimeLine Service</a>
                <div class="nav-collapse"id="navMenu">
                    <ul class="nav center">
                        <li class="active">
                            <a href="#">Home</a>
                        </li>
                        <li>
                            <a href="profile.html">Profile</a>
                        </li>
                        <li>
                            <a href="account.html">Account</a>
                        </li>
                    </ul>
                    <div class="btn-group pull-right">
                        <a class="btn" id="adminBtn">
                            <i class="icon-pencil"></i>
                            Admin
                            <span class="caret"></span>
                        </a>
                        <a class="btn" id="logoutBtn">
                            <i class="icon-user"></i>
                            Logout
                            <span class="caret"></span>
                        </a>
                    </div>
                </div>
            </div>
        </div>
    </div><!-- End of NavBar -->
    cs





    실행 결과 아래와 같습니다.

      







     상단 메뉴 부분을 완성했으니 몸체 부분을 작성하도록 하겠습니다. 



    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
            <div class="container bg">
                <!-- Start of Container -->
                <div class="timeline">
                    <!-- Start of timeline -->
                    <div class="span7 bottom15">
                        <div class="roundinside bottom15 center">
                            <fieldset>
                                <label class="lightblue bold leftalign" for="textarea"> Compose New Message </label>
                                <textarea class="input-xlarge span6" id="writearea" name="content" rows="3"></textarea>
                                <div>
                                    <a class="btn btn-primary" id="writeBtn"> Write </a>
                                    <a class="btn btn-info between" id="reloadBtn"> Refresh </a>
                                </div>
                            </fieldset>
                        </div>
                        <div class="roundinside" id="msgTemplate">
                            <a data-toggle="modal" class="getInfo">
                            <div class="name lightblue">
                                JACK
                            </div> </a>
                            <div class="content">
                                <a class="btn close" name="deleteTimeline">X</a>
                            </div>
                            <span class="date">2015/07/09</span>
                            <span class="like"> <a class="btn" id="like" name="like"> <i class="icon-chevron-up"></i> </a> </span>
                        </div>
                        <div id="timelinearea">
     
                        </div>
                    </div>
                    <div class="span4 submenu">
                        <div class="roundinside">
                            <span> ID: </span><span id="username"></span>
                        </div>
                        <div class="roundinside">
                            <div class="pagination pagination-centered">
                                <ul>
                                    <li>
                                        <a><strong id="total"></strong>Total Timeline</a>
                                    </li>
                                    <li>
                                        <a><strong id="mine"></strong>My Timeline</a>
                                    </li>
                                </ul>
                            </div>
                        </div>
                        <div class="roundinside center bottom15">
                            <input type="text" class="search" id="search" />
                            <a class="btn btn-info" id="searchBtn">
                                <i class="icon-search"></i>
                            </a>
                        </div>
                    </div>
                </div><!-- End of Timeline -->
            </div><!-- End of Container -->
            <div class="modal hide fade" id="myModal">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">
                        x
                    </button>
                    <h2><span id="modalid"></span>'s Info</h2>
                </div>
                <div class="modal-body">
                    <h3>Nick: <span id="modalnickname"></span></h3>
                    <h3>Country: <span id="modalcountry"></span></h3>
                    <h3>URL: <span id="modalurl"></span></h3>
                    <h3>Comment: <span id="modalcomment"></span></h3>
                </div>
            </div><!-- End of MyModal -->
    cs







    3. 몸체를 작성했으니, CSS를 추가해서 꾸며보겠습니다.





    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    /* timeline page */
    .container .brand {
        color: white;
        font-size: 22px;
    }
    .timeline {
        padding-top: 5px;
        padding-left: 15px;
        padding-right: 15px;
    }
    .leftalign {
        text-align: left;
    }
    .bold {
        font-weight: bold;
    }
    .content {
        font-weight: bold;
        padding-left: 10px;
        margin-top: 3px;
    }
    .date {
        color: grey;
        font-size: 12px;
        margin-right: 15px;
    }
    .roundinside {
        padding: 10px;
        background-color: white;
        -webkit-border-radius: 6px;
        -moz-border-radius: 6px;
        border-radius: 6px;
        margin-bottom: 3px;
    }
    .bottom15 {
        margin-bottom: 15px;
    }
    .submenu {
        color: #5b7dc1;
        text-align: center;
        font-size: 18px;
        font-weight: bold;
        margin-bottom: 10px;
    }
    .submenu ul {
        margin-top: 7px;
    }
    .submenu li a {
        font-size: 13px;
    }
    .submenu li a strong {
        display: block;
        line-height: 0px;
        margin-top: 15px;
    }
    .search {
        width: 70%;
        margin-top: 8px;
    }
     
    cs







     아래처럼 더욱 간결한 UI를 선보이게 되었습니다.









     화면 구성을 보느라 더미 데이터와 스타일을 따로 추가해 주겠습니다. div의 id가 msgTemplate인 부분을 찾아서 아래와 같이 수정해 줍니다.



    1
    2
    3
    4
    5
    6
    7
    8
    9
                        <div class="roundinside" id="msgTemplate" style="display: none;">
                            <div class="name lightblue">
                            </div>
                            <div class="content">
                                <a class="btn close" name="deleteMsg">X</a>
                            </div>
                            <span class="date"></span>
                            <span class="like"> <a class="btn" id="like" name="like"> <i class="icon-chevron-up"></i> </a> </span>
                        </div>
    cs













    4. 다음으로 자바스크립트를 작성하여 타임라인에 대한 여러 화면과 기능을 구현하겠습니다.




     이번에는 아래와 같이 많은 기능을 구현할 예정입니다.

      1) 타임라인 작성하기

      2) 타임라인 데이터 가져오기

      3) 타임라인 검색하기

      4) 내가 쓴 글 삭제하기

      5) Like 추가하기

      6) 메시지 개수 카운트하기



     먼저 timeline.js를 열어서 doLogin 함수 아래에 작성합니다.



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     
    var doWriteTimeline = function() {
        var msg = $("#writearea").val();
        
        $.ajax({
            type: 'POST',
            url: baseUrl + 'api/timeline/create/',
            data: {message: msg},
            beforeSend: function(req) {
                req.setRequestHeader('Authorization', loginstring);
            },
            success: function() {
                alert('OK');
                doReload();
            },
            error: function(msg) {
                alert("Fail to write data!");
            }
        });
    };
     
    cs



     다음으로는 메세지를 가져오는 함수를 구현하겠습니다.



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    var doGetTimeline = function() {
        $.ajax({
            type: 'GET',
            url: baseUrl + 'api/timeline/',
            beforeSend: function(req) {
                req.setRequestHeader('Authorization', loginstring);
            },
            success: function(data) {
                for (var i in data.messages) {
                    doAppend(data.messages[i]);
                }
                
                $("#total").html(data.total_count);
                $("#mine").html($('[name=deleteMsg]').length - 1);
                $("#username").html(username);
                $("#writearea").val();
            },
            error: function() {
                alert("Fail to get data!");
            }
        });
    };
     
    cs



     계속해서 필요한 함수들을 작성하겠습니다.



    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 doAppend = function(data) {
        node = $('#msgTemplate').clone();
        
        $('.name', node).append(data.username);
        $('.content', node).append(data.message);
        $('.date', node).append(data.created);
        $('.like', node).prepend(data.liked + " ");
        $('#like', node).attr("value", data.id);
        $('#dislike', node).attr("value", data.id);
        
        if (username == data.username) 
            $('[name=deleteMsg]', node).attr("value", data.id);
        else 
            $('[name=deleteMsg]', node).remove();
            
        node.show();
        $('#timelinearea').append(node);
    };
     
    var doReload = function() {
        doClear();
        doGetTimeline();
    };
     
    var doClear = function() {
        $('#timelinearea').html('');
    };
     
    cs




     작성한 JS들을 연결하기 위해 timeline.html을 열어 작성해줍니다.




    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
            <script>
                $(document).ready(function() {
                    getLoginString();
                    doGetTimeline();
                    $('#adminBtn').click(goAdmin);
                    $('#writeBtn').click(doWriteTimeline);
                    $('#reloadBtn').click(doReload);
                });
            </script>
     
    cs








     자 그럼 타임라인의 기능에 대해서 수행을 확인해 보겠습니다.



     먼저 계정으로 로그인 된 상태에서 타임라인을 작성해보도록 하겠습니다.







     Write를 눌러 제대로 개제되는 지 확인합니다.



    보시는 바와 같이 제대로 타임라인에 개제 되었습니다.













    5. 타임라인의 작성 구현 후, 타임라인 삭제 및 검색을 구현하겠습니다.




      먼저 삭제 기능을 구현하겠습니다. 삭제 기능은 timeline.html에 구현하도록 하겠습니다. html 내부의 script 태그 내에 작성해주세요.

     ( * 기존 live에서 on으로 대체하면서 매핑문제 때문에 html 내부에 구현하게 되었습니다.)




    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $(document).on("click""[name=deleteMsg]"function(e) {
        var id = e.target.getAttribute('value');
        // alert(tmp);
     
        $.ajax({
            type : 'POST',
            url : 'http://127.0.0.1:8000/api/timeline/' + id + "/delete/",
            beforeSend : function(req) {
                req.setRequestHeader('Authorization', loginstring);
            },
            success : function(data) {
                doReload();
            },
            error : function(msg) {
                alert("Fail to delete data!");
            }
        });
     
    });
    cs





     그 다음, 타임라인 검색 기능을 구현하도록 하겠습니다.



    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
    var doSearchTimeline = function() {
        $.ajax({
            type: 'GET',
            url: baseUrl + 'api/timeline/find/',
            data: {query: $("#search").val()},
            beforeSend: function(req) {
                req.setRequestHeader('Authorization', loginstring);
            },
            success: function(data) {
                doClear();
                for (var i in data) {
                    doAppend(data[i]);
                }
                
                $("#total").html(data.length);
                $("#mini").html($('[name=deleteMsg]').length - 1);
                $("#search").val("");
            },
            error: function() {
                alert("Fail to get Data!");
            }
        });
    };
     
     
    cs




     마지막으로 구현하지 않았던 로그아웃 기능을 구현하여 테스트 해보겠습니다.




    1
    2
    3
    4
    5
    6
     
    var doLogout = function() {
        resetLoginString();
        window.location = "login.html";
    };
     
    cs






     timeline.html에 연결해 줍니다.





    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
    <script>
        $(document).ready(function() {
            getLoginString();
            doGetTimeline();
            $('#adminBtn').click(goAdmin);
            $('#writeBtn').click(doWriteTimeline);
            $('#reloadBtn').click(doReload);
            $(document).on("click""[name=deleteMsg]"function(e) {
                var id = e.target.getAttribute('value');
                // alert(tmp);
     
                $.ajax({
                    type : 'POST',
                    url : 'http://127.0.0.1:8000/api/timeline/' + id + "/delete/",
                    beforeSend : function(req) {
                        req.setRequestHeader('Authorization', loginstring);
                    },
                    success : function(data) {
                        doReload();
                    },
                    error : function(msg) {
                        alert("Fail to delete data!");
                    }
                });
     
            });
            $("#searchBtn").click(doSearchTimeline);
            $("#logoutBtn").click(doLogout);
     
        });
     
    </script>
    cs






     삭제, 검색, 로그아웃이 잘 되는지 확인하시고 다음으로 넘어가 주세요.











    6. Like기능과 Modal Dialog 표시를 구현하겠습니다.




      코멘트에 호감을 표시하는 기능인 Like를 먼저 구현해보도록 하겠습니다. Like 기능 역시 timeline.html에 작성합니다.

     



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    $(document).on("click""[name=like]"function(e) {
        var id = e.target.getAttribute('value');
     
        $.ajax({
            type : 'POST',
            url : baseUrl + 'api/timeline/' + id + '/like/',
            beforeSend : function(req) {
                req.setRequestHeader('Authorization', loginstring);
            },
            success : function() {
                doReload();
            },
            error : function(msg) {
                alert("Fail to set data!");
            }
        });
    });
     
    cs




     다음으로는 Modal Dialog에 대해 구현하겠습니다. 이 기능 또한 timeline.html에 작성합니다.



    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
     
     
    $(document).on("click"".name.lightblue"function(e) {
        var username = $(this).html();
        
        $.ajax({
            type: 'GET',
            url: baseUrl + 'api/profile/' + username + '/',
            beforeSend: function(req){
                req.setRequestHeader('Authorization', loginstring);
            },
            success: function(data) {
                $("#modalid").html(data.username);
                $("#modalnickname").html(data.nickname);
                $("#modalcountry").html(data.country);
                $("#modalcomment").html(data.comment);
                $("#modalurl").html(data.url);
                $("#myModal").modal("show");
            },
            error: function(msg) {
                alert("Fail to get data!");
            }
        });
    });
     
    cs




     두 기능을 구현한 뒤, Like 아이콘 클릭시 count가 되는지, 사용자 아이디를 클릭 시, Modal 이 뜨는지 확인하세요.



     

     다음 장에서는 Profile과 Account 창 구현을 하도록 하겠습니다.






    * 본 포스팅은 이재근 등 4명 저 "Fast Web Service Build up: 웹 서비스를 쉽고 빠르게 구축하는 기술" 저서를 참고하여 작성하였습니다

    댓글

Designed by Tistory.