7주차 과제(WEB)_1

Peroro·2023년 5월 10일
0
post-custom-banner

7주차 웹 과제: 게시글 페이징

결과물

  • <, 1, 2, >와 같이 게시글 페이징에 대해서 구현을 해보았다.
  • <은 앞 block으로, 1,2는 페이지, >는 뒤 block으로 넘어가는 구조이다.

코드

//read_index.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./read_index.js"></script>
</head>
<body onload = "load()">
    <?php
        session_start();
        $page = isset($_GET['page'])? $_GET['page'] : 1;
        if(!isset($_SESSION['id'])){?>
            <input type="button" name = "login" id = "login" value="login" onclick = gotologin()><?php
        }
        else{?>
            <input type="post" name = "write" id = "write" value = "write" onclick = gotowrite()><?php
        }
    ?>
    <table>
    <thead>
        <tr>
            <td width="70">번호</td>
            <td width="500">제목</td>
            <td width="120">글쓴이</td>
            <td width="100">작성일</td>
            <td width="100">조회수</td>
        </tr>
    </thead>
    <tbody name = "result" id = "result">
    </tbody>
    </table>
    <input type="hidden" name="cur_page" id = "cur_page" value = <?php echo $page; ?> >
    <p class = "pagerclass" id = "pager">
    </p>
    <input type="text" name="cur_word" id="cur_word">
    <input type="submit" value="" onclick="findboard()">
</body>
</html>
  • 변화가 거의 없는 모습이다.
  • paragraph 'pager'와 hidden type 'cur_page'가 생겼다.
//read_index.js
function gotowrite(){
    location.href = "write.php";
}
function gotologin(){
    location.href = "login.php";
}
function load(){
  findboard();
  paging();
}
// one page = 10 list, one block = 5 pages
function findboard(){
    const word = document.getElementById('cur_word').value;
    const page = document.getElementById('cur_page').value;        
        // Ajax 요청 보내기
    const xhr = new XMLHttpRequest();
    xhr.open('GET', '/get_read_index.php?request=board&page=' + encodeURIComponent(page) + '&word=' + encodeURIComponent(word));
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4 && xhr.status === 200) {
          const response = JSON.parse(xhr.responseText);
            
          // 응답 데이터 처리하기
          updateUI(response);
      }
    };
    xhr.send();
}

function updateUI(response){
    const tableBodyElement = document.getElementById('result');
    tableBodyElement.innerHTML = ''; // 테이블 본문 요소 초기화
  
    for (const record of response) {
      const rowElement = document.createElement('tr'); // 새로운 tr 요소 생성
      const BID = document.createElement('td'); 
      const ID = document.createElement('td');
      const TITLE = document.createElement('td');
      const DATE = document.createElement('td');
      const HIT = document.createElement('td');
      BID.textContent = record.bid;
      ID.textContent = record.id;
      TITLE.textContent = record.title;
      DATE.textContent = record.date;
      HIT.textContent = record.hit;// td 요소에 데이터 설정
      rowElement.appendChild(BID); 
      rowElement.appendChild(TITLE);
      rowElement.appendChild(ID);
      rowElement.appendChild(DATE);
      rowElement.appendChild(HIT);// td 요소를 tr 요소에 추가;
      tableBodyElement.appendChild(rowElement); // tr 요소를 테이블 본문 요소에 추가
      TITLE.addEventListener('click', function(){
            location.href = "read.php?bid=" + record.bid;
      })
    }
}

function paging(){
  const page = document.getElementById('cur_page').value;
  const word = document.getElementById('cur_word').value; 
  const xhr = new XMLHttpRequest();
  xhr.open('GET', '/get_read_index.php?request=page&page=' + encodeURIComponent(page)+ '&word=' + encodeURIComponent(word));
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4 && xhr.status === 200) {
          const response = JSON.parse(xhr.responseText);
          Updatepage(response, page, word);
      }
    };
    xhr.send();
}

