diff --git a/README.md b/README.md index aa8c0cbb88..fe0f73689b 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,8 @@ There is a task for CI testing with PhantomJS ## Change Log -* __2013-03-29__ - Version 2.0.3 - fixing some more minor bugs. +* __2013-04-23__ - Version 2.0.5 - Moving to $http for external template fetching. Should fix issues with grid rendering before templates are retrieved, as well as fetching the same template multiple times. Also fixed bug that prevented the grid from maintaining row selections post-sort thanks to [sum4me](https://github.com/sum4me). +* __2013-04-08__ - Version 2.0.4 - fixing some more minor bugs. * __2013-03-29__ - Version 2.0.3 - changed default multiSelect behavior, updating some plugins and making some more minor bugfixes. * __2013-03-08__ - Version 2.0.2 - minor bugfixes, updating some plugins. * __2013-03-05__ - Version 2.0.1 - Moved to grunt build system. No more international version; all languages are included by default. Fixed minor grouping display issue. Using $templateCache for templates instead of global namespace. diff --git a/build/ng-grid.debug.js b/build/ng-grid.debug.js index e2929285bb..1ab885515c 100644 --- a/build/ng-grid.debug.js +++ b/build/ng-grid.debug.js @@ -2,7 +2,7 @@ * ng-grid JavaScript Library * Authors: https://github.com/angular-ui/ng-grid/blob/master/README.md * License: MIT (http://www.opensource.org/licenses/mit-license.php) -* Compiled At: 04/16/2013 15:21 +* Compiled At: 04/23/2013 14:36 ***********************************************/ (function(window, $) { 'use strict'; @@ -1196,7 +1196,7 @@ var ngFooter = function ($scope, grid) { /// /// /// -var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse) { +var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse, $http, $q) { var defaults = { //Define an aggregate template to customize the rows when grouped. See github wiki for more details. aggregateTemplate: undefined, @@ -1410,32 +1410,46 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, self.data = []; self.lateBindColumns = false; self.filteredRows = []; + + self.initTemplates = function() { + var templates = ['rowTemplate', 'aggregateTemplate', 'headerRowTemplate', 'checkboxCellTemplate', 'checkboxHeaderTemplate', 'menuTemplate', 'footerTemplate']; + + var promises = []; + templates.forEach(function(template) { + promises.push( self.getTemplate(template) ); + }); + + return $q.all(promises); + }; //Templates // test templates for urls and get the tempaltes via synchronous ajax calls - var getTemplate = function (key) { + self.getTemplate = function (key) { var t = self.config[key]; var uKey = self.gridId + key + ".html"; + var p = $q.defer(); if (t && !TEMPLATE_REGEXP.test(t)) { - $templateCache.put(uKey, $.ajax({ - type: "GET", - url: t, - async: false - }).responseText); + $http.get(t, { + cache: $templateCache + }) + .success(function(data){ + $templateCache.put(uKey, data); + p.resolve(); + }) + .error(function(err){ + p.reject("Could not load template: " + t); + }); } else if (t) { $templateCache.put(uKey, t); + p.resolve(); } else { var dKey = key + ".html"; $templateCache.put(uKey, $templateCache.get(dKey)); + p.resolve(); } + + return p.promise; }; - getTemplate('rowTemplate'); - getTemplate('aggregateTemplate'); - getTemplate('headerRowTemplate'); - getTemplate('checkboxCellTemplate'); - getTemplate('checkboxHeaderTemplate'); - getTemplate('menuTemplate'); - getTemplate('footerTemplate'); if (typeof self.config.data == "object") { self.data = self.config.data; // we cannot watch for updates if you don't pass the string name @@ -1637,35 +1651,41 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, } }; self.init = function() { - //factories and services - $scope.selectionProvider = new ngSelectionProvider(self, $scope, $parse); - $scope.domAccessProvider = new ngDomAccessProvider(self); - self.rowFactory = new ngRowFactory(self, $scope, domUtilityService, $templateCache, $utils); - self.searchProvider = new ngSearchProvider($scope, self, $filter); - self.styleProvider = new ngStyleProvider($scope, self); - $scope.$watch('configGroups', function(a) { - var tempArr = []; - angular.forEach(a, function(item) { - tempArr.push(item.field || item); - }); - self.config.groups = tempArr; - self.rowFactory.filteredRowsChanged(); - $scope.$emit('ngGridEventGroups', a); - }, true); - $scope.$watch('columns', function (a) { - domUtilityService.BuildStyles($scope, self, true); - $scope.$emit('ngGridEventColumns', a); - }, true); - $scope.$watch(function() { - return options.i18n; - }, function(newLang) { - $utils.seti18n($scope, newLang); + return self.initTemplates().then(function(){ + //factories and services + $scope.selectionProvider = new ngSelectionProvider(self, $scope, $parse); + $scope.domAccessProvider = new ngDomAccessProvider(self); + self.rowFactory = new ngRowFactory(self, $scope, domUtilityService, $templateCache, $utils); + self.searchProvider = new ngSearchProvider($scope, self, $filter); + self.styleProvider = new ngStyleProvider($scope, self); + $scope.$watch('configGroups', function(a) { + var tempArr = []; + angular.forEach(a, function(item) { + tempArr.push(item.field || item); + }); + self.config.groups = tempArr; + self.rowFactory.filteredRowsChanged(); + $scope.$emit('ngGridEventGroups', a); + }, true); + $scope.$watch('columns', function (a) { + domUtilityService.BuildStyles($scope, self, true); + $scope.$emit('ngGridEventColumns', a); + }, true); + $scope.$watch(function() { + return options.i18n; + }, function(newLang) { + $utils.seti18n($scope, newLang); + }); + self.maxCanvasHt = self.calcMaxCanvasHeight(); + if (self.config.sortInfo.fields && self.config.sortInfo.fields.length > 0) { + self.getColsFromFields(); + self.sortActual(); + } }); - self.maxCanvasHt = self.calcMaxCanvasHeight(); - if (self.config.sortInfo.fields && self.config.sortInfo.fields.length > 0) { - self.getColsFromFields(); - self.sortActual(); - } + + // var p = $q.defer(); + // p.resolve(); + // return p.promise; }; self.resizeOnData = function(col) { @@ -1760,7 +1780,7 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, angular.forEach(tempData, function(item, i) { var e = self.rowMap[i]; if (e != undefined) { - var v = self.rowCache[v]; + var v = self.rowCache[i]; if(v != undefined) { item.preSortSelected = v.selected; item.preSortIndex = i; @@ -2008,8 +2028,6 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, } return newDim; }; - //call init - self.init(); }; var ngRange = function (top, bottom) { @@ -2799,7 +2817,7 @@ ngGridDirectives.directive('ngGridMenu', ['$compile', '$templateCache', function }; return ngGridMenu; }]); -ngGridDirectives.directive('ngGrid', ['$compile', '$filter', '$templateCache', '$sortService', '$domUtilityService', '$utilityService', '$timeout', '$parse', function ($compile, $filter, $templateCache, sortService, domUtilityService, $utils, $timeout, $parse) { +ngGridDirectives.directive('ngGrid', ['$compile', '$filter', '$templateCache', '$sortService', '$domUtilityService', '$utilityService', '$timeout', '$parse', '$http', '$q', function ($compile, $filter, $templateCache, sortService, domUtilityService, $utils, $timeout, $parse, $http, $q) { var ngGridDirective = { scope: true, compile: function() { @@ -2808,138 +2826,140 @@ ngGridDirectives.directive('ngGrid', ['$compile', '$filter', '$templateCache', ' var $element = $(iElement); var options = $scope.$eval(iAttrs.ngGrid); options.gridDim = new ngDimension({ outerHeight: $($element).height(), outerWidth: $($element).width() }); - var grid = new ngGrid($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse); - // if columndefs are a string of a property ont he scope watch for changes and rebuild columns. - if (typeof options.columnDefs == "string") { - $scope.$parent.$watch(options.columnDefs, function (a) { - if (!a) { - grid.refreshDomSizes(); + var grid = new ngGrid($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse, $http, $q); + return grid.init().then(function() { + // if columndefs are a string of a property ont he scope watch for changes and rebuild columns. + if (typeof options.columnDefs == "string") { + $scope.$parent.$watch(options.columnDefs, function (a) { + if (!a) { + grid.refreshDomSizes(); + grid.buildColumns(); + return; + } + // we have to set this to false in case we want to autogenerate columns with no initial data. + grid.lateBoundColumns = false; + $scope.columns = []; + grid.config.columnDefs = a; grid.buildColumns(); - return; - } - // we have to set this to false in case we want to autogenerate columns with no initial data. - grid.lateBoundColumns = false; - $scope.columns = []; - grid.config.columnDefs = a; - grid.buildColumns(); - grid.configureColumnWidths(); - grid.eventProvider.assignEvents(); - domUtilityService.RebuildGrid($scope, grid); - }, true); - } else { - grid.buildColumns(); - } - - // if it is a string we can watch for data changes. otherwise you won't be able to update the grid data - if (typeof options.data == "string") { - var dataWatcher = function (a) { - // make a temporary copy of the data - grid.data = $.extend([], a); - grid.rowFactory.fixRowCache(); - angular.forEach(grid.data, function (item, j) { - var indx = grid.rowMap[j] || j; - if (grid.rowCache[indx]) { - grid.rowCache[indx].ensureEntity(item); + grid.configureColumnWidths(); + grid.eventProvider.assignEvents(); + domUtilityService.RebuildGrid($scope, grid); + }, true); + } else { + grid.buildColumns(); + } + + // if it is a string we can watch for data changes. otherwise you won't be able to update the grid data + if (typeof options.data == "string") { + var dataWatcher = function (a) { + // make a temporary copy of the data + grid.data = $.extend([], a); + grid.rowFactory.fixRowCache(); + angular.forEach(grid.data, function (item, j) { + var indx = grid.rowMap[j] || j; + if (grid.rowCache[indx]) { + grid.rowCache[indx].ensureEntity(item); + } + grid.rowMap[indx] = j; + }); + grid.searchProvider.evalFilter(); + grid.configureColumnWidths(); + grid.refreshDomSizes(); + if (grid.config.sortInfo.fields.length > 0) { + grid.getColsFromFields(); + grid.sortActual(); + grid.searchProvider.evalFilter(); + $scope.$emit('ngGridEventSorted', grid.config.sortInfo); } - grid.rowMap[indx] = j; + $scope.$emit("ngGridEventData", grid.gridId); + }; + $scope.$parent.$watch(options.data, dataWatcher); + $scope.$parent.$watch(options.data + '.length', function() { + dataWatcher($scope.$eval(options.data)); }); - grid.searchProvider.evalFilter(); - grid.configureColumnWidths(); - grid.refreshDomSizes(); - if (grid.config.sortInfo.fields.length > 0) { - grid.getColsFromFields(); - grid.sortActual(); - grid.searchProvider.evalFilter(); - $scope.$emit('ngGridEventSorted', grid.config.sortInfo); + } + + grid.footerController = new ngFooter($scope, grid); + //set the right styling on the container + iElement.addClass("ngGrid").addClass(grid.gridId.toString()); + if (!options.enableHighlighting) { + iElement.addClass("unselectable"); + } + if (options.jqueryUITheme) { + iElement.addClass('ui-widget'); + } + iElement.append($compile($templateCache.get('gridTemplate.html'))($scope)); // make sure that if any of these change, we re-fire the calc logic + //walk the element's graph and the correct properties on the grid + domUtilityService.AssignGridContainers($scope, iElement, grid); + //now use the manager to assign the event handlers + grid.eventProvider = new ngEventProvider(grid, $scope, domUtilityService, $timeout); + + // method for user to select a specific row programatically + options.selectRow = function (rowIndex, state) { + if (grid.rowCache[rowIndex]) { + if (grid.rowCache[rowIndex].clone) { + grid.rowCache[rowIndex].clone.setSelection(state ? true : false); + } + grid.rowCache[rowIndex].setSelection(state ? true : false); } - $scope.$emit("ngGridEventData", grid.gridId); }; - $scope.$parent.$watch(options.data, dataWatcher); - $scope.$parent.$watch(options.data + '.length', function() { - dataWatcher($scope.$eval(options.data)); - }); - } - - grid.footerController = new ngFooter($scope, grid); - //set the right styling on the container - iElement.addClass("ngGrid").addClass(grid.gridId.toString()); - if (!options.enableHighlighting) { - iElement.addClass("unselectable"); - } - if (options.jqueryUITheme) { - iElement.addClass('ui-widget'); - } - iElement.append($compile($templateCache.get('gridTemplate.html'))($scope)); // make sure that if any of these change, we re-fire the calc logic - //walk the element's graph and the correct properties on the grid - domUtilityService.AssignGridContainers($scope, iElement, grid); - //now use the manager to assign the event handlers - grid.eventProvider = new ngEventProvider(grid, $scope, domUtilityService, $timeout); - - // method for user to select a specific row programatically - options.selectRow = function (rowIndex, state) { - if (grid.rowCache[rowIndex]) { - if (grid.rowCache[rowIndex].clone) { - grid.rowCache[rowIndex].clone.setSelection(state ? true : false); - } - grid.rowCache[rowIndex].setSelection(state ? true : false); - } - }; - // method for user to select the row by data item programatically - options.selectItem = function (itemIndex, state) { - options.selectRow(grid.rowMap[itemIndex], state); - }; - // method for user to set the select all state. - options.selectAll = function (state) { - $scope.toggleSelectAll(state); - }; - // method for user to set the groups programatically - options.groupBy = function (field) { - if (field) { - $scope.groupBy($scope.columns.filter(function(c) { + // method for user to select the row by data item programatically + options.selectItem = function (itemIndex, state) { + options.selectRow(grid.rowMap[itemIndex], state); + }; + // method for user to set the select all state. + options.selectAll = function (state) { + $scope.toggleSelectAll(state); + }; + // method for user to set the groups programatically + options.groupBy = function (field) { + if (field) { + $scope.groupBy($scope.columns.filter(function(c) { + return c.field == field; + })[0]); + } else { + var arr = $.extend(true, [], $scope.configGroups); + angular.forEach(arr, $scope.groupBy); + } + }; + // method for user to set the sort field programatically + options.sortBy = function (field) { + var col = $scope.columns.filter(function (c) { return c.field == field; - })[0]); - } else { - var arr = $.extend(true, [], $scope.configGroups); - angular.forEach(arr, $scope.groupBy); - } - }; - // method for user to set the sort field programatically - options.sortBy = function (field) { - var col = $scope.columns.filter(function (c) { - return c.field == field; - })[0]; - if (col) col.sort(); - }; - // the grid Id, entity, scope for convenience - options.gridId = grid.gridId; - options.ngGrid = grid; - options.$gridScope = $scope; - options.$gridServices = { SortService: sortService, DomUtilityService: domUtilityService }; - $scope.$on('ngGridEventDigestGrid', function(){ - domUtilityService.digest($scope.$parent); - }); - - $scope.$on('ngGridEventDigestGridParent', function(){ - domUtilityService.digest($scope.$parent); - }); - // set up the columns - $scope.$evalAsync(function() { - $scope.adjustScrollLeft(0); - }); - //initialize plugins. - angular.forEach(options.plugins, function (p) { - if (typeof p === 'function') { - p = p.call(this); + })[0]; + if (col) col.sort(); + }; + // the grid Id, entity, scope for convenience + options.gridId = grid.gridId; + options.ngGrid = grid; + options.$gridScope = $scope; + options.$gridServices = { SortService: sortService, DomUtilityService: domUtilityService }; + $scope.$on('ngGridEventDigestGrid', function(){ + domUtilityService.digest($scope.$parent); + }); + + $scope.$on('ngGridEventDigestGridParent', function(){ + domUtilityService.digest($scope.$parent); + }); + // set up the columns + $scope.$evalAsync(function() { + $scope.adjustScrollLeft(0); + }); + //initialize plugins. + angular.forEach(options.plugins, function (p) { + if (typeof p === 'function') { + p = p.call(this); + } + p.init($scope.$new(), grid, options.$gridServices); + options.plugins[$utils.getInstanceType(p)] = p; + }); + //send initi finalize notification. + if (options.init == "function") { + options.init(grid, $scope); } - p.init($scope.$new(), grid, options.$gridServices); - options.plugins[$utils.getInstanceType(p)] = p; + return null; }); - //send initi finalize notification. - if (options.init == "function") { - options.init(grid, $scope); - } - return null; } }; } diff --git a/build/ng-grid.js b/build/ng-grid.js index 9d116f6d24..99537a4837 100644 --- a/build/ng-grid.js +++ b/build/ng-grid.js @@ -2,7 +2,7 @@ * ng-grid JavaScript Library * Authors: https://github.com/angular-ui/ng-grid/blob/master/README.md * License: MIT (http://www.opensource.org/licenses/mit-license.php) -* Compiled At: 04/16/2013 15:21 +* Compiled At: 04/23/2013 14:36 ***********************************************/ (function(window, $) { 'use strict'; @@ -1097,7 +1097,7 @@ var ngFooter = function ($scope, grid) { }; }; -var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse) { +var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse, $http, $q) { var defaults = { aggregateTemplate: undefined, afterSelectionChange: function() { @@ -1189,29 +1189,43 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, self.data = []; self.lateBindColumns = false; self.filteredRows = []; - var getTemplate = function (key) { + + self.initTemplates = function() { + var templates = ['rowTemplate', 'aggregateTemplate', 'headerRowTemplate', 'checkboxCellTemplate', 'checkboxHeaderTemplate', 'menuTemplate', 'footerTemplate']; + + var promises = []; + templates.forEach(function(template) { + promises.push( self.getTemplate(template) ); + }); + + return $q.all(promises); + }; + self.getTemplate = function (key) { var t = self.config[key]; var uKey = self.gridId + key + ".html"; + var p = $q.defer(); if (t && !TEMPLATE_REGEXP.test(t)) { - $templateCache.put(uKey, $.ajax({ - type: "GET", - url: t, - async: false - }).responseText); + $http.get(t, { + cache: $templateCache + }) + .success(function(data){ + $templateCache.put(uKey, data); + p.resolve(); + }) + .error(function(err){ + p.reject("Could not load template: " + t); + }); } else if (t) { $templateCache.put(uKey, t); + p.resolve(); } else { var dKey = key + ".html"; $templateCache.put(uKey, $templateCache.get(dKey)); + p.resolve(); } + + return p.promise; }; - getTemplate('rowTemplate'); - getTemplate('aggregateTemplate'); - getTemplate('headerRowTemplate'); - getTemplate('checkboxCellTemplate'); - getTemplate('checkboxHeaderTemplate'); - getTemplate('menuTemplate'); - getTemplate('footerTemplate'); if (typeof self.config.data == "object") { self.data = self.config.data; @@ -1401,34 +1415,36 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, } }; self.init = function() { - $scope.selectionProvider = new ngSelectionProvider(self, $scope, $parse); - $scope.domAccessProvider = new ngDomAccessProvider(self); - self.rowFactory = new ngRowFactory(self, $scope, domUtilityService, $templateCache, $utils); - self.searchProvider = new ngSearchProvider($scope, self, $filter); - self.styleProvider = new ngStyleProvider($scope, self); - $scope.$watch('configGroups', function(a) { - var tempArr = []; - angular.forEach(a, function(item) { - tempArr.push(item.field || item); - }); - self.config.groups = tempArr; - self.rowFactory.filteredRowsChanged(); - $scope.$emit('ngGridEventGroups', a); - }, true); - $scope.$watch('columns', function (a) { - domUtilityService.BuildStyles($scope, self, true); - $scope.$emit('ngGridEventColumns', a); - }, true); - $scope.$watch(function() { - return options.i18n; - }, function(newLang) { - $utils.seti18n($scope, newLang); + return self.initTemplates().then(function(){ + $scope.selectionProvider = new ngSelectionProvider(self, $scope, $parse); + $scope.domAccessProvider = new ngDomAccessProvider(self); + self.rowFactory = new ngRowFactory(self, $scope, domUtilityService, $templateCache, $utils); + self.searchProvider = new ngSearchProvider($scope, self, $filter); + self.styleProvider = new ngStyleProvider($scope, self); + $scope.$watch('configGroups', function(a) { + var tempArr = []; + angular.forEach(a, function(item) { + tempArr.push(item.field || item); + }); + self.config.groups = tempArr; + self.rowFactory.filteredRowsChanged(); + $scope.$emit('ngGridEventGroups', a); + }, true); + $scope.$watch('columns', function (a) { + domUtilityService.BuildStyles($scope, self, true); + $scope.$emit('ngGridEventColumns', a); + }, true); + $scope.$watch(function() { + return options.i18n; + }, function(newLang) { + $utils.seti18n($scope, newLang); + }); + self.maxCanvasHt = self.calcMaxCanvasHeight(); + if (self.config.sortInfo.fields && self.config.sortInfo.fields.length > 0) { + self.getColsFromFields(); + self.sortActual(); + } }); - self.maxCanvasHt = self.calcMaxCanvasHeight(); - if (self.config.sortInfo.fields && self.config.sortInfo.fields.length > 0) { - self.getColsFromFields(); - self.sortActual(); - } }; self.resizeOnData = function(col) { var longest = col.minWidth; @@ -1520,7 +1536,7 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, angular.forEach(tempData, function(item, i) { var e = self.rowMap[i]; if (e != undefined) { - var v = self.rowCache[v]; + var v = self.rowCache[i]; if(v != undefined) { item.preSortSelected = v.selected; item.preSortIndex = i; @@ -1756,7 +1772,6 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, } return newDim; }; - self.init(); }; var ngRange = function (top, bottom) { @@ -2506,7 +2521,7 @@ ngGridDirectives.directive('ngGridMenu', ['$compile', '$templateCache', function }; return ngGridMenu; }]); -ngGridDirectives.directive('ngGrid', ['$compile', '$filter', '$templateCache', '$sortService', '$domUtilityService', '$utilityService', '$timeout', '$parse', function ($compile, $filter, $templateCache, sortService, domUtilityService, $utils, $timeout, $parse) { +ngGridDirectives.directive('ngGrid', ['$compile', '$filter', '$templateCache', '$sortService', '$domUtilityService', '$utilityService', '$timeout', '$parse', '$http', '$q', function ($compile, $filter, $templateCache, sortService, domUtilityService, $utils, $timeout, $parse, $http, $q) { var ngGridDirective = { scope: true, compile: function() { @@ -2515,117 +2530,120 @@ ngGridDirectives.directive('ngGrid', ['$compile', '$filter', '$templateCache', ' var $element = $(iElement); var options = $scope.$eval(iAttrs.ngGrid); options.gridDim = new ngDimension({ outerHeight: $($element).height(), outerWidth: $($element).width() }); - var grid = new ngGrid($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse); - if (typeof options.columnDefs == "string") { - $scope.$parent.$watch(options.columnDefs, function (a) { - if (!a) { - grid.refreshDomSizes(); + + var grid = new ngGrid($scope, options, sortService, domUtilityService, $filter, $templateCache, $utils, $timeout, $parse, $http, $q); + return grid.init().then(function() { + if (typeof options.columnDefs == "string") { + $scope.$parent.$watch(options.columnDefs, function (a) { + if (!a) { + grid.refreshDomSizes(); + grid.buildColumns(); + return; + } + grid.lateBoundColumns = false; + $scope.columns = []; + grid.config.columnDefs = a; grid.buildColumns(); - return; - } - grid.lateBoundColumns = false; - $scope.columns = []; - grid.config.columnDefs = a; - grid.buildColumns(); - grid.configureColumnWidths(); - grid.eventProvider.assignEvents(); - domUtilityService.RebuildGrid($scope, grid); - }, true); - } else { - grid.buildColumns(); - } - if (typeof options.data == "string") { - var dataWatcher = function (a) { - grid.data = $.extend([], a); - grid.rowFactory.fixRowCache(); - angular.forEach(grid.data, function (item, j) { - var indx = grid.rowMap[j] || j; - if (grid.rowCache[indx]) { - grid.rowCache[indx].ensureEntity(item); + grid.configureColumnWidths(); + grid.eventProvider.assignEvents(); + domUtilityService.RebuildGrid($scope, grid); + }, true); + } else { + grid.buildColumns(); + } + if (typeof options.data == "string") { + var dataWatcher = function (a) { + grid.data = $.extend([], a); + grid.rowFactory.fixRowCache(); + angular.forEach(grid.data, function (item, j) { + var indx = grid.rowMap[j] || j; + if (grid.rowCache[indx]) { + grid.rowCache[indx].ensureEntity(item); + } + grid.rowMap[indx] = j; + }); + grid.searchProvider.evalFilter(); + grid.configureColumnWidths(); + grid.refreshDomSizes(); + if (grid.config.sortInfo.fields.length > 0) { + grid.getColsFromFields(); + grid.sortActual(); + grid.searchProvider.evalFilter(); + $scope.$emit('ngGridEventSorted', grid.config.sortInfo); } - grid.rowMap[indx] = j; + $scope.$emit("ngGridEventData", grid.gridId); + }; + $scope.$parent.$watch(options.data, dataWatcher); + $scope.$parent.$watch(options.data + '.length', function() { + dataWatcher($scope.$eval(options.data)); }); - grid.searchProvider.evalFilter(); - grid.configureColumnWidths(); - grid.refreshDomSizes(); - if (grid.config.sortInfo.fields.length > 0) { - grid.getColsFromFields(); - grid.sortActual(); - grid.searchProvider.evalFilter(); - $scope.$emit('ngGridEventSorted', grid.config.sortInfo); + } + grid.footerController = new ngFooter($scope, grid); + iElement.addClass("ngGrid").addClass(grid.gridId.toString()); + if (!options.enableHighlighting) { + iElement.addClass("unselectable"); + } + if (options.jqueryUITheme) { + iElement.addClass('ui-widget'); + } + iElement.append($compile($templateCache.get('gridTemplate.html'))($scope)); + domUtilityService.AssignGridContainers($scope, iElement, grid); + grid.eventProvider = new ngEventProvider(grid, $scope, domUtilityService, $timeout); + options.selectRow = function (rowIndex, state) { + if (grid.rowCache[rowIndex]) { + if (grid.rowCache[rowIndex].clone) { + grid.rowCache[rowIndex].clone.setSelection(state ? true : false); + } + grid.rowCache[rowIndex].setSelection(state ? true : false); } - $scope.$emit("ngGridEventData", grid.gridId); }; - $scope.$parent.$watch(options.data, dataWatcher); - $scope.$parent.$watch(options.data + '.length', function() { - dataWatcher($scope.$eval(options.data)); - }); - } - grid.footerController = new ngFooter($scope, grid); - iElement.addClass("ngGrid").addClass(grid.gridId.toString()); - if (!options.enableHighlighting) { - iElement.addClass("unselectable"); - } - if (options.jqueryUITheme) { - iElement.addClass('ui-widget'); - } - iElement.append($compile($templateCache.get('gridTemplate.html'))($scope)); - domUtilityService.AssignGridContainers($scope, iElement, grid); - grid.eventProvider = new ngEventProvider(grid, $scope, domUtilityService, $timeout); - options.selectRow = function (rowIndex, state) { - if (grid.rowCache[rowIndex]) { - if (grid.rowCache[rowIndex].clone) { - grid.rowCache[rowIndex].clone.setSelection(state ? true : false); - } - grid.rowCache[rowIndex].setSelection(state ? true : false); - } - }; - options.selectItem = function (itemIndex, state) { - options.selectRow(grid.rowMap[itemIndex], state); - }; - options.selectAll = function (state) { - $scope.toggleSelectAll(state); - }; - options.groupBy = function (field) { - if (field) { - $scope.groupBy($scope.columns.filter(function(c) { + options.selectItem = function (itemIndex, state) { + options.selectRow(grid.rowMap[itemIndex], state); + }; + options.selectAll = function (state) { + $scope.toggleSelectAll(state); + }; + options.groupBy = function (field) { + if (field) { + $scope.groupBy($scope.columns.filter(function(c) { + return c.field == field; + })[0]); + } else { + var arr = $.extend(true, [], $scope.configGroups); + angular.forEach(arr, $scope.groupBy); + } + }; + options.sortBy = function (field) { + var col = $scope.columns.filter(function (c) { return c.field == field; - })[0]); - } else { - var arr = $.extend(true, [], $scope.configGroups); - angular.forEach(arr, $scope.groupBy); - } - }; - options.sortBy = function (field) { - var col = $scope.columns.filter(function (c) { - return c.field == field; - })[0]; - if (col) col.sort(); - }; - options.gridId = grid.gridId; - options.ngGrid = grid; - options.$gridScope = $scope; - options.$gridServices = { SortService: sortService, DomUtilityService: domUtilityService }; - $scope.$on('ngGridEventDigestGrid', function(){ - domUtilityService.digest($scope.$parent); - }); - $scope.$on('ngGridEventDigestGridParent', function(){ - domUtilityService.digest($scope.$parent); - }); - $scope.$evalAsync(function() { - $scope.adjustScrollLeft(0); - }); - angular.forEach(options.plugins, function (p) { - if (typeof p === 'function') { - p = p.call(this); + })[0]; + if (col) col.sort(); + }; + options.gridId = grid.gridId; + options.ngGrid = grid; + options.$gridScope = $scope; + options.$gridServices = { SortService: sortService, DomUtilityService: domUtilityService }; + $scope.$on('ngGridEventDigestGrid', function(){ + domUtilityService.digest($scope.$parent); + }); + $scope.$on('ngGridEventDigestGridParent', function(){ + domUtilityService.digest($scope.$parent); + }); + $scope.$evalAsync(function() { + $scope.adjustScrollLeft(0); + }); + angular.forEach(options.plugins, function (p) { + if (typeof p === 'function') { + p = p.call(this); + } + p.init($scope.$new(), grid, options.$gridServices); + options.plugins[$utils.getInstanceType(p)] = p; + }); + if (options.init == "function") { + options.init(grid, $scope); } - p.init($scope.$new(), grid, options.$gridServices); - options.plugins[$utils.getInstanceType(p)] = p; + return null; }); - if (options.init == "function") { - options.init(grid, $scope); - } - return null; } }; } diff --git a/build/ng-grid.min.js b/build/ng-grid.min.js index 710d1f9f7e..53bd0d5052 100644 --- a/build/ng-grid.min.js +++ b/build/ng-grid.min.js @@ -1,2 +1,2 @@ -(function(e,n){"use strict";var t=6,o=4,r="asc",i="desc",l="_ng_field_",a="_ng_depth_",s="_ng_hidden_",c="_ng_column_",g=/CUSTOM_FILTERS/g,d=/COL_FIELD/g,u=/DISPLAY_CELL_TEMPLATE/g,f=/EDITABLE_CELL_TEMPLATE/g,p=/<.+>/;e.ngGrid={},e.ngGrid.i18n={};var h=angular.module("ngGrid.services",[]),m=angular.module("ngGrid.directives",[]),v=angular.module("ngGrid.filters",[]);angular.module("ngGrid",["ngGrid.services","ngGrid.directives","ngGrid.filters"]);var w=function(e,n,o,r){if(void 0===e.selectionProvider.selectedItems)return!0;var i,l=o.which||o.keyCode,a=!1,s=!1,c=e.selectionProvider.lastClickedRow.rowIndex,g=e.columns.filter(function(e){return e.visible}),d=e.columns.filter(function(e){return e.pinned});if(e.col&&(i=g.indexOf(e.col)),37!=l&&38!=l&&39!=l&&40!=l&&9!=l&&13!=l)return!0;if(e.enableCellSelection){9==l&&o.preventDefault();var u=e.showSelectionCheckbox?1==e.col.index:0==e.col.index,f=1==e.$index||0==e.$index,p=e.$index==e.renderedColumns.length-1||e.$index==e.renderedColumns.length-2,h=g.indexOf(e.col)==g.length-1,m=d.indexOf(e.col)==d.length-1;if(37==l||9==l&&o.shiftKey){var v=0;u||(i-=1),f?u&&9==l&&o.shiftKey?(v=r.$canvas.width(),i=g.length-1,s=!0):v=r.$viewport.scrollLeft()-e.col.width:d.length>0&&(v=r.$viewport.scrollLeft()-g[i].width),r.$viewport.scrollLeft(v)}else(39==l||9==l&&!o.shiftKey)&&(p?h&&9==l&&!o.shiftKey?(r.$viewport.scrollLeft(0),i=e.showSelectionCheckbox?1:0,a=!0):r.$viewport.scrollLeft(r.$viewport.scrollLeft()+e.col.width):m&&r.$viewport.scrollLeft(0),h||(i+=1))}var w;w=e.configGroups.length>0?r.rowFactory.parsedData.filter(function(e){return!e.isAggRow}):r.filteredRows;var C=0;if(0!=c&&(38==l||13==l&&o.shiftKey||9==l&&o.shiftKey&&s)?C=-1:c!=w.length-1&&(40==l||13==l&&!o.shiftKey||9==l&&a)&&(C=1),C){var b=w[c+C];b.beforeSelectionChange(b,o)&&(b.continueSelection(o),e.$emit("ngGridEventDigestGridParent"),e.selectionProvider.lastClickedRow.renderedRowIndex>=e.renderedRows.length-t-2?r.$viewport.scrollTop(r.$viewport.scrollTop()+e.rowHeight):t+2>=e.selectionProvider.lastClickedRow.renderedRowIndex&&r.$viewport.scrollTop(r.$viewport.scrollTop()-e.rowHeight))}return e.enableCellSelection&&setTimeout(function(){e.domAccessProvider.focusCellElement(e,e.renderedColumns.indexOf(g[i]))},3),!1};String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),Array.prototype.indexOf||(Array.prototype.indexOf=function(e){var n=this.length>>>0,t=Number(arguments[1])||0;for(t=0>t?Math.ceil(t):Math.floor(t),0>t&&(t+=n);n>t;t++)if(t in this&&this[t]===e)return t;return-1}),Array.prototype.filter||(Array.prototype.filter=function(e){var n=Object(this),t=n.length>>>0;if("function"!=typeof e)throw new TypeError;for(var o=[],r=arguments[1],i=0;t>i;i++)if(i in n){var l=n[i];e.call(r,l,i,n)&&o.push(l)}return o}),v.filter("checkmark",function(){return function(e){return e?"✔":"✘"}}),v.filter("ngColumns",function(){return function(e){return e.filter(function(e){return!e.isAggCol})}}),h.factory("$domUtilityService",["$utilityService",function(e){var t={},o={},r=function(){var e=n("
");e.appendTo("body"),e.height(100).width(100).css("position","absolute").css("overflow","scroll"),e.append('
'),t.ScrollH=e.height()-e[0].clientHeight,t.ScrollW=e.width()-e[0].clientWidth,e.empty(),e.attr("style",""),e.append('M'),t.LetterW=e.children().first().width(),e.remove()};return t.eventStorage={},t.AssignGridContainers=function(e,o,r){r.$root=n(o),r.$topPanel=r.$root.find(".ngTopPanel"),r.$groupPanel=r.$root.find(".ngGroupPanel"),r.$headerContainer=r.$topPanel.find(".ngHeaderContainer"),e.$headerContainer=r.$headerContainer,r.$headerScroller=r.$topPanel.find(".ngHeaderScroller"),r.$headers=r.$headerScroller.children(),r.$viewport=r.$root.find(".ngViewport"),r.$canvas=r.$viewport.find(".ngCanvas"),r.$footerPanel=r.$root.find(".ngFooterPanel"),e.$watch(function(){return r.$viewport.scrollLeft()},function(e){return r.$headerContainer.scrollLeft(e)}),t.UpdateGridLayout(e,r)},t.getRealWidth=function(e){var t=0,o={visibility:"hidden",display:"block"},r=e.parents().andSelf().not(":visible");return n.swap(r[0],o,function(){t=e.outerWidth()}),t},t.UpdateGridLayout=function(e,n){var o=n.$viewport.scrollTop();n.elementDims.rootMaxW=n.$root.width(),n.$root.is(":hidden")&&(n.elementDims.rootMaxW=t.getRealWidth(n.$root)),n.elementDims.rootMaxH=n.$root.height(),n.refreshDomSizes(),e.adjustScrollTop(o,!0)},t.numberOfGrids=0,t.BuildStyles=function(o,r,i){var l,a=r.config.rowHeight,s=r.$styleSheet,c=r.gridId,g=o.columns,d=0;s||(s=n("#"+c),s[0]||(s=n("