그리드 기능과 적용방법

FE개발팀

김동우

그리드가 뭔가요?

테이블 형식의 데이터를 에서 쉽게 보여주고 편집할 수 있도록 도와주는 Javascript Library

Test Environment

  • IE 7 - Windows XP
  • IE 8 - Windows XP
  • IE 9 - Windows 7
  • IE 10 - Windows 7
  • IE 11 - Windows 7
  • Chrome (Latest) - Windows 7 
  • Firefox (Latest) - Windows 7 

Features

Edit Types

Column Resize

Merge

Frozen Columns

Copy & Paste

Keyboard Control

Sort

Pagination

Smart Rendering

More..

  • 서버 데이터 연동
  • Row 추가 / 삭제
  • Row 활성화 / 비활성화
  • 커스텀 데이터 포맷
  • 커스텀 이벤트 핸들러 등록
  • Column간 Relation 설정
  • Ajax History (Pagination)
  • ....

설치하기

Github Repository

https://github.com/nhnent/fe.application-grid

 Download Files

  • grid.js (grid.min.js)
  • grid.css
  • images/sp_bu.gif
  • images/sp_btn.gif
  • images/uiogrid_loading.gif

 Dependency

  • jquery ~1.8.3
  • jquery-json ~2.5.1
  • backbone ~1.1.2
  • underscore ~1.8.3
  • ne-code-snippet ~1.0.1
  • ne-component-pagination ~1.0.0

음...

좀더 간단한 방법은 없나요?

Bower??

Front-End Package Manager

$ npm install -g bower

Node.js - https://nodejs.org 

Install

한줄에 딱..

$ bower install ne-application-grid

$ cd bower_components

$ ls

backbone                      underscore

jquery-json                    jquery   

ne-code-snippet           ne-component-pagination

ne-application-grid

끝!

웹페이지에 적용하기

Copy Files

  • css
    • grid.css
  • image
    • sp_bu.gif
    • sp_btn.gif
    • uiogrid_loading.gif
  • js/lib
    • jquery.js
    • jquery.json.js
    • underscore.js
    • backbone.js
    • code-snippet.js
    • grid.js

grid.css

...


