/**
* @ngdoc directive
* @name Bastion.components.directive:bstTable
* @restrict A
*
* @requires $window
*
* @description
*
* @example
*/
angular.module('Bastion.components')
.directive('bstTable', ['$window', function ($window) {
return {
restrict: 'A',
replace: true,
scope: {
'table': '=bstTable',
'rowSelect': '@',
'rowChoice': '@'
},
controller: 'BstTableController',
link: function (scope) {
var resize = function () {
angular.element($window).trigger('resize');
};
// Trigger resize after resource $promise is resolved
scope.$watch('table.resource', function (resource) {
if (resource && resource.hasOwnProperty('$promise')) {
resource.$promise.then(resize);
}
});
// Trigger resize when rows change
scope.$watch('table.rows', resize);
}
};
}])
.controller('BstTableController', ['$scope', function ($scope) {
var rows = $scope.rows = [],
headers = $scope.headers = [],
self = this;
this.selection = {allSelected: false, selectAllDisabled: false};
if (!$scope.table.numSelected) {
$scope.table.numSelected = 0;
}
$scope.table.chosenRow = null;
$scope.table.getSelected = function () {
var selectedRows = [];
angular.forEach($scope.table.rows, function (row, rowIndex) {
if (row.selected === true) {
selectedRows.push($scope.table.rows[rowIndex]);
}
});
return selectedRows;
};
$scope.table.selectAllDisabled = false;
this.disableSelectAll = $scope.table.disableSelectAll = function () {
self.selection.selectAllDisabled = true;
};
this.enableSelectAll = $scope.table.enableSelectAll = function () {
self.selection.selectAllDisabled = false;
};
$scope.table.allSelected = function () {
return self.selection.allSelected;
};
this.addRow = function (row) {
rows.push(row);
if (headers.length) {
angular.forEach(headers[0].columns, function (column, columnIndex) {
if (row.cells[columnIndex]) {
row.cells[columnIndex].show = column.show;
}
});
}
};
this.addHeader = function (columns) {
headers.push(columns);
};
this.itemSelected = function (row) {
$scope.table.numSelected += row.selected ? 1 : -1;
self.selection.allSelected = false;
};
this.itemChosen = function (row) {
$scope.table.chosenRow = row;
};
this.selectAll = $scope.table.selectAll = function (selected) {
var table = $scope.table,
rowsSelected = 0;
self.selection.allSelected = selected;
angular.forEach(table.rows, function (row) {
if (!row.unselectable) {
row.selected = self.selection.allSelected;
rowsSelected = rowsSelected + 1;
}
});
$scope.table.numSelected = selected ? rowsSelected : 0;
};
}])
.directive('bstTableHead', [function () {
var rowSelectTemplate = function () {
return '
' +
'' +
' | ';
}, rowChoiceTemplate = function () {
return ' | ';
};
return {
require: '^bstTable',
restrict: 'A',
scope: true,
controller: 'BstTableHeadController',
compile: function (tElement, tAttrs) {
if (angular.isDefined(tAttrs.rowSelect)) {
tElement.prepend(rowSelectTemplate());
} else if (angular.isDefined(tAttrs.rowChoice)) {
tElement.prepend(rowChoiceTemplate());
}
return function (scope, element, attrs, bstTableController) {
if (angular.isDefined(tAttrs.rowSelect)) {
scope.table.rowSelect = true;
} else if (angular.isDefined(tAttrs.rowChoice)) {
scope.table.rowChoice = true;
}
bstTableController.addHeader(scope.header);
scope.selection = bstTableController.selection;
scope.allSelected = function () {
bstTableController.selectAll(scope.selection.allSelected);
};
};
}
};
}])
.controller('BstTableHeadController', ['$scope', function ($scope) {
$scope.header = {
columns: []
};
this.addColumn = function (column) {
$scope.header.columns.push(column);
};
}])
.directive('bstTableColumn', ['$compile', function ($compile) {
var sortIconTemplate = '' +
'' +
' | ';
return {
require: '^bstTableHead',
restrict: 'A',
scope: true,
controller: ['$scope', function ($scope) {
$scope.column = { show: true };
}],
compile: function (tElement, tAttributes) {
var newElement;
if (tAttributes.hasOwnProperty("sortable")) {
newElement = angular.element(sortIconTemplate);
newElement.find('.sort-icon').before(tElement.html());
newElement.addClass('sortable');
newElement.addClass(tElement.attr('class'));
tElement.replaceWith(newElement);
}
return function (scope, element, attributes, bstTableHeadController) {
if (attributes.hasOwnProperty("sortable")) {
$compile(element)(scope);
}
scope.column.id = attributes.bstTableColumn;
bstTableHeadController.addColumn(scope.column);
scope.$watch('column.show', function (show) {
var display = show ? '' : 'none';
element.css('display', display);
});
};
}
};
}])
.directive('bstTableRow', ['$parse', function ($parse) {
var rowSelectTemplate, rowChoiceTemplate, activeRowTemplate;
rowSelectTemplate = function (model) {
return '' +
'' +
' | ';
};
rowChoiceTemplate = function (model) {
return '' +
'' +
' | ';
};
activeRowTemplate = function (activeTest) {
return '';
};
return {
require: '^bstTable',
restrict: 'A',
scope: true,
controller: 'BstTableRowController',
compile: function (tElement, tAttrs) {
if (angular.isDefined(tAttrs.activeRow)) {
tElement.find('td:first-child').append(activeRowTemplate(tAttrs.activeRow));
}
if (angular.isDefined(tAttrs.rowSelect)) {
tElement.prepend(rowSelectTemplate(tAttrs.rowSelect));
}
if (angular.isDefined(tAttrs.rowChoice)) {
tElement.prepend(rowChoiceTemplate(tAttrs.rowChoice));
}
if (angular.isDefined(tAttrs.activeRow)) {
tElement.find('td').attr('ng-class', '{ "active-row": ' + tAttrs.activeRow + ' }');
}
return function (scope, element, attrs, bstTableController) {
bstTableController.addRow(scope.row);
if (attrs.rowSelect) {
scope.model = $parse(attrs.rowSelect)(scope);
if ($parse(attrs.rowSelectIf)(scope)) {
scope.model.unselectable = true;
}
scope.$watch('model.selected', function (selected) {
if (selected) {
element.addClass('selected-row');
} else {
element.removeClass('selected-row');
}
});
} else if (attrs.rowChoice) {
scope.model = $parse(attrs.rowChoice)(scope);
}
if (attrs.activeRow) {
scope.activeTest = $parse(attrs.activeRow)(scope);
}
scope.itemSelected = function (row) {
bstTableController.itemSelected(row);
};
scope.itemChosen = function (row) {
element.parent().find('.selected-row').removeClass('selected-row');
element.addClass('selected-row');
bstTableController.itemChosen(row);
};
};
}
};
}])
.controller('BstTableRowController', ['$scope', function ($scope) {
$scope.row = {
cells: []
};
this.addCell = function (cell) {
$scope.row.cells.push(cell);
};
}])
.directive('bstTableCell', [function () {
return {
require: '^bstTableRow',
restrict: 'A',
scope: true,
controller: ['$scope', function ($scope) {
$scope.cell = { show: true };
}],
link: function (scope, element, attrs, bstTableRowController) {
bstTableRowController.addCell(scope.cell);
scope.$watch('cell.show', function (show) {
var display = show ? '' : 'none';
element.css('display', display);
});
}
};
}]);