├── .travis.yml ├── API.md ├── LICENSE ├── README.md ├── bower.json ├── deploy.sh ├── design └── structure.key ├── dist ├── ax5grid.css ├── ax5grid.js ├── ax5grid.min.js └── ax5grid.min.js.map ├── karma.conf.js ├── package.json ├── src ├── ax5grid.gif ├── ax5grid.js ├── ax5grid.scss ├── modules │ ├── ax5grid-body.js │ ├── ax5grid-collector.js │ ├── ax5grid-data.js │ ├── ax5grid-excel.js │ ├── ax5grid-formatter.js │ ├── ax5grid-header.js │ ├── ax5grid-inline-editor.js │ ├── ax5grid-page.js │ ├── ax5grid-scroller.js │ ├── ax5grid-tmpl.js │ └── ax5grid-util.js └── scss │ ├── _ax5grid.scss │ └── _ax5grid_variables.scss └── test ├── bower.json ├── column-class.html ├── columns-test.html ├── context-menu.html ├── display.html ├── flex.html ├── focus-test.html ├── index.html ├── index2.html ├── inline-edit.html ├── merge-cells.html ├── onload-test.html ├── paging.html ├── php ├── composer.json ├── composer.lock ├── db │ ├── db.config.php │ └── sample.db ├── index.php ├── json_data.php ├── lib │ └── Grid.php └── views │ └── grid.php ├── sort.html ├── test-data.html ├── test.grid.html ├── test.grid.js └── tree.html /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4" 4 | before_script: 5 | - export CHROME_BIN=chromium-browser 6 | - export DISPLAY=:99.0 7 | - sh -e /etc/init.d/xvfb start -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2016 Thomas Jang, Brant and Team AXISJ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/ax5ui/ax5ui-grid.svg?branch=master)](https://travis-ci.org/ax5ui/ax5ui-grid) 2 | [![npm version](https://badge.fury.io/js/ax5ui-grid.svg)](https://badge.fury.io/js/ax5ui-grid) 3 | [![](https://img.shields.io/npm/dm/ax5ui-grid.svg)](https://www.npmjs.com/package/ax5ui-grid) 4 | 5 | 6 | # ax5ui-grid 7 | "grid" displays data in a table format with various options provided for configuration. 8 | 9 | ![ax5grid](src/ax5grid.gif) 10 | 11 | > *Dependencies* 12 | > * _[jQuery 1.X+](http://jquery.com/)_ 13 | > * _[ax5core](http://ax5.io/ax5core)_ 14 | 15 | 16 | ### Install with bower 17 | ```sh 18 | bower install ax5ui-grid 19 | ``` 20 | [bower](http://bower.io/#install-bower) is web front-end package manager. 21 | When you install `bower`, it will be installed under the `bower_components` folder to resolve the plug-in dependencies. 22 | (You can change the folder location. [.bowerrc](http://bower.io/docs/config/#bowerrc-specification) ) 23 | 24 | It is recommended that you install by using `bower`. 25 | If you've never used bower, please refer to [http://bower.io/#install-bower](http://bower.io/#install-bower). 26 | 27 | ### Install with npm 28 | If you do not use bower, it also can be installed by using npm as an alternative. 29 | In case of npm, which is the package manager for the front end, you need to solve the problem of plug-in dependencies. 30 | 31 | ```sh 32 | npm install jquery 33 | npm install ax5core 34 | npm install ax5ui-grid 35 | ``` 36 | 37 | After downloading the install file of npm, you will need to copy it to the location where you want to use as a resource for the project. 38 | If the copy process is inconvenient, it also can be done easily by using `gulp` or `grunt`. 39 | 40 | ### Download code 41 | - [ax5core Github releases](https://github.com/ax5ui/ax5core/releases) 42 | - [ax5ui-grid Github releases](https://github.com/ax5ui/ax5ui-grid/releases) 43 | 44 | 45 | ### Insert "ax5grid" in HTML HEAD. 46 | 47 | Folder location can be any for your project. However, please be sure to assign the right path in the project. 48 | ```html 49 | 50 | 51 | 52 | 53 | ``` 54 | 55 | **CDN urls** 56 | This is a list of CDN urls for ax5ui-grid. ax5ui offers the CDN services through the rawgit. 57 | ``` 58 | https://cdn.rawgit.com/ax5ui/ax5ui-grid/master/dist/ax5grid.css 59 | https://cdn.rawgit.com/ax5ui/ax5ui-grid/master/dist/ax5grid.js 60 | https://cdn.rawgit.com/ax5ui/ax5ui-grid/master/dist/ax5grid.min.js 61 | ``` 62 | 63 | ### Basic Usage 64 | ```html 65 |
66 | ``` 67 | ```js 68 | var firstGrid = new ax5.ui.grid(); 69 | firstGrid.setConfig({ 70 | target: $('[data-ax5grid="first-grid"]'), 71 | frozenColumnIndex: 2, 72 | frozenRowIndex: 0, 73 | showLineNumber: true, 74 | showRowSelector: true, 75 | multipleSelect: true, 76 | lineNumberColumnWidth: 40, 77 | rowSelectorColumnWidth: 28, 78 | sortable: true, 79 | multiSort: false, 80 | header: { 81 | align: "center", 82 | columnHeight: 28 83 | }, 84 | body: { 85 | align: "center", 86 | columnHeight: 28, 87 | onClick: function () { 88 | // console.log(this); 89 | this.self.select(this.dindex); 90 | } 91 | }, 92 | columns: [ 93 | { 94 | key: "a", 95 | label: "필드A", 96 | width: 80, 97 | styleClass: function () { 98 | return "ABC"; 99 | }, 100 | enableFilter: true, 101 | align: "center" 102 | }, 103 | {key: "b", label: "필드B", align: "center"}, 104 | { 105 | key: undefined, label: "필드C", columns: [ 106 | {key: "price", label: "단가", formatter: "money", align: "right"}, 107 | {key: "amount", label: "수량", formatter: "money", align: "right"}, 108 | {key: "cost", label: "금액", align: "right", formatter: "money"} 109 | ] 110 | }, 111 | {key: "saleDt", label: "판매일자", align: "center"}, 112 | {key: "customer", label: "고객명"}, 113 | {key: "saleType", label: "판매타입"} 114 | ] 115 | }); 116 | ``` 117 | 118 | 119 | *** 120 | 121 | ### Preview 122 | - [See Demonstration](http://ax5.io/ax5ui-grid/demo/index.html) 123 | 124 | If you have any questions, please refer to the following [gitHub](https://github.com/ax5ui/ax5ui-kernel) 125 | 126 | ## Question 127 | - https://jsdev.kr/c/axisj/ax5ui 128 | - https://github.com/ax5ui/ax5ui-kernel/issues 129 | 130 | [![axisj-contributed](https://img.shields.io/badge/AXISJ.com-Contributed-green.svg)](https://github.com/axisj) 131 | ![](https://img.shields.io/badge/Seowoo-Mondo&Thomas-red.svg) 132 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ax5ui-grid", 3 | "version": "1.4.131", 4 | "description": "A grid plugin that works with Bootstrap & jQuery", 5 | "authors": [ 6 | "ThomasJ " 7 | ], 8 | "main": "dist/ax5grid.js", 9 | "keywords": [ 10 | "bootstrap", 11 | "jquery", 12 | "ax5ui", 13 | "plugin", 14 | "bootstrap jQuery plugins", 15 | "grid", 16 | "ax5ui-grid", 17 | "javascript ui" 18 | ], 19 | "dependencies": { 20 | "jquery": "", 21 | "ax5core": ">=1.4.115", 22 | "ax5ui-menu": "", 23 | "ax5ui-formatter": "", 24 | "ax5ui-calendar": "", 25 | "ax5ui-picker": "" 26 | }, 27 | "license": "MIT", 28 | "homepage": "ax5.io" 29 | } -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | VERSION=`jq '.version' package.json | sed -e 's/^"//' -e 's/"$//'` 2 | 3 | git tag -a $VERSION -m $VERSION || true 4 | 5 | git push origin HEAD:master --follow-tags --force || true 6 | 7 | npm publish || true 8 | -------------------------------------------------------------------------------- /design/structure.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ax5ui/ax5ui-grid/aebf37305228f511649f6533bcaa80b21ac3f4d1/design/structure.key -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017. tom@axisj.com 3 | * - github.com/thomasjang 4 | * - www.axisj.com 5 | */ 6 | 7 | // Karma configuration 8 | // Generated on Wed Sep 21 2016 00:37:04 GMT+0900 (KST) 9 | 10 | module.exports = function (config) { 11 | var configuration = { 12 | // base path that will be used to resolve all patterns (eg. files, exclude) 13 | basePath: '', 14 | 15 | // frameworks to use 16 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 17 | frameworks: ['mocha'], 18 | 19 | // list of files / patterns to load in the browser 20 | files: [ 21 | 'https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js', 22 | 'https://cdnjs.cloudflare.com/ajax/libs/should.js/11.1.2/should.min.js', 23 | 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js', 24 | 'https://cdn.rawgit.com/ax5ui/ax5core/master/dist/ax5core.min.js', 25 | 'dist/ax5grid.js', 26 | 'https://rawgit.com/aeei/aejs/master/dist/ae.min.js', 27 | 'test/test.*.js' 28 | ], 29 | // list of files to exclude 30 | exclude: [], 31 | // preprocess matching files before serving them to the browser 32 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 33 | preprocessors: {}, 34 | // test results reporter to use 35 | // possible values: 'dots', 'progress' 36 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 37 | reporters: ['progress'], 38 | // web server port 39 | port: 9876, 40 | // enable / disable colors in the output (reporters and logs) 41 | colors: true, 42 | // level of logging 43 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 44 | logLevel: config.LOG_INFO, 45 | // enable / disable watching file and executing tests whenever any file changes 46 | autoWatch: true, 47 | // start these browsers 48 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 49 | browsers: ['PhantomJS'], 50 | //browsers: ['Chrome', 'Firefox'], 51 | customLaunchers: { 52 | Chrome_travis_ci: { 53 | base: 'Chrome', 54 | flags: ['--no-sandbox'] 55 | } 56 | }, 57 | singleRun: true, 58 | concurrency: Infinity 59 | }; 60 | 61 | if (process.env.TRAVIS) { 62 | configuration.browsers = ['PhantomJS']; 63 | } 64 | 65 | config.set(configuration); 66 | } 67 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ax5ui-grid", 3 | "version": "1.4.131", 4 | "description": "A grid plugin that works with Bootstrap & jQuery", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/ax5ui/ax5ui-grid" 9 | }, 10 | "author": { 11 | "name": "Thomas Jang", 12 | "email": "tom@axisj.com", 13 | "url": "ax5.io" 14 | }, 15 | "keywords": [ 16 | "bootstrap", 17 | "jquery", 18 | "ax5ui", 19 | "plugin", 20 | "bootstrap jQuery plugins", 21 | "grid", 22 | "ax5ui-grid", 23 | "javascript ui" 24 | ], 25 | "scripts": { 26 | "test": "karma start karma.conf.js" 27 | }, 28 | "dependencies": { 29 | "jquery": "", 30 | "ax5core": ">=1.4.115", 31 | "ax5ui-menu": "", 32 | "ax5ui-formatter": "", 33 | "ax5ui-calendar": "", 34 | "ax5ui-picker": "" 35 | }, 36 | "devDependencies": { 37 | "karma": "^1.3.0", 38 | "karma-mocha": "^1.2.0", 39 | "karma-phantomjs-launcher": "^1.0.2", 40 | "mocha": "^3.1.0", 41 | "phantomjs-prebuilt": "^2.1.13", 42 | "webdriverio": "^4.6.1" 43 | } 44 | } -------------------------------------------------------------------------------- /src/ax5grid.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ax5ui/ax5ui-grid/aebf37305228f511649f6533bcaa80b21ac3f4d1/src/ax5grid.gif -------------------------------------------------------------------------------- /src/ax5grid.scss: -------------------------------------------------------------------------------- 1 | @import "node_modules/ax5core/src/_ax5.scss"; 2 | 3 | @import "scss/ax5grid_variables"; 4 | @import "scss/ax5grid"; 5 | -------------------------------------------------------------------------------- /src/modules/ax5grid-collector.js: -------------------------------------------------------------------------------- 1 | // ax5.ui.grid.collector 2 | (function () { 3 | 4 | const GRID = ax5.ui.grid; 5 | 6 | const U = ax5.util; 7 | 8 | let sum = function () { 9 | let value = 0, 10 | i = this.list.length; 11 | while (i--) { 12 | if (!("__groupingList" in this.list[i])) { 13 | value += U.number(this.list[i][this.key]); 14 | } 15 | } 16 | return value; 17 | }; 18 | 19 | let avg = function () { 20 | let value = 0, 21 | i = this.list.length, listLength = 0; 22 | while (i--) { 23 | if (!("__groupingList" in this.list[i])) { 24 | value += U.number(this.list[i][this.key]); 25 | listLength++; 26 | } 27 | } 28 | return U.number(value / (listLength || 1), {"round": 2}); 29 | }; 30 | 31 | GRID.collector = { 32 | sum: sum, 33 | avg: avg 34 | }; 35 | 36 | })(); -------------------------------------------------------------------------------- /src/modules/ax5grid-excel.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. tom@axisj.com 3 | * - github.com/thomasjang 4 | * - www.axisj.com 5 | */ 6 | 7 | // ax5.ui.grid.excel 8 | (function () { 9 | 10 | const GRID = ax5.ui.grid; 11 | 12 | const U = ax5.util; 13 | 14 | const base64 = function (s) { 15 | return window.btoa(unescape(encodeURIComponent(s))); 16 | }; 17 | 18 | const uri = "data:application/vnd.ms-excel;base64,"; 19 | 20 | const getExcelTmpl = function () { 21 | return `\ufeff 22 | {{#tables}}{{{body}}}{{/tables}} 23 | `; 24 | }; 25 | 26 | const tableToExcel = function (table, fileName) { 27 | let link, a, output, 28 | tables = [].concat(table); 29 | 30 | output = ax5.mustache.render(getExcelTmpl(), { 31 | worksheet: (function () { 32 | var arr = []; 33 | tables.forEach(function (t, ti) { 34 | arr.push({name: "Sheet" + (ti + 1)}); 35 | }); 36 | return arr; 37 | })(), 38 | tables: (function () { 39 | var arr = []; 40 | tables.forEach(function (t, ti) { 41 | arr.push({body: t}); 42 | }); 43 | return arr; 44 | })() 45 | }); 46 | 47 | let isChrome = navigator.userAgent.indexOf("Chrome") > -1, 48 | isSafari = !isChrome && navigator.userAgent.indexOf("Safari") > -1, 49 | isIE = /*@cc_on!@*/false || !!document.documentMode; // this works with IE10 and IE11 both :) 50 | 51 | let blob1, blankWindow, $iframe, iframe, anchor; 52 | 53 | if (navigator.msSaveOrOpenBlob) { 54 | blob1 = new Blob([output], {type: "text/html"}); 55 | window.navigator.msSaveOrOpenBlob(blob1, fileName); 56 | } 57 | else if (isSafari) { 58 | // 사파리는 지원이 안되므로 그냥 테이블을 클립보드에 복사처리 59 | //tables 60 | blankWindow = window.open('about:blank', this.id + '-excel-export', 'width=600,height=400'); 61 | blankWindow.document.write(output); 62 | blankWindow = null; 63 | } 64 | else { 65 | if (isIE && typeof Blob === "undefined") { 66 | //otherwise use the iframe and save 67 | //requires a blank iframe on page called txtArea1 68 | $iframe = jQuery(''); 69 | jQuery(document.body).append($iframe); 70 | 71 | iframe = window[this.id + '-excel-export']; 72 | iframe.document.open("text/html", "replace"); 73 | iframe.document.write(output); 74 | iframe.document.close(); 75 | iframe.focus(); 76 | iframe.document.execCommand("SaveAs", true, fileName); 77 | $iframe.remove(); 78 | } else { 79 | // Attempt to use an alternative method 80 | anchor = document.body.appendChild( 81 | document.createElement("a") 82 | ); 83 | 84 | // If the [download] attribute is supported, try to use it 85 | if ("download" in anchor) { 86 | anchor.download = fileName; 87 | anchor.href = URL.createObjectURL(new Blob([output], { type: 'text/csv' })); 88 | anchor.click(); 89 | document.body.removeChild(anchor); 90 | } 91 | } 92 | } 93 | 94 | return true; 95 | }; 96 | 97 | GRID.excel = { 98 | export: tableToExcel 99 | }; 100 | })(); -------------------------------------------------------------------------------- /src/modules/ax5grid-formatter.js: -------------------------------------------------------------------------------- 1 | // ax5.ui.grid.formatter 2 | (function () { 3 | 4 | const GRID = ax5.ui.grid; 5 | 6 | const U = ax5.util; 7 | 8 | const money = function () { 9 | if (typeof this.value !== "undefined") { 10 | let val = ('' + this.value).replace(/[^0-9^\.^\-]/g, ""), 11 | regExpPattern = new RegExp('([0-9])([0-9][0-9][0-9][,.])'), 12 | arrNumber = val.split('.'), 13 | returnValue; 14 | 15 | arrNumber[0] += '.'; 16 | 17 | do { 18 | arrNumber[0] = arrNumber[0].replace(regExpPattern, '$1,$2'); 19 | } while (regExpPattern.test(arrNumber[0])); 20 | 21 | return (arrNumber.length > 1) ? arrNumber[0] + U.left(arrNumber[1], 2) : arrNumber[0].split('.')[0]; 22 | } else { 23 | return ""; 24 | } 25 | }; 26 | 27 | GRID.formatter = { 28 | money: money 29 | }; 30 | 31 | })(); -------------------------------------------------------------------------------- /src/modules/ax5grid-inline-editor.js: -------------------------------------------------------------------------------- 1 | // ax5.ui.grid.inlineEditor 2 | (function () { 3 | 4 | const GRID = ax5.ui.grid; 5 | 6 | const edit_text = { 7 | useReturnToSave: true, 8 | editMode: "popup", 9 | getHtml: function (_root, _columnKey, _editor, _value) { 10 | if(typeof _editor.attributes !== "undefined"){ 11 | var attributesText = ""; 12 | for (var k in _editor.attributes){ 13 | attributesText += ` ${k}='${_editor.attributes[k]}'`; 14 | } 15 | } 16 | return ``; 17 | }, 18 | init: function (_root, _columnKey, _editor, _$parent, _value) { 19 | var $el; 20 | _$parent.append($el = jQuery(this.getHtml(_root, _columnKey, _editor, _value))); 21 | this.bindUI(_root, _columnKey, $el, _editor, _$parent, _value); 22 | $el.on("blur", function () { 23 | GRID.body.inlineEdit.deActive.call(_root, "RETURN", _columnKey); 24 | }); 25 | return $el; 26 | }, 27 | bindUI: function (_root, _columnKey, _$el, _editor, _$parent, _value) { 28 | _$el.focus().select(); 29 | } 30 | }; 31 | 32 | const edit_money = { 33 | useReturnToSave: true, 34 | editMode: "popup", 35 | getHtml: function (_root, _columnKey, _editor, _value) { 36 | let attributesText = ""; 37 | if(typeof _editor.attributes !== "undefined"){ 38 | for (let k in _editor.attributes){ 39 | attributesText += ` ${k}='${_editor.attributes[k]}'`; 40 | } 41 | } 42 | return ''; 43 | }, 44 | init: function (_root, _columnKey, _editor, _$parent, _value) { 45 | let $el; 46 | _$parent.append($el = jQuery(this.getHtml(_root, _columnKey, _editor, _value))); 47 | this.bindUI(_root, _columnKey, $el, _editor, _$parent, _value); 48 | $el.on("blur", function () { 49 | GRID.body.inlineEdit.deActive.call(_root, "RETURN", _columnKey); 50 | }); 51 | return $el; 52 | }, 53 | bindUI: function (_root, _columnKey, _$el, _editor, _$parent, _value) { 54 | _$el.data("binded-ax5ui", "ax5formater"); 55 | _$el.ax5formatter($.extend(true, { 56 | pattern: "money" 57 | }, _editor.config)); 58 | _$el.focus().select(); 59 | } 60 | }; 61 | 62 | const edit_number = { 63 | useReturnToSave: true, 64 | editMode: "popup", 65 | getHtml: function (_root, _columnKey, _editor, _value) { 66 | let attributesText = ""; 67 | if(typeof _editor.attributes !== "undefined"){ 68 | for (let k in _editor.attributes){ 69 | attributesText += ` ${k}='${_editor.attributes[k]}'`; 70 | } 71 | } 72 | return ''; 73 | }, 74 | init: function (_root, _columnKey, _editor, _$parent, _value) { 75 | var $el; 76 | _$parent.append($el = jQuery(this.getHtml(_root, _columnKey, _editor, _value))); 77 | this.bindUI(_root, _columnKey, $el, _editor, _$parent, _value); 78 | $el.on("blur", function () { 79 | GRID.body.inlineEdit.deActive.call(_root, "RETURN", _columnKey); 80 | }); 81 | return $el; 82 | }, 83 | bindUI: function (_root, _columnKey, _$el, _editor, _$parent, _value) { 84 | _$el.data("binded-ax5ui", "ax5formater"); 85 | _$el.ax5formatter($.extend(true, { 86 | pattern: "number" 87 | }, _editor.config)); 88 | _$el.focus().select(); 89 | } 90 | }; 91 | 92 | const edit_date = { 93 | useReturnToSave: true, 94 | editMode: "popup", 95 | getHtml: function (_root, _columnKey, _editor, _value) { 96 | return ''; 97 | }, 98 | init: function (_root, _columnKey, _editor, _$parent, _value) { 99 | var $el; 100 | _$parent.append($el = jQuery(this.getHtml(_root, _columnKey, _editor, _value))); 101 | this.bindUI(_root, _columnKey, $el, _editor, _$parent, _value); 102 | return $el; 103 | }, 104 | bindUI: function (_root, _columnKey, _$el, _editor, _$parent, _value) { 105 | var self = _root; 106 | _$el.data("binded-ax5ui", "ax5picker"); 107 | 108 | _$el.ax5picker($.extend(true, { 109 | direction: "auto", 110 | content: { 111 | type: 'date', 112 | formatter: { 113 | pattern: 'date' 114 | } 115 | }, 116 | onStateChanged: function () { 117 | if (this.state == "open") { 118 | this.self.activePicker.attr("data-ax5grid-inline-edit-picker", "date"); 119 | } else if (this.state == "close") { 120 | GRID.body.inlineEdit.deActive.call(self, "RETURN", _columnKey); 121 | } 122 | } 123 | }, _editor.config)); 124 | 125 | _$el.focus().select(); 126 | } 127 | }; 128 | 129 | const edit_select = { 130 | useReturnToSave: false, 131 | editMode: "popup", 132 | getHtml: function (_root, _columnKey, _editor, _value) { 133 | var po = []; 134 | po.push('
'); 135 | po.push('
'); 136 | 137 | return po.join(''); 138 | }, 139 | init: function (_root, _columnKey, _editor, _$parent, _value) { 140 | var $el; 141 | _$parent.append($el = jQuery(this.getHtml(_root, _columnKey, _editor, _value))); 142 | this.bindUI(_root, _columnKey, $el, _editor, _$parent, _value); 143 | return $el; 144 | }, 145 | bindUI: function (_root, _columnKey, _$el, _editor, _$parent, _value) { 146 | var eConfig = { 147 | columnKeys: { 148 | optionValue: "value", 149 | optionText: "text", 150 | optionSelected: "selected" 151 | } 152 | }; 153 | jQuery.extend(true, eConfig, _editor.config); 154 | 155 | eConfig.options.forEach(function (n) { 156 | if (n[eConfig.columnKeys.optionValue] == _value) n[eConfig.columnKeys.optionSelected] = true; 157 | }); 158 | 159 | var self = _root; 160 | _$el.data("binded-ax5ui", "ax5select"); 161 | _$el.ax5select($.extend(true, { 162 | tabIndex: 1, 163 | direction: "auto", 164 | columnKeys: eConfig.columnKeys, 165 | options: eConfig.options, 166 | onStateChanged: function () { 167 | if (this.state == "open") { 168 | this.self.activeSelectOptionGroup.attr("data-ax5grid-inline-edit-picker", "select"); 169 | } else if (this.state == "changeValue") { 170 | GRID.body.inlineEdit.deActive.call(self, "RETURN", _columnKey, this.value[0][eConfig.columnKeys.optionValue]); 171 | } else if (this.state == "close") { 172 | GRID.body.inlineEdit.deActive.call(self, "ESC", _columnKey); 173 | } 174 | } 175 | }, _editor.config)); 176 | _$el.ax5select("open"); 177 | _$el.ax5select("setValue", _value); 178 | _$el.find("a").focus(); 179 | } 180 | }; 181 | 182 | const edit_checkbox = { 183 | editMode: "inline", 184 | getHtml: function (_root, _editor, _value) { 185 | 186 | var lineHeight = (_root.config.body.columnHeight - _root.config.body.columnPadding * 2 - _root.config.body.columnBorderWidth); 187 | var checked; 188 | if (_editor.config && _editor.config.trueValue) { 189 | checked = (_value == _editor.config.trueValue) ? "true" : "false"; 190 | } else { 191 | checked = (_value == false || _value == "false" || _value < "1") ? "false" : "true"; 192 | } 193 | 194 | var eConfig = { 195 | marginTop: 2, 196 | height: lineHeight - 4 197 | }; 198 | jQuery.extend(true, eConfig, _editor.config); 199 | eConfig.marginTop = (lineHeight - eConfig.height) / 2; 200 | 201 | return '
'; 202 | } 203 | }; 204 | 205 | const edit_textarea = { 206 | useReturnToSave: false, 207 | editMode: "popup", 208 | _getHtml: function (_root, _columnKey, _editor, _value) { 209 | // init 에서 사용하게 될 HTML 태그를 만들어 줍니다. 210 | return `
`; 211 | }, 212 | _bindUI: function (_root, _columnKey, _$el, _editor, _$parent, _value) { 213 | // 위치와 크기를 구합니다. 214 | let offset = _$el.offset(); 215 | let box = { 216 | width: _$el.width() 217 | }; 218 | let editorHeight = 150; 219 | let buttonHeight = 30; 220 | 221 | // 새로운 엘리먼트 생성 222 | let $newDiv = jQuery(`
223 | 224 |
225 | 226 |
227 |
`); 228 | let $newTextarea = $newDiv.find("textarea"); 229 | // 엘리먼트에 CSS 적용 230 | $newDiv.css({ 231 | position: "absolute", 232 | left: offset.left, 233 | top: offset.top, 234 | width: box.width, 235 | height: editorHeight 236 | }); 237 | $newDiv.find("textarea"); 238 | 239 | // 새로운 엘리먼트를 document.body에 append 240 | jQuery(document.body).append($newDiv); 241 | $newTextarea.focus().select(); 242 | 243 | $newTextarea.on("blur", function (e) { 244 | GRID.body.inlineEdit.deActive.call(_root, "RETURN", _columnKey, this.value); 245 | $newDiv.remove(); 246 | ax5.util.stopEvent(e.originalEvent); 247 | }); 248 | $newTextarea.on("keydown", function (e) { 249 | if(e.which == ax5.info.eventKeys.ESC){ 250 | GRID.body.inlineEdit.deActive.call(_root, "ESC", _columnKey); 251 | $newDiv.remove(); 252 | ax5.util.stopEvent(e.originalEvent); 253 | } 254 | }); 255 | 256 | /// 값 변경 257 | /// GRID.body.inlineEdit.deActive.call(_root, "RETURN", _columnKey, this.value[0][eConfig.columnKeys.optionValue]); 258 | /// 에디팅 취소 259 | /// GRID.body.inlineEdit.deActive.call(_root, "ESC", _columnKey); 260 | }, 261 | 262 | init: function (_root, _columnKey, _editor, _$parent, _value) { 263 | // 인라인 에디팅 활성화 시작 264 | /** 265 | * _root : gridInstance 266 | * _columnKey : di + "_" + col.colIndex + "_" + col.rowIndex 267 | * _editor : col.editor 268 | * _$parent : 셀 269 | * _value : 값 270 | */ 271 | let $el; 272 | _$parent.append($el = jQuery(this._getHtml(_root, _columnKey, _editor, _value))); 273 | // 셀에 HTML 컨텐츠 추가 274 | 275 | this._bindUI(_root, _columnKey, $el, _editor, _$parent, _value); 276 | // 이벤트 바인딩 277 | 278 | return $el; 279 | }, 280 | }; 281 | 282 | GRID.inlineEditor = { 283 | "text": edit_text, 284 | "money": edit_money, 285 | "number": edit_number, 286 | "date": edit_date, 287 | "select": edit_select, 288 | "checkbox": edit_checkbox, 289 | "textarea": edit_textarea 290 | }; 291 | 292 | })(); -------------------------------------------------------------------------------- /src/modules/ax5grid-page.js: -------------------------------------------------------------------------------- 1 | // ax5.ui.grid.page 2 | (function () { 3 | 4 | const GRID = ax5.ui.grid; 5 | 6 | const U = ax5.util; 7 | 8 | const onclickPageMove = function (_act) { 9 | var callback = function (_pageNo) { 10 | if (this.page.currentPage != _pageNo) { 11 | this.page.selectPage = _pageNo; 12 | if (this.config.page.onChange) { 13 | this.config.page.onChange.call({ 14 | self: this, 15 | page: this.page, 16 | data: this.data 17 | }); 18 | } 19 | } 20 | }; 21 | var processor = { 22 | "first": function () { 23 | callback.call(this, 0); 24 | }, 25 | "prev": function () { 26 | var pageNo = this.page.currentPage - 1; 27 | if (pageNo < 0) pageNo = 0; 28 | callback.call(this, pageNo); 29 | }, 30 | "next": function () { 31 | var pageNo = this.page.currentPage + 1; 32 | if (pageNo > this.page.totalPages - 1) pageNo = this.page.totalPages - 1; 33 | callback.call(this, pageNo); 34 | }, 35 | "last": function () { 36 | callback.call(this, this.page.totalPages - 1); 37 | } 38 | }; 39 | 40 | if (_act in processor) { 41 | processor[_act].call(this); 42 | } 43 | else { 44 | callback.call(this, _act - 1); 45 | } 46 | }; 47 | 48 | const navigationUpdate = function () { 49 | let self = this; 50 | if (this.page) { 51 | let page = { 52 | hasPage: false, 53 | currentPage: this.page.currentPage, 54 | pageSize: this.page.pageSize, 55 | totalElements: this.page.totalElements, 56 | totalPages: this.page.totalPages, 57 | firstIcon: this.config.page.firstIcon, 58 | prevIcon: this.config.page.prevIcon || "«", 59 | nextIcon: this.config.page.nextIcon || "»", 60 | lastIcon: this.config.page.lastIcon, 61 | }; 62 | let navigationItemCount = this.config.page.navigationItemCount; 63 | 64 | page["@paging"] = (function () { 65 | let returns = [], startI, endI; 66 | 67 | startI = page.currentPage - Math.floor(navigationItemCount / 2); 68 | if (startI < 0) startI = 0; 69 | endI = page.currentPage + navigationItemCount; 70 | if (endI > page.totalPages) endI = page.totalPages; 71 | 72 | if (endI - startI > navigationItemCount) { 73 | endI = startI + navigationItemCount; 74 | } 75 | 76 | if (endI - startI < navigationItemCount) { 77 | startI = endI - navigationItemCount; 78 | } 79 | if (startI < 0) startI = 0; 80 | 81 | for (let p = startI, l = endI; p < l; p++) { 82 | returns.push({'pageNo': (p + 1), 'selected': page.currentPage == p}); 83 | } 84 | return returns; 85 | })(); 86 | 87 | if (page["@paging"].length > 0) { 88 | page.hasPage = true; 89 | } 90 | 91 | this.$["page"]["navigation"].html(GRID.tmpl.get("page_navigation", page)); 92 | this.$["page"]["navigation"].find("[data-ax5grid-page-move]").on("click", function () { 93 | onclickPageMove.call(self, this.getAttribute("data-ax5grid-page-move")); 94 | }); 95 | 96 | } else { 97 | this.$["page"]["navigation"].empty(); 98 | } 99 | }; 100 | 101 | const statusUpdate = function () { 102 | if (!this.config.page.statusDisplay) { 103 | return; 104 | } 105 | 106 | let toRowIndex, rangeCount = Math.min(this.xvar.dataRowCount, this.xvar.virtualPaintRowCount); 107 | let data = {}; 108 | 109 | toRowIndex = this.xvar.virtualPaintStartRowIndex + rangeCount; 110 | 111 | if (toRowIndex > this.xvar.dataRowCount) { 112 | toRowIndex = this.xvar.dataRowCount; 113 | } 114 | 115 | data.fromRowIndex = U.number(this.xvar.virtualPaintStartRowIndex + 1, {"money": true}); 116 | data.toRowIndex = U.number(toRowIndex, {"money": true}); 117 | data.totalElements = false; 118 | data.dataRealRowCount = (this.xvar.dataRowCount !== this.xvar.dataRealRowCount) ? U.number(this.xvar.dataRealRowCount, {"money": true}) : false; 119 | data.dataRowCount = U.number(this.xvar.dataRowCount, {"money": true}); 120 | data.progress = (this.appendProgress) ? this.config.appendProgressIcon : ""; 121 | 122 | if (this.page) { 123 | data.fromRowIndex_page = U.number(this.xvar.virtualPaintStartRowIndex + (this.page.currentPage * this.page.pageSize) + 1, {"money": true}); 124 | data.toRowIndex_page = U.number(this.xvar.virtualPaintStartRowIndex + rangeCount + (this.page.currentPage * this.page.pageSize), {"money": true}); 125 | data.totalElements = U.number(this.page.totalElements, {"money": true}); 126 | 127 | if (data.toRowIndex_page > this.page.totalElements) { 128 | data.toRowIndex_page = this.page.totalElements; 129 | } 130 | } 131 | 132 | this.$["page"]["status"].html( 133 | GRID.tmpl.get("page_status", data) 134 | ); 135 | }; 136 | 137 | GRID.page = { 138 | navigationUpdate: navigationUpdate, 139 | statusUpdate: statusUpdate 140 | }; 141 | 142 | })(); -------------------------------------------------------------------------------- /src/modules/ax5grid-tmpl.js: -------------------------------------------------------------------------------- 1 | // ax5.ui.grid.tmpl 2 | (function () { 3 | 4 | const GRID = ax5.ui.grid; 5 | 6 | const main = function () { 7 | return `
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 | const page_navigation = function(){ 66 | return `
67 | {{#hasPage}} 68 |
69 | {{#firstIcon}}{{/firstIcon}} 70 | 71 |
72 |
73 | {{#@paging}} 74 | 75 | {{/@paging}} 76 |
77 |
78 | 79 | {{#lastIcon}}{{/lastIcon}} 80 |
81 | {{/hasPage}} 82 |
`; 83 | }; 84 | 85 | const page_status = function(){ 86 | return `{{{progress}}} {{fromRowIndex}} - {{toRowIndex}} of {{dataRowCount}} {{#totalElements}}  Total {{.}}{{/totalElements}}`; 87 | }; 88 | 89 | GRID.tmpl = { 90 | "main": main, 91 | "page_navigation": page_navigation, 92 | "page_status": page_status, 93 | 94 | get: function (tmplName, data, columnKeys) { 95 | let template = GRID.tmpl[tmplName].call(this, columnKeys); 96 | ax5.mustache.parse(template); 97 | return ax5.mustache.render(template, data); 98 | } 99 | }; 100 | 101 | 102 | })(); -------------------------------------------------------------------------------- /src/scss/_ax5grid_variables.scss: -------------------------------------------------------------------------------- 1 | //== 2 | $ax5grid-border: 1px solid #ccc !default; 3 | $ax5grid-bg: #fff !default; 4 | $ax5grid-font-size: 12px !default; 5 | $ax5grid-column-border: 1px solid #ccc !default; 6 | 7 | //== header 8 | $ax5grid-header-column-color: #222 !default; 9 | $ax5grid-header-column-border: 1px solid #ccc !default; 10 | $ax5grid-header-column-box-shadow: inset 1px 1px 0px 0px #fff !default; 11 | $ax5grid-header-column-bg-colors: (#FFFFFF, #F0F0F0) !default; 12 | $ax5grid-header-column-hover-bg-colors: (#eee, #eee) !default; 13 | $ax5grid-header-column-resizer-color: #ff3300 !default; 14 | $ax5grid-header-column-resizer-size: 4px !default; 15 | $ax5grid-header-sorter-size: 9px !default; 16 | $ax5grid-header-sorter-color: #000 !default; 17 | 18 | //== aside 19 | $ax5grid-aside-border: 1px solid darken(#ccc, 0%) !default; 20 | $ax5grid-aside-bg: #f2f2f2 !default; 21 | $ax5grid-aside-column-shadow: inset 1px 1px 0px 0px #fff !default; 22 | 23 | $ax5grid-frozen-line-border: 1px solid darken(#ccc, 10%) !default; 24 | 25 | //== footsum 26 | $ax5grid-footsum-bg: #ffe7e2 !default; 27 | $ax5grid-footsum-line-border: 1px solid darken(#ccc, 10%) !default; 28 | 29 | //== page 30 | $ax5grid-page-border: 1px solid #ccc !default; 31 | $ax5grid-page-bg-colors: (#FFFFFF, #F0F0F0) !default; 32 | $ax5grid-page-navigation-padding: 5px !default; 33 | $ax5grid-page-navigation-font-size: 12px !default; 34 | $ax5grid-page-navigation-btn-min-width: 20px !default; 35 | $ax5grid-page-navigation-btn-border: 0px none !default; 36 | $ax5grid-page-navigation-btn-border-radius: 5px !default; 37 | $ax5grid-page-navigation-btn-bg: transparent !default; 38 | $ax5grid-page-navigation-btn-font-size: 11px !default; 39 | $ax5grid-page-navigation-btn-color: #222 !default; 40 | $ax5grid-page-navigation-btn-hover-bg: #888 !default; 41 | $ax5grid-page-navigation-btn-hover-color: #fff !default; 42 | 43 | $ax5grid-page-status-font-size: 12px !default; 44 | $ax5grid-page-status-padding: 10px !default; 45 | $ax5grid-page-status-color: #222 !default; 46 | 47 | //== scroll 48 | $ax5grid-scroll-track-border: 1px solid #ccc !default; 49 | $ax5grid-scroll-track-bg: #f3f3f3 !default; 50 | $ax5grid-scroll-corner-bg: #EAEDEF !default; 51 | 52 | $ax5grid-scroll-bar-border-radius: 10px !default; 53 | $ax5grid-scroll-bar-border: 0px solid #fff !default; 54 | $ax5grid-scroll-bar-bg: #ccc !default; 55 | $ax5grid-scroll-bar-hover-border: 0px solid #ccc !default; 56 | $ax5grid-scroll-bar-hover-bg: #bababa !default; 57 | 58 | //== body.row 59 | $ax5grid-row-bg-0: #f3f3f3 !default; 60 | $ax5grid-row-bg-1: #fff !default; 61 | $ax5grid-row-bg-2: #f3f3f3 !default; 62 | $ax5grid-row-bg-3: #fff !default; 63 | $ax5grid-row-hover-bg: lighten(#cce2f3, 5%) !default; 64 | $ax5grid-row-grouping-bg: #ffffe7 !default; 65 | $ax5grid-row-selected: lighten(#b1d7fe, 10%) !default; 66 | 67 | //== body.cell 68 | $ax5grid-cell-padding-row-selector: 5px !default; 69 | $ax5grid-cell-padding: 3px 5px !default; 70 | 71 | $ax5grid-cell-checkbox-border: 1px solid #ccc !default; 72 | $ax5grid-cell-checkbox-border-radius: 3px !default; 73 | $ax5grid-cell-checkbox-bg-colors: (#FFFFFF, #F0F0F0) !default; 74 | $ax5grid-cell-disable-checkbox-bg-colors: (darken(nth($ax5grid-cell-checkbox-bg-colors, 2), 10%), darken(nth($ax5grid-cell-checkbox-bg-colors, 1), 10%)) !default; 75 | $ax5grid-cell-checkbox-arrow-color: #3372ff !default; 76 | 77 | $ax5grid-cell-focused-box-shadow: inset 0px 0px 1px 1px #0581f2 !default; 78 | $ax5grid-cell-focused-bg: lighten(#b1d7fe, 10%) !default; 79 | $ax5grid-cell-focused-color: #000 !default; 80 | 81 | $ax5grid-cell-selected-border-color: #ccc !default; 82 | $ax5grid-cell-selected-bg: #b1d7fe !default; 83 | $ax5grid-cell-selected-color: #000 !default; 84 | 85 | //== resizer 86 | $ax5grid-resizer-color: #ff3300 !default; 87 | $ax5grid-resizer-size: 2px !default; 88 | -------------------------------------------------------------------------------- /test/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ax5ui-picker-tester", 3 | "dependencies": { 4 | "jquery": "^1.11.0", 5 | "bootstrap": "^3.3.6", 6 | "font-awesome": "" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/columns-test.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 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 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /test/context-menu.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 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 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /test/display.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 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 | 243 | 244 | 245 | -------------------------------------------------------------------------------- /test/flex.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
42 |
43 | 44 |
45 |
46 |
47 | 48 | 49 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /test/focus-test.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 |
37 | 38 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | GRID 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 |

height

34 | 35 | 36 | 37 | 38 |
39 |
40 |

row

41 | 42 | 43 | 44 | 45 | 46 |
47 |
48 |

column

49 | 50 | 51 | 52 |
53 |
54 |

etc.

55 | 56 | 57 |
58 |
59 | 60 |
61 |
62 | 63 | 64 | 65 | 66 |
67 |
68 | 69 | 70 |
71 | 72 | 73 |
74 | 75 |
76 | 77 | 343 | 344 | 345 | -------------------------------------------------------------------------------- /test/index2.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 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 | 59 |
60 | 61 | 62 | 263 | 264 | 265 | -------------------------------------------------------------------------------- /test/inline-edit.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 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 | 355 | 356 | 357 | -------------------------------------------------------------------------------- /test/merge-cells.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 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 | 332 | 333 | 334 | -------------------------------------------------------------------------------- /test/onload-test.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 |
37 | 38 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /test/paging.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 |
37 | 38 | 41 |
42 | 43 | 44 | 217 | 218 | 219 | -------------------------------------------------------------------------------- /test/php/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "fzaninotto/faker": "^1.6", 4 | "aviat4ion/query": "^2.5" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/php/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "a52392adef56416c32d684e3efb4ab3a", 8 | "content-hash": "182bc53417cc5ef4fe472c003b2ac6bf", 9 | "packages": [ 10 | { 11 | "name": "aviat4ion/query", 12 | "version": "v2.5.1", 13 | "source": { 14 | "type": "git", 15 | "url": "https://git.timshomepage.net/aviat4ion/Query.git", 16 | "reference": "555865bdb79fcaaf042ad43e45b3c9b0abbe02cc" 17 | }, 18 | "require": { 19 | "php": ">=5.3" 20 | }, 21 | "type": "library", 22 | "autoload": { 23 | "files": [ 24 | "autoload.php" 25 | ] 26 | }, 27 | "notification-url": "https://packagist.org/downloads/", 28 | "license": [ 29 | "dbad-license" 30 | ], 31 | "authors": [ 32 | { 33 | "name": "Timothy J. Warren", 34 | "email": "tim@timshomepage.net", 35 | "homepage": "https://timshomepage.net", 36 | "role": "Developer" 37 | } 38 | ], 39 | "description": "Database Query Builder and Abstraction layer", 40 | "homepage": "https://github.com/aviat4ion/Query", 41 | "keywords": [ 42 | "codeigniter", 43 | "database", 44 | "firebird", 45 | "mysql", 46 | "pdo", 47 | "postgres", 48 | "query builder", 49 | "sqlite" 50 | ], 51 | "abandoned": "aviat/ion", 52 | "time": "2015-07-31 14:56:16" 53 | }, 54 | { 55 | "name": "fzaninotto/faker", 56 | "version": "v1.6.0", 57 | "source": { 58 | "type": "git", 59 | "url": "https://github.com/fzaninotto/Faker.git", 60 | "reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123" 61 | }, 62 | "dist": { 63 | "type": "zip", 64 | "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/44f9a286a04b80c76a4e5fb7aad8bb539b920123", 65 | "reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123", 66 | "shasum": "" 67 | }, 68 | "require": { 69 | "php": "^5.3.3|^7.0" 70 | }, 71 | "require-dev": { 72 | "ext-intl": "*", 73 | "phpunit/phpunit": "~4.0", 74 | "squizlabs/php_codesniffer": "~1.5" 75 | }, 76 | "type": "library", 77 | "extra": { 78 | "branch-alias": [] 79 | }, 80 | "autoload": { 81 | "psr-4": { 82 | "Faker\\": "src/Faker/" 83 | } 84 | }, 85 | "notification-url": "https://packagist.org/downloads/", 86 | "license": [ 87 | "MIT" 88 | ], 89 | "authors": [ 90 | { 91 | "name": "François Zaninotto" 92 | } 93 | ], 94 | "description": "Faker is a PHP library that generates fake data for you.", 95 | "keywords": [ 96 | "data", 97 | "faker", 98 | "fixtures" 99 | ], 100 | "time": "2016-04-29 12:21:54" 101 | } 102 | ], 103 | "packages-dev": [], 104 | "aliases": [], 105 | "minimum-stability": "stable", 106 | "stability-flags": [], 107 | "prefer-stable": false, 108 | "prefer-lowest": false, 109 | "platform": [], 110 | "platform-dev": [] 111 | } 112 | -------------------------------------------------------------------------------- /test/php/db/db.config.php: -------------------------------------------------------------------------------- 1 | 'sqlite', 13 | 'host' => '', 14 | 'user' => '', 15 | 'pass' => '', 16 | 'port' => '', 17 | 'database' => '', 18 | 19 | // Only required 20 | // SQLite or Firebird 21 | 'file' => 'db/sample.db', 22 | 23 | // Optional paramaters 24 | 'prefix' => '', // Database table prefix 25 | 'alias' => 'default' // Connection name for the Query function 26 | )); -------------------------------------------------------------------------------- /test/php/db/sample.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ax5ui/ax5ui-grid/aebf37305228f511649f6533bcaa80b21ac3f4d1/test/php/db/sample.db -------------------------------------------------------------------------------- /test/php/index.php: -------------------------------------------------------------------------------- 1 | set($_POST) 24 | ->update($_POST['id']) 25 | ->get_json(); 26 | } 27 | break; 28 | 29 | case 'delete': 30 | if(isset($_POST['ids']) && !empty($_POST['ids'])) { 31 | $ret = $sales 32 | ->delete($_POST['ids']) 33 | ->get_json(); 34 | } 35 | break; 36 | 37 | default: 38 | $len = isset($_POST['len']) ? $_POST['len'] : 10; 39 | $page = isset($_POST['page']) ? $_POST['page'] : 1; 40 | $sortInfo = isset($_POST['sort']) ? $_POST['sort'] : ''; 41 | 42 | $ret = $sales 43 | ->set_limit($len) 44 | ->set_page($page) 45 | ->set_sort($sortInfo) 46 | ->read() 47 | ->get_json(); 48 | break; 49 | 50 | } 51 | 52 | echo $ret; 53 | 54 | class json_data { 55 | protected $db; 56 | protected $ret; 57 | protected $setData; 58 | protected $data; 59 | protected $page; 60 | protected $offset; 61 | protected $limit; 62 | protected $tbl; 63 | protected $sort; 64 | 65 | public function __construct($page = 1, $limit = 10) 66 | { 67 | $this->db = Query(array( 68 | 'type' => 'sqlite', 69 | 'host' => '', 70 | 'user' => '', 71 | 'pass' => '', 72 | 'port' => '', 73 | 'database' => '', 74 | 75 | // Only required 76 | // SQLite or Firebird 77 | 'file' => 'db/sample.db', 78 | 79 | // Optional paramaters 80 | 'prefix' => '', // Database table prefix 81 | 'alias' => 'default' // Connection name for the Query function 82 | )); 83 | 84 | $this->ret = array( 85 | 'status' => 'success', 86 | 'msg' => '', 87 | 'data' => '' 88 | ); 89 | 90 | $this->tbl = 'sales'; 91 | $this->data = false; 92 | $this->setData = array(); 93 | 94 | return $this; 95 | } 96 | 97 | public function read() 98 | { 99 | $this->page = intval($this->page) > 0 ? intval($this->page) : 1; 100 | 101 | $this->limit = intval($this->limit); 102 | $this->offset = ($this->page - 1) * $this->limit; 103 | 104 | $total_cnt = $this->db->count_all_results($this->tbl); 105 | 106 | if(is_array($this->sort) && !empty($this->sort)) { 107 | foreach($this->sort as $item) { 108 | $this->db->order_by($item['key'], $item['orderBy']); 109 | } 110 | } 111 | 112 | $this->data['list'] = $this->db 113 | ->limit($this->limit, $this->offset) 114 | ->get($this->tbl) 115 | ->fetchAll(PDO::FETCH_ASSOC); 116 | 117 | $this->data['page'] = array( 118 | 'currentPage' => $this->page - 1, 119 | 'pageSize' => $this->limit, 120 | 'totalPages' => ceil($total_cnt / $this->limit), 121 | 'totalElements' => $total_cnt 122 | ); 123 | 124 | return $this; 125 | } 126 | 127 | public function update($id) 128 | { 129 | $column = array('company', 'price', 'amount'); 130 | 131 | foreach($column as $key) { 132 | if(isset($this->setData[$key])) { 133 | $this->db->set($key, $this->setData[$key]); 134 | } 135 | } 136 | 137 | $cost = $this->setData['price'] * $this->setData['amount']; 138 | $this->db->set('cost', $cost); 139 | 140 | $this->db 141 | ->where('id', $id) 142 | ->update($this->tbl); 143 | 144 | $this->data['cost'] = $cost; 145 | 146 | return $this; 147 | } 148 | 149 | public function delete($ids) 150 | { 151 | $this->data = $ids; 152 | $this->db->where_in('id', $ids)->delete($this->tbl); 153 | return $this; 154 | } 155 | 156 | public function set($key, $data = null) 157 | { 158 | if(is_array($key)) { 159 | $this->setData = $key; 160 | } else { 161 | $this->setData[$key] = $data; 162 | } 163 | 164 | return $this; 165 | } 166 | public function get() 167 | { 168 | return $this->data; 169 | } 170 | 171 | public function get_one() 172 | { 173 | return isset($this->data[0]) ? $this->data[0] : false; 174 | } 175 | 176 | public function get_json($data = null) 177 | { 178 | $this->ret['data'] = $data ? $data : $this->data; 179 | return json_encode($this->ret); 180 | } 181 | 182 | public function set_limit($limit) 183 | { 184 | $this->limit = $limit; 185 | 186 | return $this; 187 | } 188 | 189 | public function set_page($page) 190 | { 191 | $this->page = $page; 192 | 193 | return $this; 194 | } 195 | 196 | public function set_sort($sort) 197 | { 198 | $this->sort = $sort; 199 | 200 | return $this; 201 | } 202 | } -------------------------------------------------------------------------------- /test/php/lib/Grid.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | GRID 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 69 | 70 |
71 | 74 | 75 |
76 |
77 |
78 | 79 |
80 | 81 |
82 |
83 | 84 | 89 | 90 | 255 | 256 | 257 | -------------------------------------------------------------------------------- /test/sort.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 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 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /test/test.grid.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | ax5ui TESTING 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /test/tree.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | GRID 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 |
67 |
68 |
69 | 70 | 71 | 309 | 310 | 311 | --------------------------------------------------------------------------------