Started xosForm component
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/alert.component.js b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/alert.component.js
new file mode 100644
index 0000000..7d7a026
--- /dev/null
+++ b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/alert.component.js
@@ -0,0 +1,145 @@
+/**
+ * © 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">
+    <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'])
+      .controller('SampleCtrl', function(){
+        this.config1 = {
+          type: 'success'
+        };
+
+        this.show = false;
+      });
+    </file>
+  </example>
+  **/
+
+  .directive('xosAlert', function(){
+    return {
+      restrict: 'E',
+      scope: {
+        config: '=',
+        show: '=?'
+      },
+      template: `
+        <div class="alert alert-{{vm.config.type}}" ng-show="vm.show">
+          <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">
+            <span aria-hidden="true">&times;</span>
+          </button>
+          <p ng-transclude></p>
+        </div>
+      `,
+      transclude: true,
+      bindToController: true,
+      controllerAs: 'vm',
+      controller: function($timeout){
+
+        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 = () => {
+          this.show = false;
+        }
+
+        if(this.config.autoHide){
+          let to = $timeout(() => {
+            this.dismiss();
+            $timeout.cancel(to);
+          }, this.config.autoHide);
+        }
+      }
+    }
+  })
+})();
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/form.component.js b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/form.component.js
new file mode 100644
index 0000000..f33c639
--- /dev/null
+++ b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/form.component.js
@@ -0,0 +1,154 @@
+/**
+ * © OpenCORD
+ *
+ * Visit http://guide.xosproject.org/devguide/addview/ for more information
+ *
+ * Created by teone on 4/18/16.
+ */
+
+(function () {
+  'use strict';
+
+  angular.module('xos.uiComponents')
+
+  /**
+    * @ngdoc directive
+    * @name xos.uiComponents.directive:xosForm
+    * @restrict E
+    * @description The xos-form directive
+    * @param {Object} config The configuration object
+    * ```
+    * {
+    *   exclude: ['id', 'validators', 'created', 'updated', 'deleted'], //field to be skipped in the form, the provide values are concatenated
+    *   actions: [ // define the form buttons with related callback
+    *     {
+            label: 'save',
+            icon: 'ok', // refers to bootstraps glyphicon
+            cb: (user) => { // receive the model
+              console.log(user);
+            },
+            class: 'success'
+          }
+    *   ]
+    * }
+    * ```
+    * @element ANY
+    * @scope
+    * @example
+  <example module="sampleAlert1">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl1 as vm">
+        
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('sampleAlert1', ['xos.uiComponents'])
+      .controller('SampleCtrl1', function(){
+        this.config1 = {
+          exclude: ['password', 'last_login']
+        };
+      });
+    </file>
+  </example>
+
+  **/
+
+  .directive('xosForm', function(){
+    return {
+      restrict: 'E',
+      scope: {
+        config: '=',
+        ngModel: '='
+      },
+      template: `
+        <ng-form name="vm.config.formName || 'form'">
+          <div class="form-group" ng-repeat="field in vm.formField">
+            <label>{{vm.formatLabel(field.label)}}</label>
+            <input type="text" name="" class="form-control" ng-model="vm.ngModel[field]"/>
+          </div>
+          <div class="form-group" ng-if="vm.config.actions">
+            <button href=""
+              ng-repeat="action in vm.config.actions"
+              ng-click="action.cb(vm.ngModel)"
+              class="btn btn-{{action.class}}"
+              title="{{action.label}}">
+              <i class="glyphicon glyphicon-{{action.icon}}"></i>
+              {{action.label}}
+            </button>
+          </div>
+        </ng-form>
+      `,
+      bindToController: true,
+      controllerAs: 'vm',
+      controller: function($scope, $log, _, LabelFormatter, XosFormHelpers){
+
+        if(!this.config){
+          throw new Error('[xosForm] Please provide a configuration via the "config" attribute');
+        }
+
+        if(!this.config.actions){
+          throw new Error('[xosForm] Please provide an action list in the configuration');
+        }
+
+        this.formatLabel = LabelFormatter.format;
+
+        this.excludedField = ['id', 'validators', 'created', 'updated', 'deleted', 'backend_status'];
+        if(this.config && this.config.exclude){
+          this.excludedField = this.excludedField.concat(this.config.exclude);
+        }
+
+
+        this.formField = [];
+        $scope.$watch(() => this.ngModel, (model) => {
+          if(!model){
+            return;
+          }
+          this.formField = XosFormHelpers.buildFormStructure(_.difference(Object.keys(model), this.excludedField));
+        });
+
+      }
+    }
+  })
+  .service('XosFormHelpers', function(_, LabelFormatter){
+
+    this._getFieldFormat = (value) => {
+
+      // check if is date
+      if (_.isDate(value)){
+        return 'date';
+      }
+
+      // check if is boolean
+      // isNaN(false) = false, false is a number (0), true is a number (1)
+      if(typeof value  === 'boolean'){
+        return 'boolean';
+      }
+
+      // check if a string is a number
+      if(!isNaN(value)){
+        return 'number';
+      }
+
+      return typeof value;
+    };
+
+    this.buildFormStructure = (modelField, customField, model) => {
+      return _.reduce(Object.keys(modelField), (form, f) => {
+        form[f] = {
+          label: (customField[f] && customField[f].label) ? `${customField[f].label}:` : LabelFormatter.format(f),
+          type: (customField[f] && customField[f].type) ? customField[f].type : this._getFieldFormat(model[f]),
+          validators: {}
+        };
+        return form;
+      }, {});
+    };
+
+    this.parseModelField = (fields) => {
+      return _.reduce(fields, (form, f) => {
+        form[f] = {};
+        return form;
+      }, {});
+    }
+
+  })
+})();
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/pagination.component.js b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/pagination.component.js
new file mode 100644
index 0000000..b7b1701
--- /dev/null
+++ b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/pagination.component.js
@@ -0,0 +1,122 @@
+/**
+ * © 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:xosPagination
+    * @restrict E
+    * @description The xos-table directive
+    * @param {Number} pageSize Number of elements per page
+    * @param {Number} totalElements Number of total elements in the collection
+    * @param {Function} change The callback to be triggered on page change.
+    * * @element ANY
+    * @scope
+    * @example
+  <example module="samplePagination">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl1 as vm">
+        <xos-pagination
+          page-size="vm.pageSize"
+          total-elements="vm.totalElements"
+          change="vm.change">
+        </xos-pagination>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('samplePagination', ['xos.uiComponents'])
+      .controller('SampleCtrl1', function(){
+        this.pageSize = 10;
+        this.totalElements = 35;
+        this.change = (pageNumber) => {
+          console.log(pageNumber);
+        }
+      });
+    </file>
+  </example>
+  **/
+
+  .directive('xosPagination', function(){
+    return {
+      restrict: 'E',
+      scope: {
+        pageSize: '=',
+        totalElements: '=',
+        change: '='
+      },
+      template: `
+        <div class="row" ng-if="vm.pageList.length > 1">
+          <div class="col-xs-12 text-center">
+            <ul class="pagination">
+              <li
+                ng-click="vm.goToPage(vm.currentPage - 1)"
+                ng-class="{disabled: vm.currentPage == 0}">
+                <a href="" aria-label="Previous">
+                    <span aria-hidden="true">&laquo;</span>
+                </a>
+              </li>
+              <li ng-repeat="i in vm.pageList" ng-class="{active: i === vm.currentPage}">
+                <a href="" ng-click="vm.goToPage(i)">{{i + 1}}</a>
+              </li>
+              <li
+                ng-click="vm.goToPage(vm.currentPage + 1)"
+                ng-class="{disabled: vm.currentPage == vm.pages - 1}">
+                <a href="" aria-label="Next">
+                    <span aria-hidden="true">&raquo;</span>
+                </a>
+              </li>
+            </ul>
+          </div>
+        </div>
+      `,
+      bindToController: true,
+      controllerAs: 'vm',
+      controller: function($scope){
+        
+        this.currentPage = 0;
+
+        this.goToPage = (n) => {
+          if(n < 0 || n === this.pages){
+            return;
+          }
+          this.currentPage = n;
+          this.change(n);
+        }
+
+        this.createPages = (pages) => {
+          let arr = [];
+          for(var i = 0; i < pages; i++){
+            arr.push(i);
+          }
+          return arr;
+        }
+
+        // watch for data changes
+        $scope.$watch(() => this.totalElements, () => {
+          if(this.totalElements){
+            this.pages = Math.ceil(this.totalElements / this.pageSize);
+            this.pageList = this.createPages(this.pages);
+          }
+        });
+      }
+    }
+  })
+  .filter('pagination', function(){
+    return function(input, start) {
+      if(!input || !angular.isArray(input)){
+        return input;
+      }
+      start = parseInt(start, 10);
+      return input.slice(start);
+    };
+  });
+})();
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/table.component.js b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/table.component.js
new file mode 100644
index 0000000..02ce30c
--- /dev/null
+++ b/views/ngXosLib/xosHelpers/src/ui_components/dumbComponents/table.component.js
@@ -0,0 +1,285 @@
+/**
+ * © OpenCORD
+ *
+ * Visit http://guide.xosproject.org/devguide/addview/ for more information
+ *
+ * Created by teone on 3/24/16.
+ */
+
+(function () {
+  'use strict';
+
+  angular.module('xos.uiComponents')
+
+    /**
+    * @ngdoc directive
+    * @name xos.uiComponents.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'
+          }
+        ],
+        filter: 'field', // can be by `field` or `fulltext`
+        order: true // whether to show ordering arrows
+    * }
+    * ```
+    * @param {Array} data The data that should be rendered
+    * @element ANY
+    * @scope
+    * @example
+
+  <example module="sampleTable1">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl1 as vm">
+        <xos-table data="vm.data" config="vm.config"></xos-table>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('sampleTable1', ['xos.uiComponents'])
+      .controller('SampleCtrl1', function(){
+        this.config = {
+          columns: [
+            {
+              label: 'First Name', // column title
+              prop: 'name' // property to read in the data array
+            },
+            {
+              label: 'Last Name',
+              prop: 'lastname'
+            }
+          ]
+        };
+
+        this.data = [
+          {
+            name: 'John',
+            lastname: 'Doe'
+          },
+          {
+            name: 'Gili',
+            lastname: 'Fereydoun'
+          }
+        ]
+      });
+    </file>
+  </example>
+
+  <example module="sampleTable2">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl2 as vm">
+        <xos-table data="vm.data" config="vm.config"></xos-table>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('sampleTable2', ['xos.uiComponents'])
+      .controller('SampleCtrl2', function(){
+        this.config = {
+          columns: [
+            {
+              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', // table classes, default to `table table-striped table-bordered`
+          actions: [ // if defined add an action column
+            {
+              label: 'delete', // label
+              icon: 'remove', // icons, refers to bootstraps glyphicon
+              cb: (user) => { // callback, get feeded with the full object
+                console.log(user);
+              },
+              color: 'red' // icon color
+            }
+          ],
+          filter: 'field', // can be by `field` or `fulltext`
+          order: true
+        };
+
+        this.data = [
+          {
+            name: 'John',
+            lastname: 'Doe'
+          },
+          {
+            name: 'Gili',
+            lastname: 'Fereydoun'
+          }
+        ]
+      });
+    </file>
+  </example>
+
+  <example module="sampleTable3">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl3 as vm">
+        <xos-table data="vm.data" config="vm.config"></xos-table>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('sampleTable3', ['xos.uiComponents'])
+      .controller('SampleCtrl3', function(){
+        this.config = {
+          columns: [
+            {
+              label: 'First Name', // column title
+              prop: 'name' // property to read in the data array
+            },
+            {
+              label: 'Last Name',
+              prop: 'lastname'
+            }
+          ],
+          pagination: {
+            pageSize: 2
+          }
+        };
+
+        this.data = [
+          {
+            name: 'John',
+            lastname: 'Doe'
+          },
+          {
+            name: 'Gili',
+            lastname: 'Fereydoun'
+          },
+          {
+            name: 'Lucky',
+            lastname: 'Clarkson'
+          },
+          {
+            name: 'Tate',
+            lastname: 'Spalding'
+          }
+        ]
+      });
+    </file>
+  </example>
+    **/
+
+    .directive('xosTable', function(){
+      return {
+        restrict: 'E',
+        scope: {
+          data: '=',
+          config: '='
+        },
+        template: `
+          <div ng-show="vm.data.length > 0">
+            <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>
+                  <th ng-repeat="col in vm.columns">
+                    {{col.label}}
+                    <span ng-if="vm.config.order">
+                      <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = false">
+                        <i class="glyphicon glyphicon-chevron-up"></i>
+                      </a>
+                      <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = true">
+                        <i class="glyphicon glyphicon-chevron-down"></i>
+                      </a>
+                    </span>
+                  </th>
+                  <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 | 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">
+                  <td ng-repeat="col in vm.columns">{{item[col.prop]}}</td>
+                  <td ng-if="vm.config.actions">
+                    <a href=""
+                      ng-repeat="action in vm.config.actions"
+                      ng-click="action.cb(item)"
+                      title="{{action.label}}">
+                      <i
+                        class="glyphicon glyphicon-{{action.icon}}"
+                        style="color: {{action.color}};"></i>
+                    </a>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+            <xos-pagination
+              ng-if="vm.config.pagination"
+              page-size="vm.config.pagination.pageSize"
+              total-elements="vm.data.length"
+              change="vm.goToPage">
+              </xos-pagination>
+          </div>
+          <div ng-show="vm.data.length == 0 || !vm.data">
+             <xos-alert config="{type: 'info'}">
+              No data to show.
+            </xos-alert>
+          </div>
+        `,
+        bindToController: true,
+        controllerAs: 'vm',
+        controller: function(){
+
+          if(!this.config){
+            throw new Error('[xosTable] Please provide a configuration via the "config" attribute');
+          }
+
+          if(!this.config.columns){
+            throw new Error('[xosTable] Please provide a columns list in the configuration');
+          }
+
+          this.columns = this.config.columns;
+          this.classes = this.config.classes || 'table table-striped table-bordered';
+
+          if(this.config.actions){
+            // TODO validate action format
+          }
+          if(this.config.pagination){
+            this.currentPage = 0;
+            this.goToPage = (n) => {
+              this.currentPage = n;
+            };
+          }
+
+        }
+      }
+    })
+})();