본문으로 바로가기

tabulator 적용 사례 (인수인계 문서)

category 코딩/Tabulator 2023. 5. 11. 18:26

 

1. Basic

Basic - 페이지 진입 시

페이지가 최초로 로딩 되면 각각의 페이지와 매칭 되는 다음 형식의 URL을 AJAX 호출하여, grid에 출력할 data를 받아온다.

    형식 : _ajax/tabulator/폴더/파일명

본 페이지 URL에 GET 방식 Parameter String을 함께 받으면, 그대로 AJAX URL에도 함께 전달하여 SQL 조건절에 반영한다.

Basic - Tabulator.js

Tabulator 객체를 생성하면 ID가 지정된 Element에 grid를 그린다.

grid에 뿌려질 data는 JSON object 형식이어야 하며, 본 페이지 내에 inline으로 선언할 수도 있고, 특정 URL을 AJAX 호출하여 받아 올 수도 있다.

Basic - 검색

<form> 태그 내부 name을 가진 Element들이 검색 filter가 된다.

검색 실행 시 form.serialize() 메서드를 통해 GET 방식 Parameter를 문자열로 생성, 본 페이지 URL에 붙여 다시 호출한다(새로고침) = AJAX URL도 Parameter와 함께 다시 호출되어, 검색 조건에 해당하는 data가 grid에 뿌려진다.

 

 

 

2. Tabulator 심화 - 출력

Column object를 필요한만큼 선언하여, grid에 출력할 칼럼들을 설정할 수 있다.

AJAX를 통해 수신된 데이터는 2차원 구조로써, 연관배열 형태(key-value)를 가지는데, Column object의 Column 변수에 동일한 key를 지정하여 매칭할 수 있다.

/* admin/_ajax/tabulator/manage/driver.php */

    $row[$i]['CELL_PHONE'] = $row[$i]['CELL_PHONE1'].'-'.$row[$i]['CELL_PHONE2'].'-'.$row[$i]['CELL_PHONE3'];
...(생략)...
echo(json_encode($row));


