Hiding field in smartTable
diff --git a/views/ngXosLib/karma.conf.js b/views/ngXosLib/karma.conf.js
index 39c2d0a..b7448f5 100644
--- a/views/ngXosLib/karma.conf.js
+++ b/views/ngXosLib/karma.conf.js
@@ -77,7 +77,7 @@
 
     // level of logging
     // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
-    logLevel: config.LOG_ERROR,
+    logLevel: config.LOG_INFO,
 
 
     // enable / disable watching file and executing tests whenever any file changes
diff --git a/views/ngXosLib/xosHelpers/spec/ui/smart-table.test.js b/views/ngXosLib/xosHelpers/spec/ui/smart-table.test.js
index 95b7d4b..e8cc030 100644
--- a/views/ngXosLib/xosHelpers/spec/ui/smart-table.test.js
+++ b/views/ngXosLib/xosHelpers/spec/ui/smart-table.test.js
@@ -7,10 +7,19 @@
 (function () {
   'use strict';
 
+  const mockData = [
+    {
+      id: 1,
+      first_name: 'Jon',
+      last_name: 'Snow',
+      hidden_field: 'hidden'
+    }
+  ];
+
   describe('The xos.helper module', function(){
     describe('The xos-smart-table component', () => {
 
-      let spy, scope, isolatedScope, element;
+      var spy, emptySpy, scope, isolatedScope, element;
 
       beforeEach(module('xos.helpers'));
 
@@ -18,12 +27,15 @@
       beforeEach(function(){
         module(function($provide){
           $provide.service('MockResource', function(){
-            this.test = (msg) => console.log(msg);
-            this.query = jasmine.createSpy('add')
-              .and.returnValue({$promise: cb => {
-                console.log('------------------ CB ------------------');
-                return cb([]);
-              }});
+            this.query = jasmine.createSpy('query').and.callFake(() => {
+              return {$promise: {then: (cb) => cb(mockData)}};
+            });
+          });
+
+          $provide.service('EmptyResource', function(){
+            this.query = jasmine.createSpy('emptyQuery').and.callFake(() => {
+              return {$promise: {then: (cb) => cb([])}};
+            });
           });
         });
       })
@@ -32,11 +44,11 @@
         scope = $rootScope.$new();
 
         scope.config = {
-          resource: 'MockResource'
+          resource: 'MockResource',
+          hiddenFields: ['hidden_field']
         };
 
         spy = MockResource;
-        // console.log(MockResource.query.toString(), spy.query.toString());
 
         element = angular.element('<xos-smart-table config="config"></xos-smart-table>');
         $compile(element)(scope);
@@ -45,11 +57,40 @@
       }));
 
       it('should query elements', () => {
-
-        console.log(spy.query.toString());
         expect(spy.query).toHaveBeenCalled();
+        expect($(element).find('.alert').parent().parent()).toHaveClass('ng-hide');
       });
 
+      it('should hide hidden fields', () => {
+        expect($(element).find('thead th').length).toEqual(2);
+        expect($(element).find('thead th')[0]).toContainText('First name:');
+        expect($(element).find('thead th')[1]).toContainText('Last name:');
+      });
+
+      describe('when fetching an empty collection', () => {
+        beforeEach(inject(function ($compile, $rootScope, EmptyResource) {
+          scope = $rootScope.$new();
+
+          scope.config = {
+            resource: 'EmptyResource'
+          };
+
+          emptySpy = EmptyResource;
+
+          element = angular.element('<xos-smart-table config="config"></xos-smart-table>');
+          $compile(element)(scope);
+          scope.$digest();
+          isolatedScope = element.isolateScope().vm;
+        }));
+
+        it('should display an alert', () => {
+          expect(emptySpy.query).toHaveBeenCalled();
+          expect($(element).find('.alert').parent().parent()).not.toHaveClass('ng-hide');
+          expect($(element).find('.alert')).toContainText('No data to show');
+        });
+      });
+
+
     });
   });
 })();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js b/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js
index b8b5915..4a0ecd9 100644
--- a/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js
+++ b/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js
@@ -48,6 +48,7 @@
           //     color: 'red'
           //   }
           // ],
+          classes: 'table table-striped table-bordered table-responsive',
           filter: 'field',
           order: true,
           pagination: {
@@ -55,22 +56,26 @@
           }
         };
 
-        let Resource = $injector.get(this.config.resource);
+        this.Resource = $injector.get(this.config.resource);
 
-        console.log('query', Resource.query.toString(), Resource.test(`I'm Alive!`));
-
-        Resource.query().$promise
+        this.Resource.query().$promise
         .then((res) => {
-          console.log('Data!!');
+
+          if(!res[0]){
+            return;
+          }
+
           let props = Object.keys(res[0]);
 
           _.remove(props, p => {
             return p == 'id' || p == 'password' || p == 'validators'
           });
 
-          let labels = props.map(p => LabelFormatter.format(p));
+          if(angular.isArray(this.config.hiddenFields)){
+            props = _.difference(props, this.config.hiddenFields)
+          }
 
-          console.log(props, labels);
+          let labels = props.map(p => LabelFormatter.format(p));
 
           props.forEach((p, i) => {
             this.tableConfig.columns.push({
@@ -79,9 +84,6 @@
             });
           });
 
-
-          console.log(this.tableConfig.columns);
-
           this.data = res;
         })
       }
