').attr({
'aria-label': 'Select All',
@@ -737,68 +737,82 @@ function mdHead($compile) {
'ng-disabled': '!getSelectableRows().length'
});
}
-
+
function detachCheckbox() {
var cell = element.prop('lastElementChild').firstElementChild;
-
+
if(cell.classList.contains('md-checkbox-column')) {
angular.element(cell).empty();
}
}
-
+
function enableRowSelection() {
return tableCtrl.$$rowSelect;
}
-
+
function mdSelectCtrl(row) {
return angular.element(row).controller('mdSelect');
}
-
+
function removeCheckboxColumn() {
Array.prototype.some.call(element.find('th'), function (cell) {
return cell.classList.contains('md-checkbox-column') && cell.remove();
});
}
-
+
scope.allSelected = function () {
var rows = scope.getSelectableRows();
-
return rows.length && rows.every(function (row) {
return row.isSelected();
});
};
-
+
scope.getSelectableRows = function () {
return tableCtrl.getBodyRows().map(mdSelectCtrl).filter(function (ctrl) {
return ctrl && !ctrl.disabled;
});
};
-
- scope.selectAll = function () {
- tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
- if(ctrl && !ctrl.isSelected()) {
- ctrl.select();
+
+
+ /*
+ Updated this function
+ - to select all rows if the md-select-all attribute is visible and contains an array of ojects
+ - if md-select-all is undefined function will default to its orignal behaviour "select on rows on page"
+ */
+ scope.selectAll = function () {
+ tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
+ if (ctrl.model_allRows) {
+ ctrl.selectAll();
+ }else if(ctrl && !ctrl.isSelected()) {
+ ctrl.select();
}
});
};
-
+
scope.toggleAll = function () {
return scope.allSelected() ? scope.unSelectAll() : scope.selectAll();
};
-
- scope.unSelectAll = function () {
- tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
- if(ctrl && ctrl.isSelected()) {
- ctrl.deselect();
+
+ /*
+ Updated this function
+ - to deselect all rows if the md-select-all attribute is visible and contains an array of ojects
+ - if md-select-all is undefined function will default to its orignal behaviour "select on rows on page"
+ */
+ scope.unSelectAll = function () {
+ tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
+ if (ctrl.model_allRows) {
+ ctrl.deselectAll();
+ }else if(ctrl && ctrl.isSelected()) {
+ ctrl.deselect();
}
});
};
-
+
scope.$watchGroup([enableRowSelection, tableCtrl.enableMultiSelect], function (newValue) {
if(newValue[0] !== oldValue[0]) {
if(newValue[0]) {
addCheckboxColumn();
-
+
if(newValue[1]) {
attatchCheckbox();
}
@@ -812,11 +826,11 @@ function mdHead($compile) {
detachCheckbox();
}
}
-
+
angular.copy(newValue, oldValue);
});
}
-
+
return {
bindToController: true,
compile: compile,
@@ -841,23 +855,27 @@ function mdRow() {
tElement.addClass('md-row');
return postLink;
}
-
+
function postLink(scope, element, attrs, tableCtrl) {
function enableRowSelection() {
return tableCtrl.$$rowSelect;
}
-
+
function isBodyRow() {
return tableCtrl.getBodyRows().indexOf(element[0]) !== -1;
}
-
+
+ function isAllRows() {
+ return scope.mdSelectAll;
+ }
+
function isChild(node) {
return element[0].contains(node[0]);
}
-
+
if(isBodyRow()) {
var cell = angular.element('');
-
+
scope.$watch(enableRowSelection, function (enable) {
// if a row is not selectable, prepend an empty cell to it
if(enable && !attrs.mdSelect) {
@@ -866,7 +884,7 @@ function mdRow() {
}
return;
}
-
+
if(isChild(cell)) {
cell.remove();
}
@@ -883,11 +901,14 @@ function mdRow() {
angular.module('md.data.table').directive('mdSelect', mdSelect);
-function mdSelect($compile, $parse) {
+function mdSelect($compile, $parse, $filter) {
// empty controller to bind scope properties to
- function Controller() {
-
+ function Controller() {
+ //Added this function which returns filtered array of objects
+ this.searchResults = function (data, searchText) {
+ return $filter('filter')(data, searchText);
+ }
}
function postLink(scope, element, attrs, ctrls) {
@@ -895,7 +916,17 @@ function mdSelect($compile, $parse) {
var tableCtrl = ctrls.shift();
var getId = $parse(attrs.mdSelectId);
+
self.id = getId(self.model);
+ /*
+ Added this function which
+ - returns filtered arrary of object from the searchResults function
+ - based on the list(json object) passed from the md-select-all atttribute
+ - and filters the list based on the text passed from the md-search atttribute
+ */
+ self.data = function () {
+ return self.searchResults(self.model_allRows, self.search);
+ }
if(tableCtrl.$$rowSelect && self.id) {
if(tableCtrl.$$hash.has(self.id)) {
@@ -925,8 +956,9 @@ function mdSelect($compile, $parse) {
});
}
}
-
- self.isSelected = function () {
+
+ //Added this opitional object argument when passed isSelected returns a boolean value based on the argument
+ self.isSelected = function (model) {
if(!tableCtrl.$$rowSelect) {
return false;
}
@@ -935,16 +967,18 @@ function mdSelect($compile, $parse) {
return tableCtrl.$$hash.has(self.id);
}
+ if (model) {
+ return tableCtrl.selected.indexOf(model) !== -1;
+ }
return tableCtrl.selected.indexOf(self.model) !== -1;
- };
+ };
self.select = function () {
if(self.disabled) {
return;
}
-
- if(tableCtrl.enableMultiSelect()) {
- tableCtrl.selected.push(self.model);
+ if (tableCtrl.enableMultiSelect()) {
+ tableCtrl.selected.push(self.model);
} else {
tableCtrl.selected.splice(0, tableCtrl.selected.length, self.model);
}
@@ -953,6 +987,44 @@ function mdSelect($compile, $parse) {
self.onSelect(self.model);
}
};
+
+ /*
+ Added this function which
+ - will select rows based on the array of objects returned from the data function
+ - will select all rows if the are not selected
+ */
+ self.selectAll = function () {
+ if (self.disabled) {
+ return;
+ }
+ if (tableCtrl.enableMultiSelect()) {
+ self.deselectAll();
+ angular.forEach(self.data(), function (model, key) {
+ if (!self.isSelected(model)) {
+ tableCtrl.selected.push(model);
+ }
+ });
+ } else {
+ tableCtrl.selected.splice(0, tableCtrl.selected.length, self.data());
+ }
+
+ if (angular.isFunction(self.onSelect)) {
+ self.onSelect(self.data());
+ }
+ }
+ /*
+ Added this function which
+ - will deselect rows based on the array of objects returned from the data function
+ - will deselect all rows if the are selected
+ */
+ self.deselectAll = function () {
+ angular.forEach(self.data(), function (model, index) {
+ if (self.isSelected(model))
+ {
+ tableCtrl.selected.splice(tableCtrl.selected.indexOf(model), 1);
+ }
+ });
+ }
self.deselect = function () {
if(self.disabled) {
@@ -1087,18 +1159,20 @@ function mdSelect($compile, $parse) {
disabled: '=ngDisabled',
onSelect: '=?mdOnSelect',
onDeselect: '=?mdOnDeselect',
- autoSelect: '=mdAutoSelect'
+ autoSelect: '=mdAutoSelect',
+ model_allRows: '=mdSelectAll',
+ search: '=mdSearch'
}
};
}
-mdSelect.$inject = ['$compile', '$parse'];
+mdSelect.$inject = ['$compile', '$parse','$filter'];
angular.module('md.data.table').directive('mdTable', mdTable);
function Hash() {
var keys = {};
-
+
this.equals = function (key, item) {
return keys[key] === item;
};
@@ -1106,7 +1180,7 @@ function Hash() {
this.get = function (key) {
return keys[key];
};
-
+
this.has = function (key) {
return keys.hasOwnProperty(key);
};
@@ -1114,145 +1188,145 @@ function Hash() {
this.purge = function (key) {
delete keys[key];
};
-
+
this.update = function (key, item) {
keys[key] = item;
};
}
function mdTable() {
-
+
function compile(tElement, tAttrs) {
tElement.addClass('md-table');
-
+
if(tAttrs.hasOwnProperty('mdProgress')) {
var body = tElement.find('tbody')[0];
var progress = angular.element('');
-
+
if(body) {
tElement[0].insertBefore(progress[0], body);
}
}
}
-
+
function Controller($attrs, $element, $q, $scope) {
var self = this;
var queue = [];
var watchListener;
var modelChangeListeners = [];
-
+
self.$$hash = new Hash();
self.$$columns = {};
-
+
function enableRowSelection() {
self.$$rowSelect = true;
-
+
watchListener = $scope.$watchCollection('$mdTable.selected', function (selected) {
modelChangeListeners.forEach(function (listener) {
listener(selected);
});
});
-
+
$element.addClass('md-row-select');
}
-
+
function disableRowSelection() {
self.$$rowSelect = false;
-
+
if(angular.isFunction(watchListener)) {
watchListener();
}
-
+
$element.removeClass('md-row-select');
}
-
+
function resolvePromises() {
if(!queue.length) {
return $scope.$applyAsync();
}
-
+
queue[0]['finally'](function () {
queue.shift();
resolvePromises();
});
}
-
+
function rowSelect() {
return $attrs.mdRowSelect === '' || self.rowSelect;
}
-
+
function validateModel() {
if(!self.selected) {
return console.error('Row selection: ngModel is not defined.');
}
-
+
if(!angular.isArray(self.selected)) {
return console.error('Row selection: Expected an array. Recived ' + typeof self.selected + '.');
}
-
+
return true;
}
-
+
self.columnCount = function () {
return self.getRows($element[0]).reduce(function (count, row) {
return row.cells.length > count ? row.cells.length : count;
}, 0);
};
-
+
self.getRows = function (element) {
- return Array.prototype.filter.call(element.rows, function (row) {
+ return Array.prototype.filter.call(element.rows, function (row) {
return !row.classList.contains('ng-leave');
});
};
-
+
self.getBodyRows = function () {
return Array.prototype.reduce.call($element.prop('tBodies'), function (result, tbody) {
return result.concat(self.getRows(tbody));
}, []);
};
-
+
self.getElement = function () {
return $element;
};
-
+
self.getHeaderRows = function () {
return self.getRows($element.prop('tHead'));
};
-
+
self.enableMultiSelect = function () {
return $attrs.multiple === '' || $scope.$eval($attrs.multiple);
};
-
+
self.waitingOnPromise = function () {
return !!queue.length;
};
-
+
self.queuePromise = function (promise) {
if(!promise) {
return;
}
-
+
if(queue.push(angular.isArray(promise) ? $q.all(promise) : $q.when(promise)) === 1) {
resolvePromises();
}
};
-
+
self.registerModelChangeListener = function (listener) {
modelChangeListeners.push(listener);
};
-
+
self.removeModelChangeListener = function (listener) {
var index = modelChangeListeners.indexOf(listener);
-
+
if(index !== -1) {
modelChangeListeners.splice(index, 1);
}
};
-
+
if($attrs.hasOwnProperty('mdProgress')) {
$scope.$watch('$mdTable.progress', self.queuePromise);
}
-
+
$scope.$watch(rowSelect, function (enable) {
if(enable && !!validateModel()) {
enableRowSelection();
@@ -1261,9 +1335,9 @@ function mdTable() {
}
});
}
-
+
Controller.$inject = ['$attrs', '$element', '$q', '$scope'];
-
+
return {
bindToController: true,
compile: compile,
@@ -1483,4 +1557,4 @@ function virtualPageSelect() {
};
}
-})(window, angular);
\ No newline at end of file
+})(window, angular);
diff --git a/src/scripts/mdHead.js b/src/scripts/mdHead.js
index 30984cb5..2a70c135 100644
--- a/src/scripts/mdHead.js
+++ b/src/scripts/mdHead.js
@@ -8,24 +8,24 @@ function mdHead($compile) {
tElement.addClass('md-head');
return postLink;
}
-
+
// empty controller to be bind scope properties to
function Controller() {
-
+
}
-
+
function postLink(scope, element, attrs, tableCtrl) {
// because scope.$watch is unpredictable
var oldValue = new Array(2);
-
+
function addCheckboxColumn() {
element.children().prepend('| ');
}
-
+
function attatchCheckbox() {
element.prop('lastElementChild').firstElementChild.appendChild($compile(createCheckBox())(scope)[0]);
}
-
+
function createCheckBox() {
return angular.element('').attr({
'aria-label': 'Select All',
@@ -34,68 +34,82 @@ function mdHead($compile) {
'ng-disabled': '!getSelectableRows().length'
});
}
-
+
function detachCheckbox() {
var cell = element.prop('lastElementChild').firstElementChild;
-
+
if(cell.classList.contains('md-checkbox-column')) {
angular.element(cell).empty();
}
}
-
+
function enableRowSelection() {
return tableCtrl.$$rowSelect;
}
-
+
function mdSelectCtrl(row) {
return angular.element(row).controller('mdSelect');
}
-
+
function removeCheckboxColumn() {
Array.prototype.some.call(element.find('th'), function (cell) {
return cell.classList.contains('md-checkbox-column') && cell.remove();
});
}
-
+
scope.allSelected = function () {
var rows = scope.getSelectableRows();
-
return rows.length && rows.every(function (row) {
return row.isSelected();
});
};
-
+
scope.getSelectableRows = function () {
return tableCtrl.getBodyRows().map(mdSelectCtrl).filter(function (ctrl) {
return ctrl && !ctrl.disabled;
});
};
-
- scope.selectAll = function () {
- tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
- if(ctrl && !ctrl.isSelected()) {
- ctrl.select();
+
+
+ /*
+ Updated this function
+ - to select all rows if the md-select-all attribute is visible and contains an array of ojects
+ - if md-select-all is undefined function will default to its orignal behaviour "select on rows on page"
+ */
+ scope.selectAll = function () {
+ tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
+ if (ctrl.model_allRows) {
+ ctrl.selectAll();
+ }else if(ctrl && !ctrl.isSelected()) {
+ ctrl.select();
}
});
};
-
+
scope.toggleAll = function () {
return scope.allSelected() ? scope.unSelectAll() : scope.selectAll();
};
-
- scope.unSelectAll = function () {
- tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
- if(ctrl && ctrl.isSelected()) {
- ctrl.deselect();
+
+ /*
+ Updated this function
+ - to deselect all rows if the md-select-all attribute is visible and contains an array of ojects
+ - if md-select-all is undefined function will default to its orignal behaviour "select on rows on page"
+ */
+ scope.unSelectAll = function () {
+ tableCtrl.getBodyRows().map(mdSelectCtrl).forEach(function (ctrl) {
+ if (ctrl.model_allRows) {
+ ctrl.deselectAll();
+ }else if(ctrl && ctrl.isSelected()) {
+ ctrl.deselect();
}
});
};
-
+
scope.$watchGroup([enableRowSelection, tableCtrl.enableMultiSelect], function (newValue) {
if(newValue[0] !== oldValue[0]) {
if(newValue[0]) {
addCheckboxColumn();
-
+
if(newValue[1]) {
attatchCheckbox();
}
@@ -109,11 +123,11 @@ function mdHead($compile) {
detachCheckbox();
}
}
-
+
angular.copy(newValue, oldValue);
});
}
-
+
return {
bindToController: true,
compile: compile,
diff --git a/src/scripts/mdSelect.js b/src/scripts/mdSelect.js
index 88ffda98..cc159d4a 100644
--- a/src/scripts/mdSelect.js
+++ b/src/scripts/mdSelect.js
@@ -2,11 +2,14 @@
angular.module('md.data.table').directive('mdSelect', mdSelect);
-function mdSelect($compile, $parse) {
+function mdSelect($compile, $parse, $filter) {
// empty controller to bind scope properties to
- function Controller() {
-
+ function Controller() {
+ //Added this function which returns filtered array of objects
+ this.searchResults = function (data, searchText) {
+ return $filter('filter')(data, searchText);
+ }
}
function postLink(scope, element, attrs, ctrls) {
@@ -14,7 +17,17 @@ function mdSelect($compile, $parse) {
var tableCtrl = ctrls.shift();
var getId = $parse(attrs.mdSelectId);
+
self.id = getId(self.model);
+ /*
+ Added this function which
+ - returns filtered arrary of object from the searchResults function
+ - based on the list(json object) passed from the md-select-all atttribute
+ - and filters the list based on the text passed from the md-search atttribute
+ */
+ self.data = function () {
+ return self.searchResults(self.model_allRows, self.search);
+ }
if(tableCtrl.$$rowSelect && self.id) {
if(tableCtrl.$$hash.has(self.id)) {
@@ -44,8 +57,9 @@ function mdSelect($compile, $parse) {
});
}
}
-
- self.isSelected = function () {
+
+ //Added this opitional object argument when passed isSelected returns a boolean value based on the argument
+ self.isSelected = function (model) {
if(!tableCtrl.$$rowSelect) {
return false;
}
@@ -54,16 +68,18 @@ function mdSelect($compile, $parse) {
return tableCtrl.$$hash.has(self.id);
}
+ if (model) {
+ return tableCtrl.selected.indexOf(model) !== -1;
+ }
return tableCtrl.selected.indexOf(self.model) !== -1;
- };
+ };
self.select = function () {
if(self.disabled) {
return;
}
-
- if(tableCtrl.enableMultiSelect()) {
- tableCtrl.selected.push(self.model);
+ if (tableCtrl.enableMultiSelect()) {
+ tableCtrl.selected.push(self.model);
} else {
tableCtrl.selected.splice(0, tableCtrl.selected.length, self.model);
}
@@ -72,6 +88,44 @@ function mdSelect($compile, $parse) {
self.onSelect(self.model);
}
};
+
+ /*
+ Added this function which
+ - will select rows based on the array of objects returned from the data function
+ - will select all rows if the are not selected
+ */
+ self.selectAll = function () {
+ if (self.disabled) {
+ return;
+ }
+ if (tableCtrl.enableMultiSelect()) {
+ self.deselectAll();
+ angular.forEach(self.data(), function (model, key) {
+ if (!self.isSelected(model)) {
+ tableCtrl.selected.push(model);
+ }
+ });
+ } else {
+ tableCtrl.selected.splice(0, tableCtrl.selected.length, self.data());
+ }
+
+ if (angular.isFunction(self.onSelect)) {
+ self.onSelect(self.data());
+ }
+ }
+ /*
+ Added this function which
+ - will deselect rows based on the array of objects returned from the data function
+ - will deselect all rows if the are selected
+ */
+ self.deselectAll = function () {
+ angular.forEach(self.data(), function (model, index) {
+ if (self.isSelected(model))
+ {
+ tableCtrl.selected.splice(tableCtrl.selected.indexOf(model), 1);
+ }
+ });
+ }
self.deselect = function () {
if(self.disabled) {
@@ -206,9 +260,11 @@ function mdSelect($compile, $parse) {
disabled: '=ngDisabled',
onSelect: '=?mdOnSelect',
onDeselect: '=?mdOnDeselect',
- autoSelect: '=mdAutoSelect'
+ autoSelect: '=mdAutoSelect',
+ model_allRows: '=mdSelectAll',
+ search: '=mdSearch'
}
};
}
-mdSelect.$inject = ['$compile', '$parse'];
\ No newline at end of file
+mdSelect.$inject = ['$compile', '$parse','$filter'];
\ No newline at end of file
diff --git a/src/scripts/mdTable.js b/src/scripts/mdTable.js
index 6b1f9635..5f96ccdc 100644
--- a/src/scripts/mdTable.js
+++ b/src/scripts/mdTable.js
@@ -4,7 +4,7 @@ angular.module('md.data.table').directive('mdTable', mdTable);
function Hash() {
var keys = {};
-
+
this.equals = function (key, item) {
return keys[key] === item;
};
@@ -12,7 +12,7 @@ function Hash() {
this.get = function (key) {
return keys[key];
};
-
+
this.has = function (key) {
return keys.hasOwnProperty(key);
};
@@ -20,13 +20,169 @@ function Hash() {
this.purge = function (key) {
delete keys[key];
};
-
+
this.update = function (key, item) {
keys[key] = item;
};
}
function mdTable() {
+
+ function compile(tElement, tAttrs) {
+ tElement.addClass('md-table');
+
+ if(tAttrs.hasOwnProperty('mdProgress')) {
+ var body = tElement.find('tbody')[0];
+ var progress = angular.element('');
+
+ if(body) {
+ tElement[0].insertBefore(progress[0], body);
+ }
+ }
+ }
+
+ function Controller($attrs, $element, $q, $scope) {
+ var self = this;
+ var queue = [];
+ var watchListener;
+ var modelChangeListeners = [];
+
+ self.$$hash = new Hash();
+ self.$$columns = {};
+
+ function enableRowSelection() {
+ self.$$rowSelect = true;
+
+ watchListener = $scope.$watchCollection('$mdTable.selected', function (selected) {
+ modelChangeListeners.forEach(function (listener) {
+ listener(selected);
+ });
+ });
+
+ $element.addClass('md-row-select');
+ }
+
+ function disableRowSelection() {
+ self.$$rowSelect = false;
+
+ if(angular.isFunction(watchListener)) {
+ watchListener();
+ }
+
+ $element.removeClass('md-row-select');
+ }
+
+ function resolvePromises() {
+ if(!queue.length) {
+ return $scope.$applyAsync();
+ }
+
+ queue[0]['finally'](function () {
+ queue.shift();
+ resolvePromises();
+ });
+ }
+
+ function rowSelect() {
+ return $attrs.mdRowSelect === '' || self.rowSelect;
+ }
+
+ function validateModel() {
+ if(!self.selected) {
+ return console.error('Row selection: ngModel is not defined.');
+ }
+
+ if(!angular.isArray(self.selected)) {
+ return console.error('Row selection: Expected an array. Recived ' + typeof self.selected + '.');
+ }
+
+ return true;
+ }
+
+ self.columnCount = function () {
+ return self.getRows($element[0]).reduce(function (count, row) {
+ return row.cells.length > count ? row.cells.length : count;
+ }, 0);
+ };
+
+ self.getRows = function (element) {
+ return Array.prototype.filter.call(element.rows, function (row) {
+ return !row.classList.contains('ng-leave');
+ });
+ };
+
+ self.getBodyRows = function () {
+ return Array.prototype.reduce.call($element.prop('tBodies'), function (result, tbody) {
+ return result.concat(self.getRows(tbody));
+ }, []);
+ };
+
+ self.getElement = function () {
+ return $element;
+ };
+
+ self.getHeaderRows = function () {
+ return self.getRows($element.prop('tHead'));
+ };
+
+ self.enableMultiSelect = function () {
+ return $attrs.multiple === '' || $scope.$eval($attrs.multiple);
+ };
+
+ self.waitingOnPromise = function () {
+ return !!queue.length;
+ };
+
+ self.queuePromise = function (promise) {
+ if(!promise) {
+ return;
+ }
+
+ if(queue.push(angular.isArray(promise) ? $q.all(promise) : $q.when(promise)) === 1) {
+ resolvePromises();
+ }
+ };
+
+ self.registerModelChangeListener = function (listener) {
+ modelChangeListeners.push(listener);
+ };
+
+ self.removeModelChangeListener = function (listener) {
+ var index = modelChangeListeners.indexOf(listener);
+
+ if(index !== -1) {
+ modelChangeListeners.splice(index, 1);
+ }
+ };
+
+ if($attrs.hasOwnProperty('mdProgress')) {
+ $scope.$watch('$mdTable.progress', self.queuePromise);
+ }
+
+ $scope.$watch(rowSelect, function (enable) {
+ if(enable && !!validateModel()) {
+ enableRowSelection();
+ } else {
+ disableRowSelection();
+ }
+ });
+ }
+
+ Controller.$inject = ['$attrs', '$element', '$q', '$scope'];
+
+ return {
+ bindToController: true,
+ compile: compile,
+ controller: Controller,
+ controllerAs: '$mdTable',
+ restrict: 'A',
+ scope: {
+ progress: '=?mdProgress',
+ selected: '=ngModel',
+ rowSelect: '=mdRowSelect'
+ }
+ };
+}
function compile(tElement, tAttrs) {
tElement.addClass('md-table');
| |