Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
Solutions for issues #16 and #18
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Nagy authored and Daniel Nagy committed Jun 24, 2015
1 parent 951a6f2 commit 141aa5d
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 110 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ angular.module('nutritionApp').controller('nutritionController', ['$nutrition',

## Change Log

**Version 0.4.5**

* Improvement: You must now explicitly place an `orderBy` attribute on a header cell to enable sorting on that column. This allows for a combination of columns that are sortable and not sortable.

* Improvement: you may now use `ngRepeat` on header cells with column ordering.

**Version 0.4.4**

* Bug Fix: When the number of rows per page is changed, pagination will now decrement the page until the min value is less than the total number of items or the page is zero.
Expand Down Expand Up @@ -159,13 +165,13 @@ Column names will be shortened if they exceed the width of the cell minus the `5
| :--------------------- | :-------- | :------- | :---------- |
| `md-order` | `<thead>` | `String` | Two-way data binding filter. |

The filter will update when the user clicks on a `<th>` cell. The filter will take on the value supplied to the `order-by` attribute or the cell's inner text. The filter can be used in to do manual sorting or automatic sorting.
The `mdOrder` attribute will be update when the user clicks a `<th>` cell to the value defined by the `order-by` attribute. The `mdOrder` attribute can be used in to do server-side sorting or client-side sorting.

> This directive does not support filtering of in-place data, i.e. data included directly in the markup, nor do I plan on supporting this.
> This directive does not support sorting of in-place data, i.e. data included directly in the markup, nor do I plan on supporting this.
##### Server Side Ordering

The provided usage example takes advantage of manual sorting by submitting a query to the server.
The provided usage example takes advantage of server-side sorting by submitting a query to the server.

##### Client Side Ordering

Expand All @@ -177,7 +183,7 @@ Just add an `orderBy:` property to the `ng-repeat` attribute that matches the `m
<thead md-order="order">
<!-- this cell will order by the name property -->
<th order-by="name">Dessert (100g serving)</th>
<!-- this cell will order by the calories property -->
<!-- this cell will not change the order when clicked -->
<th numeric>Calories</th>
</thead>
<tbody>
Expand Down
118 changes: 72 additions & 46 deletions app/md-data-table/scripts/mdDataTableHeadDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,6 @@ angular.module('md.data.table').directive('mdTableHead', ['$document', '$mdTable

function postLink(scope, element, attrs, ctrl) {

// column filtering
if(attrs.mdOrder) {
scope.$parent.isActive = function (prop) {
return scope.order === prop || scope.order === '-' + prop;
};

scope.$parent.orderBy = function (prop) {
scope.order = scope.order === prop ? '-' + prop : prop;
};

scope.$parent.getDirection = function (prop) {
if(scope.$parent.isActive(prop)) {
return scope.order[0] === '-' ? 'down' : 'up';
}
return 'up';
};
}

// row selection
if(element.parent().attr('md-row-select')) {
scope.$parent.allSelected = function (items) {
Expand Down Expand Up @@ -103,32 +85,6 @@ angular.module('md.data.table').directive('mdTableHead', ['$document', '$mdTable
if(iAttrs.hasOwnProperty('mdTrimColumnNames')) {
cell.innerHTML = '<trim>' + cell.innerHTML + '</trim>';
}

// enable column filtering
if(iAttrs.mdOrder) {
var orderBy = cell.getAttribute('order-by');

// use the cell's text as the filter property
if(!orderBy) {
cell.setAttribute('order-by', orderBy = cell.textContent.toLowerCase());
}

cell.setAttribute('ng-class', '{\'md-active\': isActive(\'' + orderBy + '\')}');
cell.setAttribute('ng-click', 'orderBy(\'' + orderBy + '\')');

var sortIcon = angular.element('<md-icon></md-icon>');

sortIcon.attr('md-svg-icon', 'templates.arrow.html');
sortIcon.attr('ng-class', 'getDirection(\'' + orderBy + '\')');

if(cell.hasAttribute('numeric')) {
angular.element(cell).prepend(sortIcon);
} else {
angular.element(cell).append(sortIcon);
}

cell.innerHTML = '<div>' + cell.innerHTML + '</div>';
}
});

// ensures a minimum width of 64px for column names
Expand Down Expand Up @@ -165,10 +121,80 @@ angular.module('md.data.table').directive('mdTableHead', ['$document', '$mdTable
}

return {
require: '^mdDataTable',
scope: {
bindToController: {
order: '=mdOrder'
},
controller: function () {},
controllerAs: 'ctrl',
require: '^mdDataTable',
scope: {},
compile: compile
};
}])

.directive('orderBy', ['$interpolate', function ($interpolate) {
'use strict';

function template(tElement) {
return '<th ng-click="setOrder()" ng-class="{\'md-active\': isActive()}">' + tElement.html() + '</th>';
}

function postLink(scope, element, attrs, ctrl) {

if(element.text().match(/{{[^}]+}}/)) {
var text = $interpolate('\'' + element.text() + '\'')(scope.$parent);
var trim = element.find('trim');

if(trim.length) {
trim.text(text.slice(1, -1));
} else if(angular.isDefined(attrs.numeric)) {
element.find('div').append(text.slice(1, -1));
} else {
element.find('div').prepend(text.slice(1, -1));
}
}

scope.getDirection = function () {
if(scope.isActive()) {
return ctrl.order[0] === '-' ? 'down' : 'up';
}
return 'up';
};

scope.isActive = function () {
return ctrl.order === scope.order || ctrl.order === '-' + scope.order;
};

scope.setOrder = function () {
ctrl.order = ctrl.order === scope.order ? '-' + scope.order : scope.order;
};
}

function compile(tElement, tAttrs) {
var sortIcon = angular.element('<md-icon></md-icon>');

sortIcon.attr('md-svg-icon', 'templates.arrow.html');
sortIcon.attr('ng-class', 'getDirection()');

if(angular.isDefined(tAttrs.numeric)) {
tElement.prepend(sortIcon);
} else {
tElement.append(sortIcon);
}

tElement.html('<div>' + tElement.html() + '</div>');

return postLink;
}

return {
compile: compile,
replace: true,
require: '^mdTableHead',
restrict: 'A',
scope: {
order: '@orderBy'
},
template: template
};
}]);
2 changes: 1 addition & 1 deletion app/md-data-table/styles/md-data-table-head.less
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ table[md-data-table] > thead {
fill: transparent;
}

&[md-order] > tr > th {
&[md-order] > tr > th[order-by] {
transition: color 0.25s;

&:hover {
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-material-data-table",
"version": "0.4.3",
"version": "0.4.5",
"description": "Material Design data table.",
"main": [
"dist/md-data-table.min.js",
Expand Down
18 changes: 9 additions & 9 deletions dist/md-data-table.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,25 +60,25 @@ table[md-data-table] > thead[md-order][md-trim-column-names] > tr > th:not(.md-a
table[md-data-table] > thead[md-order]:not([md-trim-column-names]) > tr > th:not(.md-active):not(:hover) > div > md-icon {
fill: transparent;
}
table[md-data-table] > thead[md-order] > tr > th {
table[md-data-table] > thead[md-order] > tr > th[order-by] {
transition: color 0.25s;
}
table[md-data-table] > thead[md-order] > tr > th:hover {
table[md-data-table] > thead[md-order] > tr > th[order-by]:hover {
color: rgba(0, 0, 0, 0.87);
cursor: pointer;
}
table[md-data-table] > thead[md-order] > tr > th[numeric] > div {
table[md-data-table] > thead[md-order] > tr > th[order-by][numeric] > div {
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
justify-content: flex-end;
}
table[md-data-table] > thead[md-order] > tr > th.md-active > div > md-icon {
table[md-data-table] > thead[md-order] > tr > th[order-by].md-active > div > md-icon {
fill: rgba(0, 0, 0, 0.87);
}
table[md-data-table] > thead[md-order] > tr > th:not(.md-active) > div > md-icon {
table[md-data-table] > thead[md-order] > tr > th[order-by]:not(.md-active) > div > md-icon {
fill: rgba(0, 0, 0, 0.26);
}
table[md-data-table] > thead[md-order] > tr > th > div {
table[md-data-table] > thead[md-order] > tr > th[order-by] > div {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
Expand All @@ -87,7 +87,7 @@ table[md-data-table] > thead[md-order] > tr > th > div {
align-items: center;
line-height: 18px;
}
table[md-data-table] > thead[md-order] > tr > th > div > md-icon {
table[md-data-table] > thead[md-order] > tr > th[order-by] > div > md-icon {
-webkit-flex: 0 0 auto;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
Expand All @@ -97,11 +97,11 @@ table[md-data-table] > thead[md-order] > tr > th > div > md-icon {
transition: fill 0.25s, -webkit-transform 0.25s;
transition: fill 0.25s, transform 0.25s;
}
table[md-data-table] > thead[md-order] > tr > th > div > md-icon.down {
table[md-data-table] > thead[md-order] > tr > th[order-by] > div > md-icon.down {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
table[md-data-table] > thead[md-order] > tr > th > div > md-icon.up {
table[md-data-table] > thead[md-order] > tr > th[order-by] > div > md-icon.up {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
Expand Down
118 changes: 72 additions & 46 deletions dist/md-data-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,24 +202,6 @@ angular.module('md.data.table').directive('mdTableHead', ['$document', '$mdTable

function postLink(scope, element, attrs, ctrl) {

// column filtering
if(attrs.mdOrder) {
scope.$parent.isActive = function (prop) {
return scope.order === prop || scope.order === '-' + prop;
};

scope.$parent.orderBy = function (prop) {
scope.order = scope.order === prop ? '-' + prop : prop;
};

scope.$parent.getDirection = function (prop) {
if(scope.$parent.isActive(prop)) {
return scope.order[0] === '-' ? 'down' : 'up';
}
return 'up';
};
}

// row selection
if(element.parent().attr('md-row-select')) {
scope.$parent.allSelected = function (items) {
Expand Down Expand Up @@ -301,32 +283,6 @@ angular.module('md.data.table').directive('mdTableHead', ['$document', '$mdTable
if(iAttrs.hasOwnProperty('mdTrimColumnNames')) {
cell.innerHTML = '<trim>' + cell.innerHTML + '</trim>';
}

// enable column filtering
if(iAttrs.mdOrder) {
var orderBy = cell.getAttribute('order-by');

// use the cell's text as the filter property
if(!orderBy) {
cell.setAttribute('order-by', orderBy = cell.textContent.toLowerCase());
}

cell.setAttribute('ng-class', '{\'md-active\': isActive(\'' + orderBy + '\')}');
cell.setAttribute('ng-click', 'orderBy(\'' + orderBy + '\')');

var sortIcon = angular.element('<md-icon></md-icon>');

sortIcon.attr('md-svg-icon', 'templates.arrow.html');
sortIcon.attr('ng-class', 'getDirection(\'' + orderBy + '\')');

if(cell.hasAttribute('numeric')) {
angular.element(cell).prepend(sortIcon);
} else {
angular.element(cell).append(sortIcon);
}

cell.innerHTML = '<div>' + cell.innerHTML + '</div>';
}
});

// ensures a minimum width of 64px for column names
Expand Down Expand Up @@ -363,12 +319,82 @@ angular.module('md.data.table').directive('mdTableHead', ['$document', '$mdTable
}

return {
require: '^mdDataTable',
scope: {
bindToController: {
order: '=mdOrder'
},
controller: function () {},
controllerAs: 'ctrl',
require: '^mdDataTable',
scope: {},
compile: compile
};
}])

.directive('orderBy', ['$interpolate', function ($interpolate) {
'use strict';

function template(tElement) {
return '<th ng-click="setOrder()" ng-class="{\'md-active\': isActive()}">' + tElement.html() + '</th>';
}

function postLink(scope, element, attrs, ctrl) {

if(element.text().match(/{{[^}]+}}/)) {
var text = $interpolate('\'' + element.text() + '\'')(scope.$parent);
var trim = element.find('trim');

if(trim.length) {
trim.text(text.slice(1, -1));
} else if(angular.isDefined(attrs.numeric)) {
element.find('div').append(text.slice(1, -1));
} else {
element.find('div').prepend(text.slice(1, -1));
}
}

scope.getDirection = function () {
if(scope.isActive()) {
return ctrl.order[0] === '-' ? 'down' : 'up';
}
return 'up';
};

scope.isActive = function () {
return ctrl.order === scope.order || ctrl.order === '-' + scope.order;
};

scope.setOrder = function () {
ctrl.order = ctrl.order === scope.order ? '-' + scope.order : scope.order;
};
}

function compile(tElement, tAttrs) {
var sortIcon = angular.element('<md-icon></md-icon>');

sortIcon.attr('md-svg-icon', 'templates.arrow.html');
sortIcon.attr('ng-class', 'getDirection()');

if(angular.isDefined(tAttrs.numeric)) {
tElement.prepend(sortIcon);
} else {
tElement.append(sortIcon);
}

tElement.html('<div>' + tElement.html() + '</div>');

return postLink;
}

return {
compile: compile,
replace: true,
require: '^mdTableHead',
restrict: 'A',
scope: {
order: '@orderBy'
},
template: template
};
}]);

angular.module('md.data.table').directive('mdDataTablePagination', function () {
Expand Down
Loading

0 comments on commit 141aa5d

Please sign in to comment.