본문 바로가기
코드이그나이터와 php7와 mysql

코드이그나이터4, 검색어 자동 추천 ! [ jQuery Ajax ]

1. 오토셋 APM 인스톨러 ( apache + php7.2 + mariadb ) 설치 | https://itadventure.tistory.com/93

2. 코드이그나이터 4 ( codeigniter 4 ) 설치 | https://itadventure.tistory.com/95

3. 비주얼 스튜디오 코드 에디터 설치 & 한글 설정 | https://itadventure.tistory.com/96

4. 폴더열기 / 웹페이지 편집(1) | https://itadventure.tistory.com/97

5. 웹페이지 편집(2) | https://itadventure.tistory.com/101

6. 코드이그나이터4의 URL 규칙 | https://itadventure.tistory.com/105

7. php, 네임스페이스 [ namespace ] ?! | https://itadventure.tistory.com/118

8. 코드이그나이터의 네임스페이스, 그리고 모델 | https://itadventure.tistory.com/122

9. 코드이그나이터 뷰의 파라미터 전달 | https://itadventure.tistory.com/147

10. 코드이그나이터 뷰를 나눠 볼까요? | https://itadventure.tistory.com/174

11. MYSQL 이 뭐여? [ 마이에스큐엘은 서류철이다! ] | https://itadventure.tistory.com/175

12. MYSQL 콘솔에 접속해보자! | https://itadventure.tistory.com/178

13. MySql에 넣었다가 꺼냈다가, 뭘? | https://itadventure.tistory.com/265

14. 검색진열대 MYSQL | https://itadventure.tistory.com/267

15. 편집의 왕자 MySQL | https://itadventure.tistory.com/269

16. 코드이그나이터4, MYSQL과 손잡다. | https://itadventure.tistory.com/271

17. MySQL -> 컨트롤러 -> 뷰 트리플 패스! | https://itadventure.tistory.com/272

18. 코드이그나이터! MySQL 에 입력하다! ( insert ) | https://itadventure.tistory.com/273

19. 해킹을 막아라! MySQL인젝션 보안 | https://itadventure.tistory.com/274

20. MySQL과 친해지는 phpmyadmin | https://itadventure.tistory.com/277

21. 코드이그나이터4에서 책 정보를 편집해볼까요? | https://itadventure.tistory.com/280

22. 코드이그나이터4에서 책을 지워봅시다. DELETE! | https://itadventure.tistory.com/282

23. 코드이그나이터4, 페이징 기술 | https://itadventure.tistory.com/285

24. 코드이그나이터4. 검색! | https://itadventure.tistory.com/295

25. 코드이그나이터4. 검색어 자동 추천!


이번 시간에는 네이버처럼 일부 단어를 타이핑하면
연관된 책목록이 최대 10개 자동으로 노출되어
책을 선택하는 기능에 대해 다루어 보겠습니다.
물론 네이버처럼 고차원적이지는 않는
연습 정도의 수준이긴 하지만요 :) 

우선 소스를 먼저 구성해서 저장해보겠습니다.
아래와 같이 각각 소스를 구성해서 저장해 보세요.

코드이그나이터폴더\app\Controllers\BookList4.php

<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class BookList4 extends Controller
{
    public function index()
    {        
        $db = \Config\Database::connect("default", false);
        $pageview=20;
        $page=$this->request->getVar("page");
        $searchword=$this->request->getVar("searchword");
        if($page=="")$page=1;
        $startlimit=($page-1)*$pageview;
        $query_count = $db->query("SELECT count(*) FROM book where title like '%".addslashes($searchword)."%'");
        $results_count = $query_count->getResultArray();
        $total = $results_count[0]['count(*)'];
        $totalpage = ceil($total / $pageview);
        $pagestr="{$total}건, {$totalpage}페이지 / ";
        for($i=1;$i<=$totalpage;++$i){
            $pagestr .= "<a href='?page=$i&searchword=$searchword' style='text-decoration:none'>";
            if($i==$page)$pagestr .= "<span style='color:red;font-weight:bold'>[";
            $pagestr .= "$i";
            if($i==$page)$pagestr .= "</span>]";
            $pagestr .= "</a> ";
            
        }
        $query = $db->query("SELECT * FROM book where title like '%".addslashes($searchword)."%' order by number desc limit $startlimit, $pageview");
        $results = $query->getResultArray();
        $data = [
            'title'=>"도서 목록",
            'booklist'=>$results,
            'pagestr'=>$pagestr,
            'searchword'=>$searchword
        ];
        return view('booklist4', $data);
    }
}

