Added filters to xosTable and tested
diff --git a/views/ngXosLib/.eslintrc b/views/ngXosLib/.eslintrc
index f9a952f..cf02168 100644
--- a/views/ngXosLib/.eslintrc
+++ b/views/ngXosLib/.eslintrc
@@ -24,7 +24,6 @@
"indent": [2, 2],
"no-irregular-whitespace": 1,
"eol-last": 0,
- "max-nested-callbacks": [2, 4],
"comma-spacing": [1, {"before": false, "after": true}],
"no-trailing-spaces": [1, { skipBlankLines: true }],
"no-unused-vars": [1, {"vars": "all", "args": "after-used"}],
diff --git a/views/ngXosLib/gulp/ngXosHelpers.js b/views/ngXosLib/gulp/ngXosHelpers.js
index c9915e2..f046681 100644
--- a/views/ngXosLib/gulp/ngXosHelpers.js
+++ b/views/ngXosLib/gulp/ngXosHelpers.js
@@ -63,7 +63,7 @@
styles: [
'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css',
],
- html5Mode: true,
+ html5Mode: false,
title: 'XOS Helpers documentation',
startPage: '/module',
}
@@ -109,7 +109,6 @@
gulp.watch(files, ['makeDocs']);
gulp.watch(files, function(){
- console.log('Reload');
browserSync.reload();
});
})
diff --git a/views/ngXosLib/karma.conf.js b/views/ngXosLib/karma.conf.js
index ae486dc..e3c1cbb 100644
--- a/views/ngXosLib/karma.conf.js
+++ b/views/ngXosLib/karma.conf.js
@@ -86,7 +86,7 @@
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
- browsers: ['PhantomJS', 'Chrome'],
+ browsers: ['PhantomJS'],
// Continuous Integration mode
diff --git a/views/ngXosLib/xos/core/xoslib/static/js/vendor/ngXosHelpers.js b/views/ngXosLib/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
index 6aecaf1..2fc5ba7 100644
--- a/views/ngXosLib/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
+++ b/views/ngXosLib/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
@@ -24,24 +24,46 @@
* @name xos.uiComponents.table.directive:xosTable
* @restrict E
* @description The xos-table directive
+ * @param {Object} config The configuration for the component.
+ * ```
+ * {
+ * columns: [
+ * {
+ * label: 'Human readable name',
+ * prop: 'Property to read in the model object'
+ * }
+ * ],
+ * classes: 'table table-striped table-bordered',
+ * actions: [ // if defined add an action column
+ {
+ label: 'delete',
+ icon: 'remove', // refers to bootstraps glyphicon
+ cb: (user) => { // receive the model
+ console.log(user);
+ },
+ color: 'red'
+ }
+ ]
+ * }
+ * ```
+ * @param {Array} data The data that should be rendered
* @element ANY
* @scope
* @example
- <example module="sampleModule">
+ <example module="sampleModule1">
<file name="index.html">
<div ng-controller="SampleCtrl1 as vm">
<xos-table data="vm.data" config="vm.config"></xos-table>
- </xos-table>
</div>
</file>
<file name="script.js">
- angular.module('sampleModule', ['xos.uiComponents.table'])
+ angular.module('sampleModule1', ['xos.uiComponents.table'])
.controller('SampleCtrl1', function(){
this.config = {
columns: [
{
- label: 'First Name',
- prop: 'name'
+ label: 'First Name', // column title
+ prop: 'name' // property to read in the data array
},
{
label: 'Last Name',
@@ -62,36 +84,35 @@
});
</file>
</example>
- <example module="sampleModule">
+ <example module="sampleModule2">
<file name="index.html">
<div ng-controller="SampleCtrl2 as vm">
<xos-table data="vm.data" config="vm.config"></xos-table>
- </xos-table>
</div>
</file>
<file name="script.js">
- angular.module('sampleModule', ['xos.uiComponents.table'])
+ angular.module('sampleModule2', ['xos.uiComponents.table'])
.controller('SampleCtrl2', function(){
this.config = {
columns: [
{
- label: 'First Name',
- prop: 'name'
+ label: 'First Name', // column title
+ prop: 'name' // property to read in the data array
},
{
label: 'Last Name',
prop: 'lastname'
}
],
- classes: 'table table-striped table-condensed',
- actions: [
+ classes: 'table table-striped table-condensed', // table classes, default to `table table-striped table-bordered`
+ actions: [ // if defined add an action column
{
- label: 'delete',
- icon: 'remove',
- cb: (user) => {
+ label: 'delete', // label
+ icon: 'remove', // icons, refers to bootstraps glyphicon
+ cb: (user) => { // callback, get feeded with the full object
console.log(user);
},
- color: 'red'
+ color: 'red' // icon color
}
]
};
@@ -117,7 +138,7 @@
data: '=',
config: '='
},
- template: '\n <!-- <pre>{{vm.data | json}}</pre> -->\n <table ng-class="vm.classes" ng-show="vm.data.length > 0">\n <thead>\n <tr>\n <th ng-repeat="col in vm.columns">{{col.label}}</th>\n <th ng-if="vm.config.actions">Actions</th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="item in vm.data">\n <td ng-repeat="col in vm.columns">{{item[col.prop]}}</td>\n <td ng-if="vm.config.actions">\n <i\n ng-repeat="action in vm.config.actions"\n ng-click="action.cb(item)"\n class="glyphicon glyphicon-{{action.icon}}"\n style="color: {{action.color}};"></i>\n </td>\n </tr>\n </tbody>\n </table>\n ',
+ template: '\n <!-- <pre>{{vm.data | json}}</pre> -->\n <table ng-class="vm.classes" ng-show="vm.data.length > 0">\n <thead>\n <tr>\n <th ng-repeat="col in vm.columns">{{col.label}}</th>\n <th ng-if="vm.config.actions">Actions</th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="item in vm.data">\n <td ng-repeat="col in vm.columns">{{item[col.prop]}}</td>\n <td ng-if="vm.config.actions">\n <a href=""\n ng-repeat="action in vm.config.actions"\n ng-click="action.cb(item)"\n title="action.label">\n <i\n class="glyphicon glyphicon-{{action.icon}}"\n style="color: {{action.color}};"></i>\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n ',
bindToController: true,
controllerAs: 'vm',
controller: function controller() {
diff --git a/views/ngXosLib/xosHelpers/spec/ui/table.test.js b/views/ngXosLib/xosHelpers/spec/ui/table.test.js
index e4c33f1..d83b6f6 100644
--- a/views/ngXosLib/xosHelpers/spec/ui/table.test.js
+++ b/views/ngXosLib/xosHelpers/spec/ui/table.test.js
@@ -31,51 +31,129 @@
expect(errorFunctionWrapper).toThrow(new Error('[xosTable] Please provide a columns list in the configuration'));
}));
- });
+ describe('when basicly configured', function() {
+ var scope, element, isolatedScope;
- describe('when correctly configured', function() {
- var scope, element, isolatedScope;
+ beforeEach(inject(function ($compile, $rootScope) {
+ scope = $rootScope.$new();
- beforeEach(inject(function ($compile, $rootScope) {
- scope = $rootScope.$new();
+ scope.config = {
+ columns: [
+ {
+ label: 'Label 1',
+ prop: 'label-1'
+ },
+ {
+ label: 'Label 2',
+ prop: 'label-2'
+ }
+ ]
+ };
- scope.config = {
- columns: [
+ scope.data = [
{
- label: 'Label 1',
- prop: 'label-1'
+ 'label-1': 'Sample 1.1',
+ 'label-2': 'Sample 1.2'
},
{
- label: 'Label 2',
- prop: 'label-2'
+ 'label-1': 'Sample 2.1',
+ 'label-2': 'Sample 2.2'
}
]
- };
- scope.data = [
- {
- 'label-1': 'Sample 1.1',
- 'label-2': 'Sample 1.2'
- },
- {
- 'label-1': 'Sample 2.1',
- 'label-2': 'Sample 2.2'
- }
- ]
+ element = angular.element('<xos-table config="config" data="data"></xos-table>');
+ $compile(element)(scope);
+ scope.$digest();
+ isolatedScope = element.isolateScope().vm;
+ }));
- element = angular.element('<xos-table config="config" data="data"></xos-table>');
- $compile(element)(scope);
- // scope.$apply();
- element.scope().$apply();
- isolatedScope = element.isolateScope();
- console.log(element, isolatedScope);
- }));
+ it('should contain 2 columns', function() {
+ var th = element[0].getElementsByTagName('th');
+ expect(th.length).toEqual(2);
+ expect(isolatedScope.columns.length).toEqual(2);
+ });
- xit('should contain 2 columns', function() {
- console.log('aaa', isolatedScope);
-
- // one is the filter, the other two are the products, one is the pagination
- expect(isolatedScope.columns).toEqual(2);
+ it('should contain 3 rows', function() {
+ var tr = element[0].getElementsByTagName('tr');
+ expect(tr.length).toEqual(3);
+ });
+
+ describe('when actions are passed', () => {
+
+ let cb = jasmine.createSpy('callback')
+
+ beforeEach(() => {
+ isolatedScope.config.actions = [
+ {
+ label: 'delete',
+ icon: 'remove',
+ cb: cb,
+ color: 'red'
+ }
+ ];
+ scope.$digest();
+ });
+
+ it('should have 3 columns', () => {
+ var th = element[0].getElementsByTagName('th');
+ expect(th.length).toEqual(3);
+ expect(isolatedScope.columns.length).toEqual(2);
+ });
+
+ it('when clicking on action should invoke callback', () => {
+ var link = element[0].getElementsByTagName('a')[0];
+ link.click();
+ expect(cb).toHaveBeenCalledWith(scope.data[0]);
+ });
+ });
+
+ describe('when filter is fulltext', () => {
+ beforeEach(() => {
+ isolatedScope.config.filter = 'fulltext';
+ scope.$digest();
+ });
+
+ it('should render a text field', () => {
+ var textField = element[0].getElementsByTagName('input');
+ expect(textField.length).toEqual(1);
+ });
+
+ describe('and a value is enterd', () => {
+ beforeEach(() => {
+ isolatedScope.query = '2.2';
+ scope.$digest();
+ });
+
+ it('should contain 2 rows', function() {
+ var tr = element[0].getElementsByTagName('tr');
+ expect(tr.length).toEqual(2);
+ });
+ });
+ });
+
+ describe('when filter is field', () => {
+ beforeEach(() => {
+ isolatedScope.config.filter = 'field';
+ scope.$digest();
+ });
+
+ it('should render a text field for each column', () => {
+ var textField = element[0].getElementsByTagName('input');
+ expect(textField.length).toEqual(2);
+ });
+
+ describe('and a value is enterd', () => {
+ beforeEach(() => {
+ isolatedScope.query = {'label-1': '2.1'};
+ scope.$digest();
+ });
+
+ it('should contain 3 rows', function() {
+ var tr = element[0].getElementsByTagName('tr');
+ expect(tr.length).toEqual(3);
+ });
+ });
+ });
});
});
});
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/table/table.component.js b/views/ngXosLib/xosHelpers/src/ui_components/table/table.component.js
index 4d117ae..f889a3b 100644
--- a/views/ngXosLib/xosHelpers/src/ui_components/table/table.component.js
+++ b/views/ngXosLib/xosHelpers/src/ui_components/table/table.component.js
@@ -22,6 +22,29 @@
* @name xos.uiComponents.table.directive:xosTable
* @restrict E
* @description The xos-table directive
+ * @param {Object} config The configuration for the component.
+ * ```
+ * {
+ * columns: [
+ * {
+ * label: 'Human readable name',
+ * prop: 'Property to read in the model object'
+ * }
+ * ],
+ * classes: 'table table-striped table-bordered',
+ * actions: [ // if defined add an action column
+ {
+ label: 'delete',
+ icon: 'remove', // refers to bootstraps glyphicon
+ cb: (user) => { // receive the model
+ console.log(user);
+ },
+ color: 'red'
+ }
+ ]
+ * }
+ * ```
+ * @param {Array} data The data that should be rendered
* @element ANY
* @scope
* @example
@@ -30,7 +53,6 @@
<file name="index.html">
<div ng-controller="SampleCtrl1 as vm">
<xos-table data="vm.data" config="vm.config"></xos-table>
- </xos-table>
</div>
</file>
<file name="script.js">
@@ -39,8 +61,8 @@
this.config = {
columns: [
{
- label: 'First Name',
- prop: 'name'
+ label: 'First Name', // column title
+ prop: 'name' // property to read in the data array
},
{
label: 'Last Name',
@@ -63,11 +85,10 @@
</file>
</example>
- <example module="sampleModule2">
+ <example module="sampleModule2">
<file name="index.html">
<div ng-controller="SampleCtrl2 as vm">
<xos-table data="vm.data" config="vm.config"></xos-table>
- </xos-table>
</div>
</file>
<file name="script.js">
@@ -76,23 +97,23 @@
this.config = {
columns: [
{
- label: 'First Name',
- prop: 'name'
+ label: 'First Name', // column title
+ prop: 'name' // property to read in the data array
},
{
label: 'Last Name',
prop: 'lastname'
}
],
- classes: 'table table-striped table-condensed',
- actions: [
+ classes: 'table table-striped table-condensed', // table classes, default to `table table-striped table-bordered`
+ actions: [ // if defined add an action column
{
- label: 'delete',
- icon: 'remove',
- cb: (user) => {
+ label: 'delete', // label
+ icon: 'remove', // icons, refers to bootstraps glyphicon
+ cb: (user) => { // callback, get feeded with the full object
console.log(user);
},
- color: 'red'
+ color: 'red' // icon color
}
]
};
@@ -122,6 +143,15 @@
},
template: `
<!-- <pre>{{vm.data | json}}</pre> -->
+ <div class="row" ng-if="vm.config.filter == 'fulltext'">
+ <div class="col-xs-12">
+ <input
+ class="form-control"
+ placeholder="Type to search.."
+ type="text"
+ ng-model="vm.query"/>
+ </div>
+ </div>
<table ng-class="vm.classes" ng-show="vm.data.length > 0">
<thead>
<tr>
@@ -129,15 +159,30 @@
<th ng-if="vm.config.actions">Actions</th>
</tr>
</thead>
+ <tbody ng-if="vm.config.filter == 'field'">
+ <tr>
+ <td ng-repeat="col in vm.columns">
+ <input
+ class="form-control"
+ placeholder="Type to search by {{col.label}}"
+ type="text"
+ ng-model="vm.query[col.prop]"/>
+ </td>
+ <td ng-if="vm.config.actions"></td>
+ </tr>
+ </tbody>
<tbody>
- <tr ng-repeat="item in vm.data">
+ <tr ng-repeat="item in vm.data | filter:vm.query">
<td ng-repeat="col in vm.columns">{{item[col.prop]}}</td>
<td ng-if="vm.config.actions">
- <i
+ <a href=""
ng-repeat="action in vm.config.actions"
ng-click="action.cb(item)"
- class="glyphicon glyphicon-{{action.icon}}"
- style="color: {{action.color}};"></i>
+ title="{{action.label}}">
+ <i
+ class="glyphicon glyphicon-{{action.icon}}"
+ style="color: {{action.color}};"></i>
+ </a>
</td>
</tr>
</tbody>
diff --git a/views/ngXosViews/sampleView/src/js/main.js b/views/ngXosViews/sampleView/src/js/main.js
index 5d94851..31fc373 100644
--- a/views/ngXosViews/sampleView/src/js/main.js
+++ b/views/ngXosViews/sampleView/src/js/main.js
@@ -33,11 +33,11 @@
prop: 'email'
},
{
- label: 'E-Mail',
+ label: 'First Name',
prop: 'firstname'
},
{
- label: 'E-Mail',
+ label: 'Last Name',
prop: 'lastname'
}
],
@@ -51,7 +51,8 @@
},
color: 'red'
}
- ]
+ ],
+ filter: 'field'
};
// retrieving user list
diff --git a/views/ngXosViews/sampleView/src/templates/users-list.tpl.html b/views/ngXosViews/sampleView/src/templates/users-list.tpl.html
index 4cb8d5a..10d7208 100644
--- a/views/ngXosViews/sampleView/src/templates/users-list.tpl.html
+++ b/views/ngXosViews/sampleView/src/templates/users-list.tpl.html
@@ -4,16 +4,6 @@
<p>This is only an example view.</p>
</div>
</div>
-<div class="row">
- <div class="col-xs-4">Email</div>
- <div class="col-xs-4">First Name</div>
- <div class="col-xs-4">Last Name</div>
-</div>
-<div class="row" ng-repeat="user in vm.users">
- <div class="col-xs-4">{{user.email}}</div>
- <div class="col-xs-4">{{user.firstname}}</div>
- <div class="col-xs-4">{{user.lastname}}</div>
-</div>
<div class="row">
<div class="col-xs-12">