function Updatepage(response, current_page, current_word){
  const pager = document.getElementById('pager');
  pager.innerHTML = '';
  const {start_page, end_page} = response.page_info;


  const previousPage = document.createElement('a');
  previousPage.href = `read_index.php/?page=${start_page - 1}`;
  previousPage.innerText = '<';
  pager.appendChild(previousPage);

  for (let i = start_page; i <= end_page; i++) {
    const pageLink = document.createElement('a');
    pageLink.href = `/read_index.php?page=${i}`;
    pageLink.innerText = i;
    if (i === parseInt(current_page)) {
      pageLink.className = 'active';
    }
    pager.appendChild(pageLink);
  }
  const nextPage = document.createElement('a');
  nextPage.href = `read_index.php/?page=${parseInt(end_page) + 1}`;
  nextPage.innerText = '>';
  pager.appendChild(nextPage);

}
  • paging함수와 그 page를 update 해주는 updatepage 함수가 생겼다.
  • findboard의 경우도 쿼리문을 바로 보내주던 방식이 아닌, 단어를 받으면 그 단어를 서버에 보내주는 방식으로 바꾸었다.
  • paging 함수는 findboard와 마찬가지로 현재 page와 word를 보내는 함수이다.
  • Updatepage 함수는 AJAX 요청을 통해 받아온 start_page, end_page에 대한 정보를 통해 page를 구성한다.
//get_read_index.php
<?php
    #const start_num = (page - 1)*list;
    #const query = `SELECT bid, id, title, created, hit FROM board WHERE title LIKE '%${word}%' ORDER BY bid DESC LIMIT ${start_num}, ${list}`;
    $conn = new mysqli('localhost', 'conn', 'Testnote!%89','test');
    $request = $_GET['request'];
    $page = $_GET['page'];
    $word = $_GET['word'];
    $list_num = 10;
    $page_num = 5;
    $first_board = ($page - 1) * $list_num;
    if($request == 'board'){
        $q = "SELECT bid, id, title, created, hit FROM board WHERE title LIKE '%$word%' ORDER BY bid DESC LIMIT $first_board, $list_num";
        $result = $conn->query($q);
        $rows = array();
    
        while($row = $result->fetch_array(MYSQLI_ASSOC)) {
            $rows[] = $row;
        }
    }
    else if($request == 'page'){
        $block = ceil($page/$page_num); #몇번째 block인지 계산
        $q = "SELECT COUNT(*) FROM board where LIKE '%$word%' ORDER BY bid";
        $all = $conn->query($q)->fetch_row()[0];
        $end = ceil($all/$list_num); #마지막 페이지 번호
        
        $start_page = ($block - 1) * $page_num + 1; # block의 시작 page
        $end_page = min($end, $block * $page_num); # block의 끝 page
        
        $page_info = array('start_page' => $start_page, 'end_page' => $end_page);
        $rows['page_info'] = $page_info;
    }

    header('Content-Type: application/json');
    echo json_encode($rows);
    ?>
  • get_read_index.php는 먼저 request의 값을 받고 board, page로 나뉘게 된다.
  • board는 이전과 마찬가지로 게시글에 대한 정보를 json으로 보낸다.
  • page의 경우 현재 page를 계산해 몇번째 block인지 계산을 하고 그 block의 start page와 end page에 대한 정보를 보내준다.

문제점

첫번째

  • <, >를 누르면 음수를 띄거나 화면을 띄우지 못한다. 아마도 block이 음수나 index를 초과하는 경우가 생긴 거 같은데 이를 정리할 필요가 있어보인다.

두번째

  • 페이지 번호를 누르면 검색이 초기화되는 현상이 있다. page버튼을 눌렀을 때 cur_word인자도 넘어가게 바꿔야 할 것 같다.

세번째

  • 페이지 간격이 너무 좁다. css를 통해서 간격을 늘릴 필요가 있어보인다.
profile
오늘 공부한 것을 올리는 공간 / 일주일에 글 3개 / 블로그 이전 : https://perorochan321.tistory.com/
post-custom-banner

0개의 댓글