From b61a9f1d249ffe5593712b7e4a3c2359a5d22c37 Mon Sep 17 00:00:00 2001 From: Laszlo Radics Date: Sat, 3 Aug 2013 22:22:24 +0200 Subject: [PATCH] 1. data-model chenged to ng-model (issue #27) 2. sort state fix (issue #24) 3. scope is now inherited (issue #8) 4. less verbose markup (sort-arrow-ascending and sort-arrow-descending are optional markup) --- src/main/webapp/js/lib/angular-table.js | 84 +++++++++++-------------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/src/main/webapp/js/lib/angular-table.js b/src/main/webapp/js/lib/angular-table.js index 7663223..92746e8 100644 --- a/src/main/webapp/js/lib/angular-table.js +++ b/src/main/webapp/js/lib/angular-table.js @@ -1,13 +1,12 @@ angular.module('angular-table', []) - .directive('angularTable', ['SortState', 'TemplateStaticState', - function(SortState, TemplateStaticState) { + .directive('angularTable', ['TemplateStaticState', + function(TemplateStaticState) { return { // only support elements for now to simplify the manual transclusion and replace logic. restrict: 'E', // manually transclude and replace the template to work around not being able to have a template with td or tr as a root element // see bug: https://github.com/angular/angular.js/issues/1459 compile: function (tElement, tAttrs) { - SortState.sortExpression = tAttrs.defaultSortColumn; TemplateStaticState.instrumentationEnabled = tAttrs.instrumentationEnabled; // find whatever classes were passed into the angular-table, and merge them with the built in classes for the container div @@ -18,31 +17,29 @@ angular.module('angular-table', []) tElement.replaceWith(rowTemplate); // return linking function - return function(scope) { - scope.parent = scope.$parent; + return function(scope, element, attrs, controller) { + scope.sortState = { + sortExpression : attrs.defaultSortColumn, + sortDirectionToColumnMap : {}, + setSortExpression : function(columnName) { + var s = scope.sortState; + s.sortExpression = columnName; + + // track sort directions by sorted column for a better ux + s.sortDirectionToColumnMap[s.sortExpression] = !s.sortDirectionToColumnMap[s.sortExpression]; + } + }; + scope.$watch(attrs.ngModel,function(value){scope.model = value}); + scope.$watch(attrs.filterQueryModel,function(value){scope.filterQueryModel = value}); }; - }, - scope: { - model: '=', - filterQueryModel: '=' } }; }]) - .directive('headerRow', ['ManualCompiler', 'ScrollingContainerHeightState', 'JqLiteExtension', 'SortState', 'ResizeHeightEvent', 'ResizeWidthEvent', 'Instrumentation', - function(ManualCompiler, ScrollingContainerHeightState, JqLiteExtension, SortState, ResizeHeightEvent, ResizeWidthEvent, Instrumentation) { + .directive('headerRow', ['ManualCompiler', 'ScrollingContainerHeightState', 'JqLiteExtension', 'ResizeHeightEvent', 'ResizeWidthEvent', 'Instrumentation', + function(ManualCompiler, ScrollingContainerHeightState, JqLiteExtension, ResizeHeightEvent, ResizeWidthEvent, Instrumentation) { return { // only support elements for now to simplify the manual transclusion and replace logic. restrict: 'E', - controller: ['$scope', '$parse', function($scope, $parse) { - $scope.SortState = SortState; - - $scope.setSortExpression = function(columnName) { - SortState.sortExpression = columnName; - - // track sort directions by sorted column for a better ux - SortState.sortDirectionToColumnMap[SortState.sortExpression] = !SortState.sortDirectionToColumnMap[SortState.sortExpression]; - }; - }], // manually transclude and replace the template to work around not being able to have a template with td or tr as a root element // see bug: https://github.com/angular/angular.js/issues/1459 compile: function (tElement, tAttrs) { @@ -67,16 +64,14 @@ angular.module('angular-table', []) } }; }]) - .directive('row', ['ManualCompiler', 'ResizeHeightEvent', '$window', 'Debounce', 'TemplateStaticState', 'RowState', 'SortState', + .directive('row', ['ManualCompiler', 'ResizeHeightEvent', '$window', 'Debounce', 'TemplateStaticState', 'RowState', 'ScrollingContainerHeightState', 'JqLiteExtension', 'Instrumentation', 'ResizeWidthEvent', '$compile', - function(ManualCompiler, ResizeHeightEvent, $window, Debounce, TemplateStaticState, RowState, SortState, ScrollingContainerHeightState, + function(ManualCompiler, ResizeHeightEvent, $window, Debounce, TemplateStaticState, RowState, ScrollingContainerHeightState, JqLiteExtension, Instrumentation, ResizeWidthEvent, $compile) { return { // only support elements for now to simplify the manual transclusion and replace logic. restrict: 'E', controller: ['$scope', function($scope) { - $scope.sortExpression = SortState.sortExpression; - $scope.handleClick = function(row, parentScopeClickHandler, selectedRowBackgroundColor) { var clickHandlerFunctionName = parentScopeClickHandler.replace('(row)', ''); @@ -115,7 +110,6 @@ angular.module('angular-table', []) // return a linking function return function(scope, iElement) { scope.ScrollingContainerHeightState = ScrollingContainerHeightState; - scope.SortState = SortState; var getHeaderComputedHeight = function() { return JqLiteExtension.getComputedHeightAsFloat(iElement.parent()[0]); @@ -163,7 +157,7 @@ angular.module('angular-table', []) // scroll to top when sort applied // watches get called n times until the model settles. it's typically one or two, but processing in the functions // must be idempotent and as such shouldn't rely on it being any specific number. - scope.$watch('SortState', function() { + scope.$watch('sortState', function() { iElement[0].scrollTop = 0; }, true); @@ -261,18 +255,24 @@ angular.module('angular-table', []) angular.forEach(tElement.children(), function(childColumn, index) { if(angular.element(childColumn).attr('sortable') === 'true') { // add the ascending sort icon - angular.element(childColumn).find('sort-arrow-descending').attr('ng-show', - 'SortState.sortExpression == \'' + angular.element(childColumn).attr('sort-field-name') + - '\' && !SortState.sortDirectionToColumnMap[\'' + angular.element(childColumn).attr('sort-field-name') + '\']').addClass('angularTableDefaultSortArrowAscending'); + var $sortdesc = angular.element(childColumn).find('sort-arrow-descending'); + if ($sortdesc.length == 0) + $sortdesc = $('
').appendTo(angular.element(childColumn)); + $sortdesc.attr('ng-show', + 'sortState.sortExpression == \'' + angular.element(childColumn).attr('sort-field-name') + + '\' && !sortState.sortDirectionToColumnMap[\'' + angular.element(childColumn).attr('sort-field-name') + '\']').addClass('angularTableDefaultSortArrowAscending'); // add the descending sort icon - angular.element(childColumn).find('sort-arrow-ascending').attr('ng-show', - 'SortState.sortExpression == \'' + angular.element(childColumn).attr('sort-field-name') + - '\' && SortState.sortDirectionToColumnMap[\'' + angular.element(childColumn).attr('sort-field-name') + '\']').addClass('angularTableDefaultSortArrowDescending'); + var $sortasc = angular.element(childColumn).find('sort-arrow-ascending'); + if ($sortasc.length == 0) + $sortasc = $('
').appendTo(angular.element(childColumn)); + $sortasc.attr('ng-show', + 'sortState.sortExpression == \'' + angular.element(childColumn).attr('sort-field-name') + + '\' && sortState.sortDirectionToColumnMap[\'' + angular.element(childColumn).attr('sort-field-name') + '\']').addClass('angularTableDefaultSortArrowDescending'); // add the sort click handler - angular.element(childColumn).attr('ng-click', 'setSortExpression(\'' + - angular.element(childColumn).attr('sort-field-name') + '\')'); + angular.element(childColumn).attr('ng-click', 'sortState.setSortExpression(\'' + + angular.element(childColumn).attr('sort-field-name') + '\')'); // remove the sort field name attribute from the dsl angular.element(childColumn).removeAttr('sort-field-name'); @@ -316,7 +316,7 @@ angular.module('angular-table', []) // add the ng-repeat and row selection click handler to each row rowTemplate = rowTemplate.replace('