diff --git a/views/ngXosViews/sampleView/src/js/main.js b/views/ngXosViews/sampleView/src/js/main.js
index 5f7be4d..790eb49 100644
--- a/views/ngXosViews/sampleView/src/js/main.js
+++ b/views/ngXosViews/sampleView/src/js/main.js
@@ -60,7 +60,8 @@
       };
 
       this.smartTableConfig = {
-        resource: 'Users'
+        resource: 'Users',
+        hiddenFields: ['last_login']
       }
 
       this.alertConfig = {
diff --git a/xos/core/xoslib/static/js/vendor/ngXosHelpers.js b/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
index f957a2f..0dd6043 100644
--- a/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
+++ b/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
@@ -71,6 +71,7 @@
           //     color: 'red'
           //   }
           // ],
+          classes: 'table table-striped table-bordered table-responsive',
           filter: 'field',
           order: true,
           pagination: {
@@ -78,24 +79,28 @@
           }
         };
 
-        var Resource = $injector.get(this.config.resource);
+        this.Resource = $injector.get(this.config.resource);
 
-        console.log('query', Resource.query.toString(), Resource.test('I\'m Alive!'));
+        this.Resource.query().$promise.then(function (res) {
 
-        Resource.query().$promise.then(function (res) {
-          console.log('Data!!');
+          if (!res[0]) {
+            return;
+          }
+
           var props = Object.keys(res[0]);
 
           _.remove(props, function (p) {
             return p == 'id' || p == 'password' || p == 'validators';
           });
 
+          if (angular.isArray(_this.config.hiddenFields)) {
+            props = _.difference(props, _this.config.hiddenFields);
+          }
+
           var labels = props.map(function (p) {
             return LabelFormatter.format(p);
           });
 
-          console.log(props, labels);
-
           props.forEach(function (p, i) {
             _this.tableConfig.columns.push({
               label: labels[i],
@@ -103,8 +108,6 @@
             });
           });
 
-          console.log(_this.tableConfig.columns);
-
           _this.data = res;
         });
       }]
@@ -528,6 +531,145 @@
 
 'use strict';
 
