blob: 745c3ca458ca15c0542b0a29cfe1a09d15860574 [file] [log] [blame]
Matteo Scandolo66351432016-03-24 15:29:52 -07001/**
2 * © OpenCORD
3 *
4 * Visit http://guide.xosproject.org/devguide/addview/ for more information
5 *
6 * Created by teone on 3/24/16.
7 */
8
9(function () {
10 'use strict';
11
Matteo Scandolo320ce2c2016-04-15 12:20:14 -070012 angular.module('xos.uiComponents')
Matteo Scandolo5614b902016-04-14 15:34:12 -070013
14 /**
15 * @ngdoc directive
Matteo Scandolofb5937d2016-04-15 14:27:54 -070016 * @name xos.uiComponents.directive:xosTable
Matteo Scandolo5614b902016-04-14 15:34:12 -070017 * @restrict E
18 * @description The xos-table directive
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070019 * @param {Object} config The configuration for the component.
20 * ```
21 * {
22 * columns: [
23 * {
24 * label: 'Human readable name',
25 * prop: 'Property to read in the model object'
26 * }
27 * ],
28 * classes: 'table table-striped table-bordered',
29 * actions: [ // if defined add an action column
30 {
31 label: 'delete',
32 icon: 'remove', // refers to bootstraps glyphicon
33 cb: (user) => { // receive the model
34 console.log(user);
35 },
36 color: 'red'
37 }
Matteo Scandolo92ca4552016-04-14 17:21:45 -070038 ],
39 filter: 'field', // can be by `field` or `fulltext`
40 order: true // whether to show ordering arrows
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070041 * }
42 * ```
43 * @param {Array} data The data that should be rendered
Matteo Scandolo5614b902016-04-14 15:34:12 -070044 * @element ANY
45 * @scope
46 * @example
47
Matteo Scandolofb5937d2016-04-15 14:27:54 -070048 <example module="sampleTable1">
Matteo Scandolo5614b902016-04-14 15:34:12 -070049 <file name="index.html">
50 <div ng-controller="SampleCtrl1 as vm">
51 <xos-table data="vm.data" config="vm.config"></xos-table>
Matteo Scandolo5614b902016-04-14 15:34:12 -070052 </div>
53 </file>
54 <file name="script.js">
Matteo Scandolofb5937d2016-04-15 14:27:54 -070055 angular.module('sampleTable1', ['xos.uiComponents'])
Matteo Scandolo5614b902016-04-14 15:34:12 -070056 .controller('SampleCtrl1', function(){
57 this.config = {
58 columns: [
59 {
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070060 label: 'First Name', // column title
61 prop: 'name' // property to read in the data array
Matteo Scandolo5614b902016-04-14 15:34:12 -070062 },
63 {
64 label: 'Last Name',
65 prop: 'lastname'
66 }
67 ]
68 };
69
70 this.data = [
71 {
72 name: 'John',
73 lastname: 'Doe'
74 },
75 {
76 name: 'Gili',
77 lastname: 'Fereydoun'
78 }
79 ]
80 });
81 </file>
82 </example>
83
Matteo Scandolo9bb3a952016-04-25 14:24:18 -070084 <example module="sampleTable2" animations="true">
Matteo Scandolo5614b902016-04-14 15:34:12 -070085 <file name="index.html">
86 <div ng-controller="SampleCtrl2 as vm">
87 <xos-table data="vm.data" config="vm.config"></xos-table>
Matteo Scandolo5614b902016-04-14 15:34:12 -070088 </div>
89 </file>
90 <file name="script.js">
Matteo Scandolo9bb3a952016-04-25 14:24:18 -070091 angular.module('sampleTable2', ['xos.uiComponents', 'ngAnimate'])
Matteo Scandolo5614b902016-04-14 15:34:12 -070092 .controller('SampleCtrl2', function(){
93 this.config = {
94 columns: [
95 {
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070096 label: 'First Name', // column title
97 prop: 'name' // property to read in the data array
Matteo Scandolo5614b902016-04-14 15:34:12 -070098 },
99 {
100 label: 'Last Name',
101 prop: 'lastname'
102 }
103 ],
Matteo Scandolo6a6586e2016-04-14 16:52:13 -0700104 classes: 'table table-striped table-condensed', // table classes, default to `table table-striped table-bordered`
105 actions: [ // if defined add an action column
Matteo Scandolo5614b902016-04-14 15:34:12 -0700106 {
Matteo Scandolo6a6586e2016-04-14 16:52:13 -0700107 label: 'delete', // label
108 icon: 'remove', // icons, refers to bootstraps glyphicon
109 cb: (user) => { // callback, get feeded with the full object
Matteo Scandolo5614b902016-04-14 15:34:12 -0700110 console.log(user);
111 },
Matteo Scandolo6a6586e2016-04-14 16:52:13 -0700112 color: 'red' // icon color
Matteo Scandolo5614b902016-04-14 15:34:12 -0700113 }
Matteo Scandolo92ca4552016-04-14 17:21:45 -0700114 ],
115 filter: 'field', // can be by `field` or `fulltext`
116 order: true
Matteo Scandolo5614b902016-04-14 15:34:12 -0700117 };
118
119 this.data = [
120 {
121 name: 'John',
122 lastname: 'Doe'
123 },
124 {
125 name: 'Gili',
126 lastname: 'Fereydoun'
127 }
128 ]
129 });
130 </file>
131 </example>
132
Matteo Scandolofb5937d2016-04-15 14:27:54 -0700133 <example module="sampleTable3">
134 <file name="index.html">
135 <div ng-controller="SampleCtrl3 as vm">
136 <xos-table data="vm.data" config="vm.config"></xos-table>
137 </div>
138 </file>
139 <file name="script.js">
140 angular.module('sampleTable3', ['xos.uiComponents'])
141 .controller('SampleCtrl3', function(){
142 this.config = {
143 columns: [
144 {
145 label: 'First Name', // column title
146 prop: 'name' // property to read in the data array
147 },
148 {
149 label: 'Last Name',
150 prop: 'lastname'
151 }
152 ],
153 pagination: {
154 pageSize: 2
155 }
156 };
157
158 this.data = [
159 {
160 name: 'John',
161 lastname: 'Doe'
162 },
163 {
164 name: 'Gili',
165 lastname: 'Fereydoun'
166 },
167 {
168 name: 'Lucky',
169 lastname: 'Clarkson'
170 },
171 {
172 name: 'Tate',
173 lastname: 'Spalding'
174 }
175 ]
176 });
177 </file>
178 </example>
Matteo Scandolo5614b902016-04-14 15:34:12 -0700179 **/
180
Matteo Scandolo66351432016-03-24 15:29:52 -0700181 .directive('xosTable', function(){
182 return {
183 restrict: 'E',
184 scope: {
185 data: '=',
Matteo Scandolodcc65242016-04-14 12:06:50 -0700186 config: '='
Matteo Scandolo66351432016-03-24 15:29:52 -0700187 },
Matteo Scandolo1dab3e02016-04-14 11:46:30 -0700188 template: `
Matteo Scandolofb5937d2016-04-15 14:27:54 -0700189 <div ng-show="vm.data.length > 0">
190 <div class="row" ng-if="vm.config.filter == 'fulltext'">
191 <div class="col-xs-12">
192 <input
193 class="form-control"
194 placeholder="Type to search.."
195 type="text"
196 ng-model="vm.query"/>
197 </div>
198 </div>
Matteo Scandoloc88bb9f2016-04-25 10:31:22 -0700199 <table ng-class="vm.classes" ng-hide="vm.data.length == 0">
Matteo Scandolofb5937d2016-04-15 14:27:54 -0700200 <thead>
201 <tr>
202 <th ng-repeat="col in vm.columns">
203 {{col.label}}
204 <span ng-if="vm.config.order">
205 <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = false">
206 <i class="glyphicon glyphicon-chevron-up"></i>
207 </a>
208 <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = true">
209 <i class="glyphicon glyphicon-chevron-down"></i>
210 </a>
211 </span>
212 </th>
Matteo Scandolo3fa98712016-04-26 11:44:36 -0700213 <th ng-if="vm.config.actions">Actions:</th>
Matteo Scandolofb5937d2016-04-15 14:27:54 -0700214 </tr>
215 </thead>
216 <tbody ng-if="vm.config.filter == 'field'">
217 <tr>
218 <td ng-repeat="col in vm.columns">
219 <input
220 class="form-control"
221 placeholder="Type to search by {{col.label}}"
222 type="text"
223 ng-model="vm.query[col.prop]"/>
224 </td>
225 <td ng-if="vm.config.actions"></td>
226 </tr>
227 </tbody>
228 <tbody>
229 <tr ng-repeat="item in vm.data | filter:vm.query | orderBy:vm.orderBy:vm.reverse | pagination:vm.currentPage * vm.config.pagination.pageSize | limitTo: (vm.config.pagination.pageSize || vm.data.length) track by $index">
230 <td ng-repeat="col in vm.columns">{{item[col.prop]}}</td>
231 <td ng-if="vm.config.actions">
232 <a href=""
233 ng-repeat="action in vm.config.actions"
234 ng-click="action.cb(item)"
235 title="{{action.label}}">
236 <i
237 class="glyphicon glyphicon-{{action.icon}}"
238 style="color: {{action.color}};"></i>
239 </a>
240 </td>
241 </tr>
242 </tbody>
243 </table>
244 <xos-pagination
245 ng-if="vm.config.pagination"
246 page-size="vm.config.pagination.pageSize"
247 total-elements="vm.data.length"
248 change="vm.goToPage">
249 </xos-pagination>
250 </div>
251 <div ng-show="vm.data.length == 0 || !vm.data">
Matteo Scandoloc49f53c2016-04-20 11:38:42 -0700252 <xos-alert config="{type: 'info'}">
Matteo Scandolofb5937d2016-04-15 14:27:54 -0700253 No data to show.
Matteo Scandoloc49f53c2016-04-20 11:38:42 -0700254 </xos-alert>
Matteo Scandolo6a6586e2016-04-14 16:52:13 -0700255 </div>
Matteo Scandolo1dab3e02016-04-14 11:46:30 -0700256 `,
Matteo Scandolo66351432016-03-24 15:29:52 -0700257 bindToController: true,
258 controllerAs: 'vm',
259 controller: function(){
Matteo Scandolodcc65242016-04-14 12:06:50 -0700260
261 if(!this.config){
262 throw new Error('[xosTable] Please provide a configuration via the "config" attribute');
263 }
264
265 if(!this.config.columns){
266 throw new Error('[xosTable] Please provide a columns list in the configuration');
267 }
268
269 this.columns = this.config.columns;
270 this.classes = this.config.classes || 'table table-striped table-bordered';
271
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -0700272 if(this.config.actions){
Matteo Scandolo320ce2c2016-04-15 12:20:14 -0700273 // TODO validate action format
274 }
275 if(this.config.pagination){
276 this.currentPage = 0;
277 this.goToPage = (n) => {
278 this.currentPage = n;
279 };
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -0700280 }
281
Matteo Scandolo66351432016-03-24 15:29:52 -0700282 }
283 }
284 })
285})();