.btn_text,.btn_text span{display:inline-block;background:url(../images/bg_btn_text.gif) 0 0 no-repeat;color:#333;letter-spacing:-1px;text-decoration:none;white-space:nowrap;cursor:pointer}
.btn_text span{margin-left:8px;padding-right:7px;background-position:100% 0}
.btn_text:hover,.btn_text span:hover,.btn_text:focus,.btn_text span:focus{background-position:0 -30px}
.btn_text:active,.btn_text span:active{background-position:0 -60px}
.btn_text span:hover,.btn_text span:focus{margin-left:8px;padding-right:7px;background-position:100% -30px}
.btn_text span:active{margin-left:8px;padding-right:7px;background-position:100% -60px}
.btn_text .excel{display:inline-block;padding-left:17px;background:url(
../images/sp_bu.gif) no-repeat 0 5px}
.btn_text .grid{display:inline-block;padding-left:17px;background:url(
../images/sp_bu.gif) no-repeat 0 -21px}
.btn_text2,.btn_text2 span{display:inline-block;background:url(
../images/bg_btn_text.gif) 0 -90px no-repeat;color:#444;letter-spacing:-1px;text-decoration:none;white-space:nowrap;cursor:pointer}
.btn_text2 span{margin-left:8px;padding-right:7px;background-position:100% -90px}

 

.btn_sp span{display:inline-block;overflow:hidden;width:74px;height:26px;background:url(../images/sp_btn.gif) no-repeat;cursor:pointer}

a span.del{width:55px;height:36px;background-position:-300px 0}
a:hover span.del,a:focus span.del{width:55px;height:36px;background-position:-380px 0}
a:active span.del{width:55px;height:36px;background-position:-460px 0}

 

...

HTML

...
<head>
...
    <link rel="stylesheet" type="text/css" href="/css/grid.css" />
...
    <script src="/js/lib/jquery.js"></script>
    <script src="/js/lib/jquery.json.js"></script>
    <script src="/js/lib/underscore.js"></script>
    <script src="/js/lib/backbone.js"></script>
    <script src="/js/lib/code-snippet.js"></script>
    <script src="/js/lib/grid.js"></script>
...
</head>
<body>
...
    <div id="grid"></div>
...

new ne.Grid()

var grid = new ne.Grid ({

    el : $('#grid'),   // 그리드를 생성할 HTML 요소
     headerHeight: 70,   // (default = 50) 헤더의 전체 높이 (pixel)

     rowHeight : 30,   // (default = 27) 한 Row의 높이 (pixel)

    displayRowCount: 20,   // (default = 10) 한번에 보여질 Row의 수

    ...
    columnModelList : [

       ...   // Column 정보를 정의한 배열

    ],

    toolbar: {

         hasResizeHandler: false,  //  (default = true) 높이 조절 핸들러 표시 여부
         hasControlPanel: false,   //  (default = true) 컨트롤 패널 표시 여부

        hasPagination: false,   //  (default = true) 페이지네이션 사용 여부

    }

});

grid. setRowList ([

   ... // 실제 데이터 (Row단위) 배열

]);

Row List

[
    {
        name: '전지현',
        phone: '010-1234-xxxx',
        age: 34,
        birthday: '10/30',
        company: 3,
        job: '1,3',
        popular: 1
    }, 
    {
        name: '유아인',
        phone: '010-3292-xxxx',
        age: 26,
        birthday: '07/25',
        company: 5,
        job: '1',
        popular: 2
    }, 
    {
        name: '스칼렛 요한슨',
        phone: '010-3292-xxx',
        age: 30,
        birthday: '06/22',
        company: 2,
        job: '1,2,3',
        popular: 1
    }, 
    {
        name: '전도연',
        phone: '010-9281-xxxx',
        age: 30,
        birthday: '07/22',
        company: 3,
        job: '1',
        popular: 2
    }
...
]

Column Model List

 [
    ...
    {
        columnName: 'name', // 컬럼명, 데이터의 key값과 동일해야 함.
        title: '이름', // 컬럼 헤더에 표시될 제목
        align: 'center', // 정렬 방식: left, right, center
        width: 100, // 컬럼 넓이
    },
    {
        columnName: 'birthday',
        title: '생일',
        align: 'center',
        width: 150,
        editOption: {
            type: 'text' 
            // normal, text, text-convertible, text-password, select, checkbox, radio
        }
    },
    {
	columnName: 'popular',
        title: '인기도',
        editOption: {
	    type: 'radio',
            list: [  // type이 select, checkbox, radio 인 경우에만 정의
		{text: '상', value: 1},
		{text: '중', value: 2},
		{text: '하', value: 3}
	    ]
	}
    },
    ...
]

Sample 1

var grid = new ne.Grid({
    el: $('#grid'),
    displayRowCount: 20,
    columnModelList: [
        {
            title: '이름',
            columnName: 'name',
            align: 'center',
        }, 
        {
	    title: '생일',
            columnName: 'birthday',
	    editOption: {
		type: 'text'
	    }
	},
        {
	    title: '나이',
            columnName: 'age',
            align: 'center',
	    editOption: {
	        type: 'text-convertible'
	    }
	}, 
        {
	    title: '전화번호',
	    columnName: 'phone',
	    editOption: {
	        type: 'text-password'
	    }
        }
    ],
    toolbar: {
	hasResizeHandler: false,
	hasControlPanel: false,
	hasPagination: false
    }
});
$.getJSON('/sample', function (result) {
    grid.setRowList(result);
});

Sample 1 - 실행화면

Sample 2

var grid = new ne.Grid({
    el: $('#grid'),
    displayRowCount: 20,
    headerHeight: 60,
    columnModelList: [
        {
            title: '이름',
            columnName: 'name',
            align: 'center',
	    width: 100,
        }, 
        {
	    title: '생일',
            columnName: 'birthday',
            align: 'center',
	    width: 100
	}, 
        {
	    title: '나이',
            columnName: 'age',
	    width: 100,
            isSortable: true,
            align: 'center',
	    editOption: {
		type: 'text-convertible'
	    }
	}, 
        {
            title: '전화번호',
            columnName: 'phone',
            width: 200,
	    editOption: {
		type: 'text-password'
	    },
	    
        }, 
        {
	    title: '직업',
	    columnName: 'job',
	    width: 200,
	    editOption: {
		type: 'checkbox',
		list: [
		    {text: '배우', value: 1},
		    {text: '가수', value: 2},
		    {text: '모델', value: 3}
	        ]
	    }
	}, 
        {
	    title: '인기도',
	    columnName: 'popular',
	    editOption: {
	        type: 'radio',
		list: [
		    {text: '상', value: 1},
		    {text: '중', value: 2},
		    {text: '하', value: 3}
		]
	    }
	}
    ],
    toolbar: {
	hasResizeHandler: false,
	hasControlPanel: false,
	hasPagination: false
    }
});
$.getJSON('/sample', function (result) {
	grid.setRowList(result);
});

Sample 2 - 실행화면

Advanced

Sample

var grid = new ne.Grid({
    el: $('#grid'),
    headerHeight: 40,
    displayRowCount: 20,
    columnModelList: [
	{
	    title: '번호',
	    columnName: '_number',
	    width: 50,
	    align: 'center'
	},
        {
            title: '이름',
            columnName: 'name',
	    width: 150,
            align: 'center'
        },
	{
	    title: '나이',
            columnName: 'age',
	    width: 100,
            align: 'center',
		editOption: {
		    type: 'text-convertible',
		    afterContent: ' 살'
		}
	    },
        {
	    title: '검색',
            columnName: 'search',
	    width: 120,
            align: 'center',
	    formatter: function(value, row) {
		var searchUrl = 'http://search.naver.com/search.naver?ie=utf8&sm=stp_hty&where=se&query=' + row.name;
		return '<a target="_blank" href="' + searchUrl + '">검색</a>';
	    }
	},
	{
            title: '성별',
            columnName: 'sex',
            width: 100,
            align: 'center',
	    editOption: {
	        type: 'select',
		list: [
	            {text: '남', value:'M'},
	            {text: '여', value:'F'},
		]
	    },
	    relationList: [
	        {
		    columnList: ['company'],
		    optionListChange: function(value) {
		        if (value === 'F') {
			    return [
				{text: '천상계', value: 1},
				{text: '내 영혼', value: 2},
				{text: '내 마음', value: 3},
				{text: '내 바탕화면', value: 4}
			    ];
			} else {
		            return [
				{text: '관심없음', value: 5}
			    ];
			}
		    }
                },
		{
		    columnList: ['popular'],
		    isDisabled: function(value) {
		        return value === 'M';
		    }
		}
	    ]
	},
	{
	    title: '소속',
            columnName: 'company',
	    width: 200,
	    editOption: {
	        type: 'select',
	        list: [
		    {text: '천상계', value: 1},
		    {text: '내 영혼', value: 2},
	            {text: '내 마음', value: 3},
	            {text: '내 바탕화면', value: 4},
	            {text: '관심없음', value: 5}
		]
            }
	},
	{
	    title: '인기도',
	    columnName: 'popular',
	    editOption: {
	        type: 'radio',
		list: [
		    {text: '상', value: 1},
	            {text: '중', value: 2},
	            {text: '하', value: 3}
	        ]
            }
        }
    ],
    toolbar: {
	hasResizeHandler: false,
	hasControlPanel: false,
        hasPagination: false
    }
});
$.getJSON('/sample', function (result) {
	grid.setRowList(result);
});

Sample - 실행화면

Ver 1.0.3

1.0.02015.05

  • 첫 공식 배포

1.0.3 - 2015.08

  • Cell Double Click 이벤트 핸들러
  • Resizing 로직 변경
  • setSize(), setDisplayRowCount()
  • input 이벤트 핸들러 옵션 추가
  • ...

1.0.2 - 2015.07

  • Smart Rendering 성능 개선
  • Converter (커스텀 타입) 추가
  • fixed width 옵션 추가
  • Select Row 이벤트 핸들러
  • refreshLayout() 
  • appendRow()/removeRow() 옵션 추가
  • ...

1.0.1 - 2015.06

  • Cell 관련 마우스 이벤트 핸들러
  • Sort 버튼 추가, 서버연동 Sorting
  • check된 행 동시 삭제
  • ...

사용 문의 / 버그 신고

  • Github Repository
    • https://github.com/nhnent/fe.application-grid
    • API 문서 / Wiki 문서 참고
    • Issue 등록 대환영
    • Pull Request 대감사
  • Email 
    • ​dl_grid@nhnent.com

감사합니다.

그리드 기능과 적용방법

By DongWoo Kim

그리드 기능과 적용방법

  • 570