/* admin/manage/driver.php */

    var columns = [
...(생략)...
        {title:"연락처", field:"CELL_PHONE", hozAlign:"center"},
        {title:"가입일", field:"REG_DT", hozAlign:"center"},

 

AJAX 호출은 아래와 같은 방식으로 한다.

/* admin/manage/driver.php */

    var table0 = new Tabulator("#table0", {
        height:"600px",
        layout:"fitDataStretch",
        frozenRows:1,
        ajaxURL:"/_ajax/tabulator/manage/driver.php" + window.location.search,
        // window.location.search로 현재 주소창의 GET Parameter를 전부 붙임

 

3. Tabulator 심화 - 편집

grid 내부에서 유저 이벤트를 통한 데이터 수정이 발생하면, cellEdited 변수에 지정된 사용자 함수(callback)로 처리할 수 있다.

callback 함수 ditedit_call 의 Parameter는 아래와 같다.

  • column DB 테이블의 어느 칼럼을 변경할 것인지를 string으로 지정한다.
  • val 어떤 값으로 변경할 것인지 지정한다.
  • idx 어느 row를 변경할 것인지 지정한다(SQL 조건절에 쓰인다).
/* admin/incoming/incoming.php */

function edit_cell (column, val, idx) {
    
    $.get("/_ajax/tabulator/_edit/incoming/incoming.php", { column: column, val: val, idx: idx }, function(data) {

        if (data == 'success') { alert('수정 완료'); }
        else console.log(data);

    });

}
...(생략)...
        {title:"송장번호", field:"del_invoice", hozAlign:"center"},
        {title:"메모", field:"del_memo", hozAlign:"center", width:150, editor:"input", cellEdited:function(cell){
            edit_cell( "del_memo", cell.getValue(), cell.getRow().getCell("del_no").getValue() );
        },},
        {title:"저장위치", field:"del_position", hozAlign:"center"},

위에서는 평문(plain text)을 입력 받아 칼럼을 업데이트하지만, 아래처럼 select 방식(drop-down)으로 선택하도록 할 수 있다.

/* admin/incoming/dispatch.php */

        {title:"배차상태", field:"accept_yn", hozAlign:"center", editor:"select", editorParams:{values:{"배차중":"배차중", "배차완료":"배차완료"}}, cellEdited:function(cell){
            edit_cell( "accept_yn", cell.getValue(), cell.getRow().getCell("seq").getValue() );
        }, formatter:cell_text_color},

 

cellEdited 변수에 지정된 사용자 함수(callback)는 각 페이지마다 선언되어 있고, 함수명은 edit_cell 이다. 이벤트가 발생하면 각각의 페이지와 매칭 되는 다음 형식의 URL을 AJAX 호출하여, 요청을 처리한다.

    형식 : _ajax/tabulator/_edit/폴더/파일명

1차 개발 시점 기준, 해당 요청 처리는 UPDATE(수정)만 처리하고 있다.

예) 운전사 승인/미승인 처리, 배차중/배차완료 처리 등...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4. ajax 호출로 element 갱신

페이지 로딩 시, 또는 유저 이벤트 발생 시 페이지에 새로운 데이터를 출력하는 경우가 있다.

예) 클릭한 운송건의 좌표를 modal에 표시, 배차할 운전사를 검색 - listing 등...

해당 처리는 모두 _ajax/renew 폴더에서 하고 있다.

    형식 : _ajax/renew/폴더_액션.php

마찬가지로 Parameter는 GET 방식 문자열로 받는다.

 

 

 

 

 

 

 

 

  • _filter_transfer.php 운송사를 중복 없이 <select> element에 listing 한다. 운송사는 유동적인 data이기 때문. 여러 메뉴에서 쓰인다.
  • driver_ocr.php 운전사관리 메뉴에서 관리 아이콘을 클릭하면 modal에 ocr 정보를 출력한다.
  • incoming_info_driver.php 아래에서 listing 된 운전사들 중 하나를 선택하면, 선택된 운전사의 상세 정보(아이디, 휴대폰번호, 차량번호)를 출력한다.
  • incoming_search_driver.php 입출고현황 메뉴에서 '배차하기' 버튼을 클릭, 배차 대상 운전사를 검색하면 검색 조건에 맞는 운전사들을 <select> element에 listing 한다.
  • tracking_point.php 운송현황 메뉴에서 위치 아이콘을 클릭하면 modal에 지도 정보를 출력한다.

 

5. action 폴더

1~4번에서 서술한 내용 외의 이벤트를 처리하는 파일들이 존재하는 폴더이다.

 

 

 

 

 

 

 

 

 

 

 

 

 

  • member/change_pwd.php 로그인 사용자가 패스워드 변경 시 처리한다.
  • member/login.php 로그인을 처리한다.
  • member/logout.php 로그아웃을 처리한다.
  • driver_info.php 운전사관리 메뉴에서 OCR에 기반한 정보를 편집, 저장 시 처리한다.
  • incoming_push.php 입출고현황 메뉴에서 '배차하기 → 배차알림보내기' 액션을 처리한다.

 

6. DB 컨트롤

db_conf.php 파일에 접속 대상 DB 서버를 리스팅, connection string을 정의해 놓는다.

samjin과 samjin_mall은 예시 데이터이다(향후 시스템 구성 시 여러 DB에 접근할 경우가 발생할 수 있으므로)

<?
/* admin/_library/db_conf.php */

$db_server = array(
// local은 아니지만(원격지 서버이지만) 메인 DB 서버이므로 local이라고 명명
        'local' => array(
            'type'  => "mysql",
            'host'  => '221.143.43.206',
            'user'  => 'mtcs',
            'pass'  => 'pass',
            'db'    => 'db'
        ),
        'samjin' => array(
            'type'  => "mssql", // DBMS 지정 가능
            'host'  => '125.141.224.199',
            'user'  => 'user',
            'pass'  => 'pass',
            'db'    => 'db'
        ),
        'samjin_mall' => array(
            'type'  => "mssql",
            'host'  => '125.141.224.199',
            'user'  => 'user',
            'pass'  => 'pass',
            'db'    => 'db'
        ),
    );

?>

DB 조작은 아래 4가지 함수로 처리하는데, 기본적으로 local에 질의하는 경우 해당 Parameter는 생략 가능하게 되어 있다.

<?
include 'db_conf.php';

// db.conf.php 파일에서 정의한 DB 서버들에 접속한다.
function dbConnect($server='local')

// SELECT 외의 쿼리를 수행한다. INSERT 시에는 이번에 생성한 row의 key도 구한다.
function dbQuery($query, $server='local')

// 1개의 row만 SELECT하여 1차원 배열로 구한다.
function selectOne($query, $return_type='arr', $server='local')

// 조건에 해당하는 모든 row를 SELECT하여 2차원 배열로 구한다.
function selectAll($query, $server='local')
?>

 

7. DB 쿼리와 SELECT 컨트롤 (조회한 row 처리)

상기 서술한 바와 같이 grid에 출력할 data는 _ajax/tabulator/폴더/파일명 파일과 쌍을 이루어 조회하고 있다.

그런데 grid에 출력할 칼럼이 추가/변경 되는 경우가 있을 것이다.

이 때 SQL Query문을 능숙히 작성할 수 없거나, query문만으로는 데이터를 처리/조합할 수 없는 경우, 하단에서 전체 반복문을 돌려서 PHP 구문으로 처리할 수 있다.

/* admin/_ajax/tabulator/manage/customer.php */

$query = "SELECT a.TC_IDX, a.TC_NAME , b.CUSTOMER_IDX, b.CUSTOMER_ALIAS, b.CUSTOMER_NAME,
            b.MANAGER, b.PHONE, b.MANAGER_EMAIL, b.REG_DT
                FROM TRANSPORT_COMPANY AS a
                JOIN CUSTOMER AS b ON a.TC_IDX=b.TC_IDX
            $where";
// echo $query.'<br>';
$row = selectAll($query); // SQL 쿼리로 데이터를 구한다

// 쿼리에서 처리하지 못하는 칼럼은 아래 반복문에서 다룬다.
for ($i = 0; $i < count($row); $i++) {

    $row[$i]['unknown'] = '-'; 

}

if (@count($row) == 0) $row[0]['tmp'] = 0; // tabulator.js 는 데이터가 없는 경우라도 JSON object 자체는 구성 되어야 한다.

echo(json_encode($row));

 

8. ajax 페이지 디버깅 Tip

에러 발생 시 화면

DB 컨트롤러 파일을 수정하는 경우, tabulator grid에 출력할 데이터를 불러오는 중 에러가 발생할 수 있다.

이 경우 디버깅하려면 우선 아래 쿼리문 출력 부분을 주석 해제한다.

/* admin/_ajax/tabulator/manage/customer.php */

$query = "SELECT a.TC_IDX, a.TC_NAME , b.CUSTOMER_IDX, b.CUSTOMER_ALIAS, b.CUSTOMER_NAME,
            b.MANAGER, b.PHONE, b.MANAGER_EMAIL, b.REG_DT
                FROM TRANSPORT_COMPANY AS a
                JOIN CUSTOMER AS b ON a.TC_IDX=b.TC_IDX
            $where";
// echo $query.'<br>'; // 주석 해제
$row = selectAll($query);

그리고 에러가 발생하고 있는 현재 페이지의 URL을 전부 복사하여, 브라우저에서 새 탭을 열고 붙인다.

붙인 후 URL에서 다음 부분만 변경하면 쿼리문을 확인 가능한데, 전체 복사하여 sql yog 등의 DB 관리 툴에서 실행해 보면 쿼리에 어떤 문제가 있는지 쉽게 파악할 수 있다.

 

제목 제목
http://도메인/incoming/tracking.php http://도메인/_ajax/tabulator/incoming/tracking.php

 

쿼리 문제가 아니라 PHP 코드 문제일 수 있다. 이 경우 에러 메시지를 확인할 수 없다면 서버 설정 때문이므로, 해당 페이지 상단에 아래 구문을 추가한다.

<?
    error_reporting( E_ALL );
    ini_set( "display_errors", 1 );
?>

 

9. 기타 유효한 파일들 (프론트, 퍼블리싱 등)

  • _include/head.php 공통으로 적용할 HTML Dcument 최상단 부분 - <head> 태그 내용.
  • _include/header.php 공통으로 적용할 HTML Document - body 최상단 부분.
  • _include/nav.php 좌측 menu 부분.
  • assets/css/custom.css 참조하고 있는 템플릿 스타일(워드프레스 등) 외에 직접 css를 설정한다.
  • assets/js/custom.js 공통으로 적용할 javascript(로그인, 로그아웃 등).
  • library/PHPExcel-1.8 쓰이지는 않고 있지만 엑셀 업로드 기능을 구현할 때 사용 예정이었던 라이브러리.