ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CodeIgniter] 9. AJAX 구현: jQuery
    Web/CodeIgniter 2015. 8. 28. 10:49

    8장에서 XMLHttpRequest 객체를 이용해 댓글 쓰기, 삭제를 구현헀습니다. 


    9장에서는 jQuery를 이용해 구현해보도록 하겠습니다.


    AJAX를 구현하기 위해 복잡한 과정을 거치고 DOM 스크립팅을 이용해 개발했는데 9장에서 jQuery를 이용해 개발한 소스를 비교해보면 jQuery가 단순하고 간결하게 프로그래밍할 수 있습니다.





    9.1 댓글 쓰기 AJAX로 구현

     컨트롤러와 모델 부분은 수정하지 않고 뷰만 DOM 스크립팅에서 jQuery를 이용한 방식으로 수정하면 됩니다.


     * bbs/application/views/board/view_v.php


    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    <!-- <script type="text/javascript" src="/bbs/include/js/httpRequest.js"></script> -->
    <script>
        $(document).ready(function() {
            $("#search_btn").click(function() {
                if ($("#q").val() == '') {
                    alert("검색어를 입력하세요!");
                    return false;
                } else {
                    var act = "/bbs/board/lists/ci_board/q/" + $("#q").val() + "/page/1";
                    $("#bd_search").attr('action', act).submit();
                }
            });
        });
     
        function board_search_enter(form) {
            var keycode = window.event.keyCode;
            if (keycode == 13)
                $("#search_btn").click();
        }
        
        $(function() {
            $("#comment_add").click(function () {
                $.ajax({
                    url: "/bbs/ajax_board/ajax_comment_add",
                    type: "POST",
                    data: {
                        "comment_contents": encodeURIComponent($("#input01").val()),
                        "csrf_test_name": getCookie('csrf_cookie_name'),
                        "table""<?php echo $this->uri->segment(3); ?>",
                        "board_id""<?php echo $this->uri->segment(4); ?>"
                    },
                    dataType: "html",
                    complete: function(xhr, textStatus) {
                        if (textStatus == 'success') {
                            if (xhr.responseText == 1000) {
                                alert('댓글 내용을 입력하세요.');
                            } else if (xhr.responseText == 2000) {
                                alert('다시 입력하세요.');
                            } else if (xhr.responseText == 9000) {
                                alert('로그인해야 합니다.');
                            } else {
                                alert($("#comment_area").html());
                                $("#comment_area").html(xhr.responseText);
                                $("#input01").val('');
                            }
                        }
                    }
                });
            });
        });
     
        function comment_delete(no) {
            ......
        }
        
        function delete_action() {
            ......
        }
        
        function getCookie(name) {
            ......
        }
    </script>
    <article id="board_area">
        <header>
            <h1></h1>
        </header>
        <table cellspacing="0" cellpadding="0" class="table table-striped">
            <thead>
                <tr>
                    <th scope="col"><?php echo $views -> subject;?></th>
                    <th scope="col">이름: <?php echo $views -> user_name;?></th>
                    <th scope="col">조회수: <?php echo $views -> hits;?></th>
                    <th scope="col">등록일: <?php echo $views -> reg_date;?></th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <th colspan="4">
                        <?php echo $views -> contents;?>
                    </th>
                </tr>
            </tbody>
            <tfoot>
                <tr>
                    <th colspan="4">
                        <a href="/bbs/board/lists/<?php echo $this -> uri -> segment(3); ?>/
                            page/<?php echo $this -> uri -> segment(7); ?>" class="btn btn-primary">목록 </a>
                        <a href="/bbs/board/modify/<?php echo $this -> uri -> segment(3); ?>/board_id/
                            <?php echo $this -> uri -> segment(4); ?>/page/<?php echo $this -> uri -> segment(7); ?>"
                            class="btn btn-warning"> 수정     </a>
                        <a href="/bbs/board/delete/<?php echo $this -> uri -> segment(3); ?>/board_id/
                            <?php echo $this -> uri -> segment(4); ?>/page/<?php echo $this -> uri -> segment(7); ?>"
                            class="btn btn-danger"> 삭제 </a>
                        <a href="/bbs/board/write/<?php echo $this -> uri -> segment(3); ?>/page/<?php echo $this -> uri -> segment(7); ?>"
                            class="btn btn-success">쓰기</a>                    
                    </th>
                </tr>
            </tfoot>
        </table>
        
        <form class="form-horizontal" method="POST" action="" name="com_add">
            <fieldset>
                <div class="control-group">
                    <label class="control-label" for="input01">댓글</label>
                    <div class="controls">
                        <textarea class="input-xlarge" id="input01" name="comment_contents" rows="3"></textarea>
                        <input class="btn btn-primary" type="button" id="comment_add" value="작성" />
                        <p class="help-block"></p>
                    </div>
                </div>
            </fieldset>
        </form>
        <div id="comment_area">
            <table cellspacing="0" cellpadding="0" class="table table-striped">
                <tbody>
    <?php
        foreach ($comment_list as $lt) {
    ?>
                    <tr id="row_num_<?php echo $lt->board_id; ?>">
                        <th scope="row">
                            <?php echo $lt->user_id;?>
                        </th>
                        <td><?php echo $lt->contents;?></a></td>
                        <td>
                            <time datetime="<?php echo mdate("%Y-%M-%j", human_to_unix($lt->reg_date)); ?>">
                                <?php echo $lt->reg_date;?>
                            </time>
                        </td>
                        <td>
                            <a href="#" onclick="javascript:comment_delete('<?php echo $lt->board_id; ?>')">
                                <i class="icon-trash"></i> 삭제
                            </a>
                        </td>
                    </tr>
    <?php
        }
    ?>
                </tbody>
            </table>
        </div>
    </article
    cs




     Line 21: jQuery에서 단순히 함수를 실행하라는 의미이며, DOM 객체를 사용할 준비가 되면 기능을 실행합니다.

     Line 22: jQuery에서 #은 id를 가리키고 .은 class를 가리킵니다. id가 comment_add 인 요소에 마우스 클릭 이벤트가 발생했을 때 기능을 실행하라는 의미입니다. 

     Line 23: $.ajax(action) 형태로 사용되며 AJAX 를 이용하기 위한 함수입니다. 옵션을 설정하면 그 옵션 에 대해 AJAX 액션을 실행하고 응답 결과에 대한 처리를 해줍니다.
























     jQuery를 이용해 8장의 소스보다 단순하고 간결하게 구현이 되었습니다.. 지시자 $("#comment_add")를 이용해 간단하게 요소를 지정할 수 있고, 다른 함수를 체인 형태로 연결해 실행할 수 있어 코드가 짧아지고 이해하기 쉽습니다.















    9.2 댓글 삭제 AJAX 구현

     9.1 절과 마찬가지로 DOM 스크립팅으로 되어있던 내용을 jQuery로 수정합니다.


     * bbs/application/views/board/view_v.php


    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    <!-- <script type="text/javascript" src="/bbs/include/js/httpRequest.js"></script> -->
    <script>
        $(document).ready(function() {
            $("#search_btn").click(function() {
                if ($("#q").val() == '') {
                    alert("검색어를 입력하세요!");
                    return false;
                } else {
                    var act = "/bbs/board/lists/ci_board/q/" + $("#q").val() + "/page/1";
                    $("#bd_search").attr('action', act).submit();
                }
            });
        });
     
        function board_search_enter(form) {
            var keycode = window.event.keyCode;
            if (keycode == 13)
                $("#search_btn").click();
        }
        
        $(function() {
            $("#comment_add").click(function () {
                ......     
            });
            
            $(".comment_delete").click(function() {
                $.ajax({
                    url: '/bbs/ajax_board/ajax_comment_delete',
                    type: 'POST',
                    data: {
                        "csrf_test_name": getCookie('csrf_cookie_name'),
                        "table""<?php echo $this->uri->segment(3); ?>",
                        "board_id": $(this).attr("vals")
                    },
                    dataType: "text",
                    complete: function(xhr, textStatus) {
                        if (textStatus == 'success') {
                            if (xhr.responseText == 9000) {
                                alert('로그인해야합니다.');
                            } else if (xhr.responseText == 8000) {
                                alert('본인의 댓글만 삭제할 수 있습니다.');
                            } else if (xhr.responseText == 2000) {
                                alert('다시 삭제하세요.');
                            } else {
                                $('#row_num_' + xhr.responseText).remove();
                                alert('삭제되었습니다.');
                            }
                        }
                    }
                });
            });
        });
     
     
        
        
        function getCookie(name) {
            var nameOfCookie = name + "=";
            var x = 0;
            
            while ( x <= document.cookie.length) {
                var y = (x + nameOfCookie.length);
                
                if (document.cookie.substring(x, y) == nameOfCookie) {
                    if (( endOfCookie = document.cookie.indexOf(";", y)) == -1
                        endOfCookie = document.cookie.length;
                    
                    return unescape(document.cookie.substring(y, endOfCookie));
                }
                
                x = document.cookie.indexOf(" ", x) + 1;
                
                if ( x == 0
                
                break;
            }
        }
    </script>
    <article id="board_area">
        <header>
            <h1></h1>
        </header>
        <table cellspacing="0" cellpadding="0" class="table table-striped">
            <thead>
                <tr>
                    <th scope="col"><?php echo $views -> subject;?></th>
                    <th scope="col">이름: <?php echo $views -> user_name;?></th>
                    <th scope="col">조회수: <?php echo $views -> hits;?></th>
                    <th scope="col">등록일: <?php echo $views -> reg_date;?></th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <th colspan="4">
                        <?php echo $views -> contents;?>
                    </th>
                </tr>
            </tbody>
            <tfoot>
                <tr>
                    <th colspan="4">
                        <a href="/bbs/board/lists/<?php echo $this -> uri -> segment(3); ?>/
                            page/<?php echo $this -> uri -> segment(7); ?>" class="btn btn-primary">목록 </a>
                        <a href="/bbs/board/modify/<?php echo $this -> uri -> segment(3); ?>/board_id/
                            <?php echo $this -> uri -> segment(4); ?>/page/<?php echo $this -> uri -> segment(7); ?>"
                            class="btn btn-warning"> 수정     </a>
                        <a href="/bbs/board/delete/<?php echo $this -> uri -> segment(3); ?>/board_id/
                            <?php echo $this -> uri -> segment(4); ?>/page/<?php echo $this -> uri -> segment(7); ?>"
                            class="btn btn-danger"> 삭제 </a>
                        <a href="/bbs/board/write/<?php echo $this -> uri -> segment(3); ?>/page/<?php echo $this -> uri -> segment(7); ?>"
                            class="btn btn-success">쓰기</a>                    
                    </th>
                </tr>
            </tfoot>
        </table>
        
        <form class="form-horizontal" method="POST" action="" name="com_add">
            <fieldset>
                <div class="control-group">
                    <label class="control-label" for="input01">댓글</label>
                    <div class="controls">
                        <textarea class="input-xlarge" id="input01" name="comment_contents" rows="3"></textarea>
                        <input class="btn btn-primary" type="button" id="comment_add" value="작성" />
                        <p class="help-block"></p>
                    </div>
                </div>
            </fieldset>
        </form>
        <div id="comment_area">
            <table cellspacing="0" cellpadding="0" class="table table-striped">
                <tbody>
    <?php
        foreach ($comment_list as $lt) {
    ?>
                    <tr id="row_num_<?php echo $lt->board_id; ?>">
                        <th scope="row">
                            <?php echo $lt->user_id;?>
                        </th>
                        <td><?php echo $lt->contents;?></a></td>
                        <td>
                            <time datetime="<?php echo mdate("%Y-%M-%j", human_to_unix($lt->reg_date)); ?>">
                                <?php echo $lt->reg_date;?>
                            </time>
                        </td>
                        <td>
                            <a href="#" class="comment_delete" vals='<?php echo $lt->board_id; ?>')">
                                <i class="icon-trash"></i> 삭제
                            </a>
                        </td>
                    </tr>
    <?php
        }
    ?>
                </tbody>
            </table>
        </div>
    </article
    cs




     다음으로는 AJAX 컨트롤러의 일부분을 수정해야 합니다. 



     * bbs/application/controllers/ajax_board.php


    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    <?php
    if (!defined('BASEPATH'))
        exit('No direct script access allowed');
     
    /**
     * AJAX 처리 컨트롤러
     */
     
    class Ajax_board extends CI_Controller {
     
        function __construct() {
            parent::__construct();
        }
     
        /**
         * AJAX 테스트
         */
        public function test() {
            $this -> load -> view('ajax/test_v');
        }
     
        public function ajax_action() {
            echo '<meta http-equiv="Content-Type" content="test/html; charset=utf-8" />';
     
            $name = $this -> input -> post("name");
     
            echo $name . "님 반갑습니다 !";
        }
     
        public function ajax_comment_add() {
            if (@$this -> session -> userdata('logged_in'== TRUE) {
                $this -> load -> model('board_m');
                
                $table = $this -> input -> post('table', TRUE);
                $board_id = $this -> input -> post('board_id', TRUE);
                $comment_contents = $this -> input -> post('comment_contents', TRUE);
                
                if ($comment_contents != '' ){
                    $write_data = array(
                        "table" => $table,
                        "board_pid" => $board_id,
                        "subject" => '',
                        "contents" => $comment_contents,
                        "user_id" => $this -> session -> userdata('username')
                    );
                    
                    $result = $this -> board_m -> insert_comment($write_data);
                    
                    if ($result) {
                        $sql = "SELECT * FROM "$table ." WHERE board_pid = '"$board_id . "' ORDER BY board_id DESC";
                        $query = $this -> db -> query($sql);
    ?>
    <table cellspacing="0" cellpadding="0" class="table table-striped">
        <tbody>
    <?php
                        foreach ($query -> result() as $lt) {
    ?>
            <tr>
                <th scope="row">
                    <?php echo $lt -> user_id;?>
                </th>
                <td><?php echo $lt -> contents;?></td>
                <td>
                    <time datetime="<?php echo mdate("%Y-%M-%j", human_to_unix($lt->reg_date));?>">
                        <?php echo $lt -> reg_date;?>
                    </time>
                </td>
                <td>
                    <a href="#" class="comment_delete" vals="<?php echo $lt->board_id; ?>">
                        <i class="icon-trash"></i>삭제
                    </a>
                </td>
            </tr>
    <?php
                        }
    ?>
        </tbody>
    </table>
    <?php
                    } else {
                        // 글 실패시
                        echo "2000";
                    }
                } else {
                    // 글 내용이 없을 경우
                    echo "1000";
                }
            } else {
                // 로그인 필요 에러
                echo "9000";
            }
        }
     
        public function ajax_comment_delete() {
            if ( @$this -> session -> userdata('logged_in'== TRUE) {
                $this -> load -> model('board_m');
                
                $table = $this -> input -> post("table", TRUE);
                $board_id = $this -> input -> post("board_id", TRUE);
                
                $writer_id = $this -> board_m -> writer_check2($table$board_id);
                
                if ( $writer_id -> user_id != $this -> session -> userdata('username')) {
                    echo "8000";
                } else {
                    $result = $this -> board_m -> delete_content($table$board_id);
                    
                    if ($result) {
                        echo $board_id;
                    } else {
                        echo "2000"// 글 실패
                    }
                }
            } else {
                echo "9000"// 로그인 에러
            }
        }
     
    }
     
    cs









     


     댓글 쓰기, 삭제를 jQuery의 $.ajax를 이용해 구현했습니다. 뷰에서 Ajax 요청 -> 서버에서 데이터 처리, 가공 후 반환 -> 뷰에 응답 데이터 적용하는 패턴을 익혀두시기 바랍니다. 대부분의 AJAX 액션에서 사용되는 패턴입니다. 





    * 이 포스트는 서적 '만들면서 배우는 CodeIgniter 프레임워크'를 참고하여 작성하였습니다.

    댓글

Designed by Tistory.