코드이그나이터폴더\app\Controllers\BookAjax.php

<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class BookAjax extends Controller
{
    public function index()
    {        
        $db = \Config\Database::connect("default", false);
        $searchword=$this->request->getVar("searchword");
        $query = $db->query("SELECT * FROM book where title like '%".addslashes($searchword)."%' order by number desc limit 10");
        $results = $query->getResultArray();
        $data = [
            'booklist'=>$results
        ];
        return view('bookajax', $data);
    }
}

코드이그나이터폴더\app\Views\booklist4.php

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
    .title_style { font-size:12pt; color:blue}
    .author_style { font-size:9pt; color:gray}
    #preview {
        top:0px;left:0px;
        width:500px;height:200px;
        border:1px solid black;
        background-color:white;
        overflow:auto;
    }
</style>
<script>
function findbook()
{
  if($('#searchword').val()=='')
  {
      $("#preview").hide();
      return;
  }
  $.ajax({
    url: "./bookAjax",
    type: "POST",
    data: {searchword : $('#searchword').val() },
    dataType: "html",
    success: function(data) {
      $("#preview").html(data);
      $("#preview").show();
    }
  });
  
}

function search_input(obj)
{
    $("#searchword").val($(obj).text());
    document.frm.submit();
}
</script>
<u><b><?=$title?></b></u><br/>
<?=$pagestr?>
<form name="frm" method=post action="bookList4">
제목 검색 : <input type=text name=searchword id=searchword value="<?=$searchword?>" onkeyup="findbook()">
<input type=submit value="검색">
</form>
<div style="position:relative">
    <div id="preview" style="position:absolute;display:none">

    </div>
</div>
<hr/>
<? foreach ($booklist as $book){?>
<span class=title_style><?= $book['title']?></span>
<span class=author_style>/ <?= $book['author']?></span>
<span class=author_style>/ <a href="bookEdit?number=<?= $book['number']?>">[편집]</a></span>
<span class=author_style>/ <a href="bookDelete?number=<?= $book['number']?>">[삭제]</a></span>
<br/>
<? } ?>
<hr/>
<?=$pagestr?><br/>

코드이그나이터폴더\app\Views\bookajax.php

<? foreach ($booklist as $book){?>
<span onclick="search_input(this)" style="cursor:pointer"><?=$book['title']?></span><br/>
<? } ?>

 

소스를 모두 구성하신 다음 아래 URL 에 접속하시면 내 PC 의 웹서버가 지금 구성한 책 목록 페이지에 연결해주겠지요.

http://localhost/bookList4

화살표가 있는 지점을 마우스로 클릭하고 '자바'라고 한번 타이핑해보세요.
그러면 '자바'라는 단어가 들어간 책 제목이 주루룩 뜹니다.

그 중 하나를 클릭해서 선택하면, 책 제목이 자동으로 입력되면서 검색이 됩니다.
이 것이 이번 챕터의 전부입니다.

이번 챕터는 소스가 4개인데요.
2개는 책목록을 보여주기 위한 컨트롤러와 뷰이고,

다른 2개는 검색어를 타이핑할 때 상자에 들어갈 책목록을
실시간으로 뽑아내는 컨트롤러와 뷰입니다.

보통 이런 기술을 Ajax 라고 부르는데요.
화면 깜박임 없이 실시간으로 내용을 바꿔줄 수가 있어서 아주 유용하게 사용되고 있습니다.

우선 BookList4 컨트롤러는 지난번과 비교할 때 전혀 변경된 것이 없어 넘어가도록 하겠습니다.

booklist4 뷰는 꽤 많이 바뀌었는데요.
한 부분 한 부분씩 살펴보겠습니다.

