ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CodeIgniter] 8. AJAX 구현: XMLHttpRequest
    Web/CodeIgniter 2015. 8. 26. 15:32

    8장에서는 AJAX(Asynchronous Javascript And XML) 방식을 이용해 게시판의 댓글을 구현해보곘습니다.


    jQuery 같은 자바스크립트 프레임워크를 사용하지 않고 XMLHttpRequest 를 이용해 구현합니다.


    들어가기 전에 AJAX에 대해 조금 알아보면 기존 방식의 사이트는 다음과 같습니다.

     - 웹 브라우저가 웹 서버에 요청을 전송

     - 웹 서버는 JSP/PHP/ASP 등 서버측 애플리케이션을 이용해 사용자의 요청을 처리한 뒤, 처리 결과를 HTML로 웹 브라우저에 전송

     - 웹 브라우저는 응답으로 받은 HTML을 화면에 출력


    AJAX 방식은 아래와 같습니다.

     - 사용자가 마우스 클릭 같은 이벤트를 발생시키면 자바스크립트는 DOM을 이용해서 필요한 정보를 구한 뒤, XMLHttpRequest 객체를 통해 웹 서버에 요청을 전달

     - 웹 서버는 요청에 대해 처리한 뒤 그 결과를 XML이나 JSON, HTML 또는 단순 텍스트로 생성해서 XMLHttpRequest에 전송

     - 서버로부터 응답이 도착하면 XMLHttpRequest 객체는 자바스크립트에 도착 사실을 알리고 자바스크립트는 응답 데이터와 DOM을 조작하여 사용자 화면에 반영


    AJAX는 웹 브라우저가 아닌 XMLHttpRequest 객체가 웹 서버와 통신을 하며 페이지 이동 없이(화면 깜빡임 없이) 결과가 화면에 반영됩니다.





    8.1 XMLHttpRequest 구현하기

     CodeIgniter에 적용하기 전에 매번 반복되는 XMLHttpRequest 객체를 사용하여 코드를 작성하기 번거롭기 때문에 해당 부분을 httpRequest.js 파일로 만들어 사용하겠습니다.


     bbs/include 디렉터리 내부에 js 폴더를 생성한 뒤, 그 안에 httpRequest.js 파일을 생성하여 작성하세요.


     * bbs/include/js/httpRequest.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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    function getXMLHttpRequest() {
        if (window.ActivXObject) {
            try {
                return new ActiveXObject("Msxml2.XMLHTTP");
            } catch(e) {
                try {
                    return ActiveXObject("Microsoft.XMLHTTP");
                } catch(e1) {
                    return null;
                }
            }
        } else if (window.XMLHttpRequest) {
            return new XMLHttpRequest();
        } else {
            return null;
        }
    }
     
    var httpRequest = null;
     
    function sendRequest(url, params, callback, method) {
        httpRequest = getXMLHttpRequest();
        var httpMethod = method ? method : 'GET';
     
        if (httpMethod != 'GET' && httpMethod != 'POST') {
            httpMethod = 'GET';
        }
     
        var httpParams = (params == null || params == '') ? null : params;
        var httpUrl = url;
     
        if (httpMethod == 'GET' && httpParams != null) {
            httpUrl = httpUrl + "?" + httpParams;
        }
     
        httpRequest.open(httpMethod, httpUrl, true);
        httpRequest.setRequestHeader('Content-Type''application/x-www-form-urlencoded');
        httpRequest.onreadystatechange = callback;
        httpRequest.send(httpMethod == 'POST' ? httpParams : null);
    }
     
    cs








    8.2 댓글 쓰기 AJAX로 구현하기

     댓글 쓰기 AJAX 처리에서 컨트롤러는 데이터를 입력하는 역할만 하고 뷰에서 화면 제어 등 많은 부분이 중요하기 때문에 뷰를 먼저 만듭니다.


     * 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
     
    <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() {
            var csrf_token = getCookie('csrf_cookie_name');
            var name = "comment_contents=" + encodeURIComponent(document.com_add.comment_contents.value) + 
                "&csrf_test_name=" + csrf_token + "&table=<?php echo $this->uri->segment(3); ?>&board_id=<?php echo $this->uri->segment(5); ?>";
            sendRequest("/bbs/ajax_board/ajax_comment_add"name, add_action, "POST");
        }
        
        function add_action() {
            if ( httpRequest.readyState == 4) {
                if ( httpRequest.status == 200) {
                    if ( httpRequest.responseText == 1000) {
                        alert("댓글의 내용을 입력하세요.");
                    } else if ( httpRequest.responseText == 2000) {
                        alert("다시 입력하세요.");
                    } else if ( httpRequest.responseText == 9000) {
                        alert("로그인하여야 합니다.");
                    } else {
                        var contents = document.getElementById("comment_area");
                        contents.innerHTML = httpRequest.responseText;
                        
                        var textareas = document.getElementById("input01");
                        textareas.value = '';
                    }
                }
            }
        }
        
        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" onclick="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>
                        <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>
                    </tr>
    <?php
        }
    ?>
                </tbody>
            </table>
        </div>
    </article
    cs



     Line 2: XMLHttpRequest 객체를 사용하기 위해 httpRequest.js 를 로드합니다.

     Line 22: 데이터를 XMLHttpRequest 객체를 이용해 어떤 주소에 전달하고 가공된 데이터를 받아 특정 함수를 실행합니다.

     Line 24: XMLHttpRequest 객체에 전달할 데이터를 만듭니다. 데이터는 쿼리스트링 방식으로 만듭니다. 게시글 입력을 위해 테이블 명, 원글 번호가 추가로 필요합니다.

     






     AJAX 컨트롤러에서는 POST 전송된 댓글 내용, 테이블 명, 테이블 번호를 이용해 데이터베이스에 입력하고, 입력된 결과를 HTML 형태로 만들어서 화면에 출력합니다.


     * 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
    <?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>
            </tr>
    <?php
                        }
    ?>
        </tbody>
    </table>
    <?php
                    } else {
                        // 글 실패시
                        echo "2000";
                    }
                } else {
                    // 글 내용이 없을 경우
                    echo "1000";
                }
            } else {
                // 로그인 필요 에러
                echo "9000";
            }
        }
     
    }
     
    cs



     Line 30: XMLHttpRequest 객체를 통해 전달받은 데이터를 가공하고, 댓글 리스트를 HTML 형태로 반환하는 ajax_comment_add() 함수를 작성합니다.

     Line 34: XMLHttpRequest 객체를 통해 전달받은 각 데이터를 인식하기 편한 변수명으로 바꿉니다.

     




     게시판 메인 컨트롤러인 board 컨트롤러에도 한 군데 추가해야 합니다. 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
     
    <?php
    if (!defined('BASEPATH'))
        exit('No direct script access allowed');
    /**
     *  게시판 메인 컨트롤러
     */
     
    class Board extends CI_Controller {
     
     
        ....
     
     
     
        /**
         * 게시물 보기
         */
        function view() {
            
            $table = $this -> uri -> segment(3);
            $board_id = $this -> uri -> segment(5);
            
            // 게시판 이름과 게시물 번호에 해당하는 게시물 가져오기
            $data['views'= $this -> board_m -> get_view($this -> uri -> segment(3), $this -> uri -> segment(4));
     
            // 게시판 이름과 세미루 번호에 해당하는 댓글 리스트 가져오기
            $data['comment_list'= $this -> board_m -> get_comment($table$board_id);
     
            // view 호출
            $this -> load -> view('board/view_v'$data);
        }
     
       
        ....
     
    }
     
    cs




     






     댓글 입력하는 모델은 게시물 입력 모델 함수와 거의 같습니다.



     * board_m.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
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
     
    <?php
    if (!defined('BASEPATH'))
        exit('No direct script access allowed');
     
    /**
     * 공통 게시판 모델
     */
     
    class Board_m extends CI_Model {
        function __construct() {
            parent::__construct();
        }
     
        function get_list($table = 'ci_board'$type = ''$offset = ''$limit = ''$search_word = '') {
     
            $sword = '';
     
            if ($search_word != '') {
                // 검색어 있을 경우
                $sword = ' WHERE subject like "%' . $search_word . '%" or contents like "%' . $search_word . '%" ';
            }
     
            $limit_query = '';
     
            if ($limit != '' OR $offset != '') {
                // 페이징이 있을 경우 처리
                $limit_query = ' LIMIT ' . $offset . ', ' . $limit;
            }
     
            $sql = "SELECT * FROM " . $table . $sword . " ORDER BY board_id DESC " . $limit_query;
            $query = $this -> db -> query($sql);
     
            if ($type == 'count') {
                $result = $query -> num_rows();
            } else {
                $result = $query -> result();
            }
     
            return $result;
        }
     
        /**
         * 게시물 상세보기 가져오기
         *
         * @param string $table 게시판 테이블
         * @param string $id 게시물 번호
         * @return array
         */
        function get_view($table$id) {
            // 조횟수 증가
            $sql0 = "UPDATE " . $table . " SET hits = hits + 1 WHERE board_id='" . $id . "'";
            $this -> db -> query($sql0);
     
            $sql = "SELECT * FROM " . $table . " WHERE board_id = '" . $id . "'";
            $query = $this -> db -> query($sql);
     
            // 게시물 내용 반환
            $result = $query -> row();
     
            return $result;
     
        }
        
        /**
         * 게시물 입력
         * 
         * @param array $arrays 테이블 명, 게시물 제목, 게시물 내용 1차 배열
         * @return boolean 입력 성공여부
         */
        function insert_board($arrays) {
            $insert_array = array(
                'board_pid' => 0,
                'user_id' => $arrays['userid'],
                'user_name' => 'palpit',
                'subject' => $arrays['subject'],
                'contents' => $arrays['contents'],
                'reg_date' => date("Y-m-d H:i:s")
            );
            
            $result = $this->db->insert($arrays['table'], $insert_array);
            
            return $result;
        }
        
        /**
         * 게시물 수정
         * 
         * @param array $arrays 테이블 명, 게시물 번호, 게시물 제목, 게시물 내용
         * @return boolean 성공 여부
         */
        function modify_board($arrays) {
            $modify_array = array(
                'subject' => $arrays['subject'],
                'contents' => $arrays['contents']
            );
            
            $where = array(
                'board_id' => $arrays['board_id']
            );
            
            $result = $this->db->update($arrays['table'], $modify_array$where);
            
            return $result;
        }
        
        /**
         * 게시물 삭제
         * 
         * @param string $table 테이블 명
         * @param string $no 게시물 번호
         * @return boolean 성공 여부
         * 
         */
        function delete_content($table$no) {
            $delete_array = array(
                'board_id' => $no
            );
            
            $result = $this->db->delete($table$delete_array);
            
            return $result;
        }
        
        
        /**
         * 게시물 작성자 아이디 반환
         * 
         * @return string 작성자 아이디
         */
        function writer_check() {
            $table = $this->uri->segment(3);
            $board_id = $this->uri->segment(5);
            
            $sql = "SELECT user_id FROM ".$table." WHERE board_id = '".$board_id."'";
            $query = $this->db->query($sql);
            
            return $query->row();
            
        }
        
        /**
         * 댓글 입력
         * 
         * @param array $arrays 테이블 명, 게시물 제목, 게시물 내용, 아이디 
         * @return boolean 성공 여부
         */
        function insert_comment($arrays) {
            $insert_array = array
                'board_pid' => $arrays['board_pid'],
                'user_id' => $arrays['user_id'],
                'user_name' => $arrays['user_id'],
                'subject' => $arrays['subject'],
                'contents' => $arrays['contents'],
                'reg_date' => date('Y-m-d H:i:s')
            );
            
            $this -> db -> insert($arrays['table'], $insert_array);
            
            $board_id = $this -> db -> insert_id();
            
            return $board_id;
        }
        
        /**
         * 댓글 리스트 가져오기
         * 
         * @param string $table 테이블 
         * @param string $id 게시물 번호
         * @return array
         * 
         */
        function get_comment($table$id) {
            $sql = "SELECT * FROM "$table . " WHERE board_pid = '"$id . "' ORDER BY board_id DESC";
            $query = $this -> db -> query($sql);
            
            $result = $query -> result();
            
            return $result;
        }
        
    }
     
    cs










    8.3 댓글 삭제 AJAX로 구현하기

     게시물 삭제도 뷰를 먼저 보겠습니다. 작동 순서는 삭제 버튼 클릭 -> AJAX 로 삭제할 테이블, 게시물 번호 전송 -> AJAX 컨트롤러에서 처리 후 결과 전송 -> 자바스크립트에서 후 처리입니다.









     * 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
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
     
    <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() {
            var csrf_token = getCookie('csrf_cookie_name');
            var name = "comment_contents=" + encodeURIComponent(document.com_add.comment_contents.value) + 
                "&csrf_test_name=" + csrf_token + "&table=<?php echo $this->uri->segment(3); ?>&board_id=<?php echo $this->uri->segment(4); ?>";
            sendRequest("/bbs/ajax_board/ajax_comment_add"name, add_action, "POST");
        }
        
        function add_action() {
            if ( httpRequest.readyState == 4) {
                if ( httpRequest.status == 200) {
                    if ( httpRequest.responseText == 1000) {
                        alert("댓글의 내용을 입력하세요.");
                    } else if ( httpRequest.responseText == 2000) {
                        alert("다시 입력하세요.");
                    } else if ( httpRequest.responseText == 9000) {
                        alert("로그인하여야 합니다.");
                    } else {
                        var contents = document.getElementById("comment_area");
                        contents.innerHTML = httpRequest.responseText;
                        
                        var textareas = document.getElementById("input01");
                        textareas.value = '';
                    }
                }
            }
        }
        
        function comment_delete(no) {
            var csrf_token = getCookie('csrf_cookie_name');
            var name = "csrf_test_name=" + csrf_token + "&table=<?php echo $this->uri->segment(3);?>&board_id=" + no;
     
            sendRequest("/bbs/ajax_board/ajax_comment_delete"name, delete_action, "POST");
        }
        
        function delete_action() {
            if (httpRequest.readyState == 4) {
                if (httpRequest.status == 200) {
                    if (httpRequest.responseText == 9000) {
                        alert('로그인해야 합니다');
                    } else if (httpRequest.responseText == 8000) {
                        alert('본인의 댓글만 삭제할 수 있습니다.');
                    } else if (httpRequest.responseText == 2000) {
                        alert('다시 삭제하세요.');
                    } else {
                        var no = httpRequest.responseText;
                        var delete_tr = document.getElementById("row_num_" + no);
                        
                        delete_tr.parentNode.removeChild(delete_tr);
                        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" onclick="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





     AJAX 컨트롤러에서는 POST 전송된 테이블 명, 테이블 번호를 이용해 데이터베이스에서 해당 댓글을 삭제하고 그 결과를 번호로 화면에 출력합니다.



     * 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
    <?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>
            </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











     XMLHttpRequest 객체를 이용해 AJAX로 처리하는 방법을 알아봤습니다.


     데이터를 주고받고 DOM 객체를 이용해 댓글 내용을 삽입하거나 삭제했습니다. 


     다음 장에서는 보다 손쉽게 처리할 수 있는 jQuery 프레임워크를 통해 댓글 기능을 보완해보도록 하겠습니다.





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



    댓글

Designed by Tistory.