+/**
+ * © OpenCORD
+ *
+ * Visit http://guide.xosproject.org/devguide/addview/ for more information
+ *
+ * Created by teone on 4/15/16.
+ */
+
+(function () {
+  'use strict';
+
+  angular.module('xos.uiComponents')
+
+  /**
+    * @ngdoc directive
+    * @name xos.uiComponents.directive:xosAlert
+    * @restrict E
+    * @description The xos-alert directive
+    * @param {Object} config The configuration object
+    * ```
+    * {
+    *   type: 'danger', //info, success, warning
+    *   closeBtn: true, //default false
+    *   autoHide: 3000 //delay to automatically hide the alert
+    * }
+    * ```
+    * @param {Boolean=} show Binding to show and hide the alert, default to true
+    * @element ANY
+    * @scope
+    * @example
+  <example module="sampleAlert1">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl1 as vm">
+        <xos-alert config="vm.config1">
+          A sample alert message
+        </xos-alert>
+        <xos-alert config="vm.config2">
+          A sample alert message (with close button)
+        </xos-alert>
+        <xos-alert config="vm.config3">
+          A sample info message
+        </xos-alert>
+        <xos-alert config="vm.config4">
+          A sample success message
+        </xos-alert>
+        <xos-alert config="vm.config5">
+          A sample warning message
+        </xos-alert>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('sampleAlert1', ['xos.uiComponents'])
+      .controller('SampleCtrl1', function(){
+        this.config1 = {
+          type: 'danger'
+        };
+         this.config2 = {
+          type: 'danger',
+          closeBtn: true
+        };
+         this.config3 = {
+          type: 'info'
+        };
+         this.config4 = {
+          type: 'success'
+        };
+         this.config5 = {
+          type: 'warning'
+        };
+      });
+    </file>
+  </example>
+   <example module="sampleAlert2" animations="true">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl as vm" class="row">
+        <div class="col-sm-4">
+          <a class="btn btn-default btn-block" ng-show="!vm.show" ng-click="vm.show = true">Show Alert</a>
+          <a class="btn btn-default btn-block" ng-show="vm.show" ng-click="vm.show = false">Hide Alert</a>
+        </div>
+        <div class="col-sm-8">
+          <xos-alert config="vm.config1" show="vm.show">
+            A sample alert message, not displayed by default.
+          </xos-alert>
+        </div>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('sampleAlert2', ['xos.uiComponents', 'ngAnimate'])
+      .controller('SampleCtrl', function(){
+        this.config1 = {
+          type: 'success'
+        };
+         this.show = false;
+      });
+    </file>
+  </example>
+  **/
+
+  .directive('xosAlert', function () {
+    return {
+      restrict: 'E',
+      scope: {
+        config: '=',
+        show: '=?'
+      },
+      template: '\n        <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n          <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n            <span aria-hidden="true">&times;</span>\n          </button>\n          <p ng-transclude></p>\n        </div>\n      ',
+      transclude: true,
+      bindToController: true,
+      controllerAs: 'vm',
+      controller: ["$timeout", function controller($timeout) {
+        var _this = this;
+
+        if (!this.config) {
+          throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');
+        }
+
+        // default the value to true
+        this.show = this.show !== false;
+
+        this.dismiss = function () {
+          _this.show = false;
+        };
+
+        if (this.config.autoHide) {
+          (function () {
+            var to = $timeout(function () {
+              _this.dismiss();
+              $timeout.cancel(to);
+            }, _this.config.autoHide);
+          })();
+        }
+      }]
+    };
+  });
+})();
+//# sourceMappingURL=../../../maps/ui_components/dumbComponents/alert/alert.component.js.map
+
+'use strict';
+
 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
 
 /**
@@ -717,145 +859,6 @@
 
 'use strict';
 
-/**
- * © OpenCORD
- *
- * Visit http://guide.xosproject.org/devguide/addview/ for more information
- *
- * Created by teone on 4/15/16.
- */
-
-(function () {
-  'use strict';
-
-  angular.module('xos.uiComponents')
-
-  /**
-    * @ngdoc directive
-    * @name xos.uiComponents.directive:xosAlert
-    * @restrict E
-    * @description The xos-alert directive
-    * @param {Object} config The configuration object
-    * ```
-    * {
-    *   type: 'danger', //info, success, warning
-    *   closeBtn: true, //default false
-    *   autoHide: 3000 //delay to automatically hide the alert
-    * }
-    * ```
-    * @param {Boolean=} show Binding to show and hide the alert, default to true
-    * @element ANY
-    * @scope
-    * @example
-  <example module="sampleAlert1">
-    <file name="index.html">
-      <div ng-controller="SampleCtrl1 as vm">
-        <xos-alert config="vm.config1">
-          A sample alert message
-        </xos-alert>
-        <xos-alert config="vm.config2">
-          A sample alert message (with close button)
-        </xos-alert>
-        <xos-alert config="vm.config3">
-          A sample info message
-        </xos-alert>
-        <xos-alert config="vm.config4">
-          A sample success message
-        </xos-alert>
-        <xos-alert config="vm.config5">
-          A sample warning message
-        </xos-alert>
-      </div>
-    </file>
-    <file name="script.js">
-      angular.module('sampleAlert1', ['xos.uiComponents'])
-      .controller('SampleCtrl1', function(){
-        this.config1 = {
-          type: 'danger'
-        };
-         this.config2 = {
-          type: 'danger',
-          closeBtn: true
-        };
-         this.config3 = {
-          type: 'info'
-        };
-         this.config4 = {
-          type: 'success'
-        };
-         this.config5 = {
-          type: 'warning'
-        };
-      });
-    </file>
-  </example>
-   <example module="sampleAlert2" animations="true">
-    <file name="index.html">
-      <div ng-controller="SampleCtrl as vm" class="row">
-        <div class="col-sm-4">
-          <a class="btn btn-default btn-block" ng-show="!vm.show" ng-click="vm.show = true">Show Alert</a>
-          <a class="btn btn-default btn-block" ng-show="vm.show" ng-click="vm.show = false">Hide Alert</a>
-        </div>
-        <div class="col-sm-8">
-          <xos-alert config="vm.config1" show="vm.show">
-            A sample alert message, not displayed by default.
-          </xos-alert>
-        </div>
-      </div>
-    </file>
-    <file name="script.js">
-      angular.module('sampleAlert2', ['xos.uiComponents', 'ngAnimate'])
-      .controller('SampleCtrl', function(){
-        this.config1 = {
-          type: 'success'
-        };
-         this.show = false;
-      });
-    </file>
-  </example>
-  **/
-
-  .directive('xosAlert', function () {
-    return {
-      restrict: 'E',
-      scope: {
-        config: '=',
-        show: '=?'
-      },
-      template: '\n        <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n          <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n            <span aria-hidden="true">&times;</span>\n          </button>\n          <p ng-transclude></p>\n        </div>\n      ',
-      transclude: true,
-      bindToController: true,
-      controllerAs: 'vm',
-      controller: ["$timeout", function controller($timeout) {
-        var _this = this;
-
-        if (!this.config) {
-          throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');
-        }
-
-        // default the value to true
-        this.show = this.show !== false;
-
-        this.dismiss = function () {
-          _this.show = false;
-        };
-
-        if (this.config.autoHide) {
-          (function () {
-            var to = $timeout(function () {
-              _this.dismiss();
-              $timeout.cancel(to);
-            }, _this.config.autoHide);
-          })();
-        }
-      }]
-    };
-  });
-})();
-//# sourceMappingURL=../../../maps/ui_components/dumbComponents/alert/alert.component.js.map
-
-'use strict';
-
 (function () {
   'use strict';