첫번째 줄에 나오는 다음 라인은 jQuery 라고 불리는 자바스크립트 라이브러리를 사용하기 위한 선언입니다.
jQuery 는 무엇일까요? jQuery 는 자바스크립트만으로 불편했던 기능을 보강해주는 일종의 기술 덩어리입니다.
이 한줄만 넣으면 jQuery 를 사용할 수가 있는데요.
자바스크립트로 10~20줄을 구성해야 하는 소스를 단 한 줄로 쓸 수도 있어 매우 유용하게 사랑받는 기술입니다.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

그 다음으로 style 태그가 나오는데요. #preview 라는 스타일이 추가가 되었군요.
이 css 태그는 id값이 preview 라는 항목의 css 스타일을 정의해주는 겁니다.
본문에서 style="" 태그 안에 모두 넣기보다는 여기서 정의해주면 소스가 깔끔해지는 이점이 있습니다.
참고로 preview 는 검색결과 10개를 보여줄 사각형의 상자를 의미하는데 잠시후에 등장합니다.

<style>
     :
    #preview {
        top:0px;left:0px;
        width:500px;height:200px;
        border:1px solid black;
        background-color:white;
        overflow:auto;
    }
</style>

그 다음으로 자바스크립트가 나오는데요. 바로 잠시 후에 다뤄보겠습니다.

이어서 변경된 부분은 바로 텍스트를 입력하는 부분인데요.
뒷 부분에 onkeyup="findbook()" 이 추가되었습니다.
onkeyup 은 키보드가 눌렸다가 놓일 때에 발생하는 이벤트인데요.

만일 "Do" 를 타이핑하다고 치면 "D" 키를 눌렀다 놓을때 이벤트가 한번 발생, "o"키를 눌렀다 놓을 때 또 한번 이벤트가 발생하여 총 2번의 이벤트가 발생합니다.
그러니까 findbook() 함수로 2번 실행되는 것이지요.

제목 검색 : <input type=text name=searchword id=searchword value="<?=$searchword?>" onkeyup="findbook()">

이제 자바스크립트 findbook()을 살펴볼까요?
이 부분은 책의 목록을 불러오는 ajax 라는 기술을 사용하는 jQuery 기술입니다.

function findbook()
{
  if($('#searchword').val()=='')
  {
      $("#preview").hide();
      return;
  }
  $.ajax({
    url: "./bookAjax",
    type: "POST",
    data: {searchword : $('#searchword').val() },
    dataType: "html",
    success: function(data) {
      $("#preview").html(data);
      $("#preview").show();
    }
  });  
}

앞 부분에 등장하는 아래코드는 단지 입력된 내용이 아무것도 없을 때
검색어 상자를 숨겨주는 역활을 하는 코드입니다.

if($('#searchword').val()=='')
  {
      $("#preview").hide();
      return;
  }

그리고 입력된 검색어가 있다면,
아래 부분이 실행되는데요.

  $.ajax({
    url: "./bookAjax",
    type: "POST",
    data: {searchword : $('#searchword').val() },
    dataType: "html",
    success: function(data) {
      $("#preview").html(data);
      $("#preview").show();
    }
  });  

먼저 url 은 호출할 컨트롤러의 주소입니다.
type 뒤에 나오는 "POST"은 post 로 데이터를 전달하겠다는 의미인데 form 가 동일한 방식이 사용됩니다.
data 는 전달할 파라미터를 넣어두면 됩니다. 여기서는 searchword 1개만 사용되었지만, 콤마로 구분하여 여러개를 넣을 수도 있습니다.
dataType 은 보통 "html"이나 "json"을 사용하는데 여기서는 "html"을 사용하였습니다.
그리고 success 의 경우 ajax 실행이 끝난 다음 작동할 자바스크립트 코드를 넣어주는 부분입니다.

아래 코드의 경우 받아온 결과를 id 값이 preview 인 상자에 html 코드를 그대로 넣어주고,

$("#preview").html(data);

preview 상자를 화면에 보이도록 해줍니다. 처음에는 일부러 안 보이게 숨겨놓았기 때문입니다.

$("#preview").show();

 

 

preview 상자는 소스 중에 아래와 같은 부분을 의미하는데요.
바로 이 곳에 검색결과가 미리보기로 표시되는 것이지요.
처음에는 display:none 속성 때문에 숨겨져 있습니다.

<div style="position:relative">
    <div id="preview" style="position:absolute;display:none">

    </div>
</div>

이 ajax 는 bookAjax 컨트롤러를 호출합니다.
그래서 결과를 받아오는데요. searchword 가 파라미터로 사용됩니다.

bookAjax 컨트롤러는 BookAjax.php 를 의미하는데요.
우선 책목록과 앞 부분은 비슷합니다.

        $db = \Config\Database::connect("default", false);
        $searchword=$this->request->getVar("searchword");

다만 책목록을 무조건 10개만 받아오는 부분이 실행되고

$query = $db->query("SELECT * FROM book where title like '%".addslashes($searchword)."%' order by number desc limit 10");

쿼리 결과를 $data 에 담았다가

        $results = $query->getResultArray();
        $data = [
            'booklist'=>$results
        ];

bookajax 뷰로 전달합니다.

return view('bookajax', $data);

bookajax 뷰에서는 받아온 결과를 foreach  반복문을 이용해서

<? foreach ($booklist as $book){?>
   :
<? } ?>

아래 코드로 결과를 출력합니다. 최대 10줄이 출력되겠지요.

<span onclick="search_input(this)" style="cursor:pointer"><?=$book['title']?></span><br/>

만일 앞의 검색 상자에서 Do 를 입력했다면 최종적으로 아래와 같은 HTML 소스를 만들어 내고

<span onclick="search_input(this)" style="cursor:pointer">파나소닉 루믹스 G로 찍는 사진의 마법 [개정판]</span><br/>
<span onclick="search_input(this)" style="cursor:pointer">니콘 DSLR 카메라 입문</span><br/>
<span onclick="search_input(this)" style="cursor:pointer">미러리스 & 하이브리드 카메라 입문</span><br/>
<span onclick="search_input(this)" style="cursor:pointer">빅데이터, 승리의 과학</span><br/>
<span onclick="search_input(this)" style="cursor:pointer">프로페셔널 사진의 조건! 스트로보, 외장플래시</span><br/>
<span onclick="search_input(this)" style="cursor:pointer">프로페셔널 사진의 조건, 라이트룸5</span><br/>
<span onclick="search_input(this)" style="cursor:pointer">네이버 검색 1위 만들기</span><br/>
<span onclick="search_input(this)" style="cursor:pointer">삼성 NX 스마트 카메라 미러리스로 찍는 사진의 마법</span><br/>
<span onclick="search_input(this)" style="cursor:pointer">Do it! AutoCAD 오토캐드 2014</span><br/>
<span onclick="search_input(this)" style="cursor:pointer">Do it! AutoCAD 오토캐드 2015</span><br/>

그 결과가 preview 안에 html 태그로 그대로 들어가게 되는 것이지요. 
그래서 아래와 같은 결과를 낳게 되는 것입니다.

각 책제목의 태그를 살펴보시면 아래와 같은 부분이 있을텐데요.

<span onclick="search_input(this)"

책 제목을 클릭하면 search_input(this) 라는 스크립트가 실행이 됩니다.
참고로 this 는 책 제목 자기 자신을 의미하는데요. 이것을 어떻게 활용할 수 있을까요?

search_input 함수는 아래와 같이 선언되어 있습니다.
obj 파라미터가 금방 this 라고호출한 부분을 받아서 그대로 사용하는데요.
$(obj).text() 라고 쓰면 책 제목의 문장을 그대로 가져다 쓸 수 있습니다.

function search_input(obj)
{
    $("#searchword").val($(obj).text());
    document.frm.submit();
}

이번 챕터는 내용이 너무 길어질것 같아, 설명을 좀좀 빈약한 부분이 있는데요.
궁금하신 점 문의주시면 보충해 채워넣도록 하겠습니다.

필요하신 분에게 도움이 되셨기를 바라며
오늘도 여기까지 읽어주셔서 감사합니다.

반응형