/*********************************************** * 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: 03/29/2013 17:16 ***********************************************/ (function(window, $) { 'use strict'; // the # of rows we want to add to the top and bottom of the rendered grid rows var EXCESS_ROWS = 6; var SCROLL_THRESHOLD = 4; var ASC = "asc"; // constant for sorting direction var DESC = "desc"; // constant for sorting direction var NG_FIELD = '_ng_field_'; var NG_DEPTH = '_ng_depth_'; var NG_HIDDEN = '_ng_hidden_'; var NG_COLUMN = '_ng_column_'; var CUSTOM_FILTERS = /CUSTOM_FILTERS/g; var COL_FIELD = /COL_FIELD/g; var DISPLAY_CELL_TEMPLATE = /DISPLAY_CELL_TEMPLATE/g; var EDITABLE_CELL_TEMPLATE = /EDITABLE_CELL_TEMPLATE/g; var TEMPLATE_REGEXP = /<.+>/; window.ngGrid = {}; window.ngGrid.i18n = {}; // Declare app level module which depends on filters, and services var ngGridServices = angular.module('ngGrid.services', []); var ngGridDirectives = angular.module('ngGrid.directives', []); var ngGridFilters = angular.module('ngGrid.filters', []); // initialization of services into the main module angular.module('ngGrid', ['ngGrid.services', 'ngGrid.directives', 'ngGrid.filters']); //set event binding on the grid so we can select using the up/down keys var ngMoveSelectionHandler = function($scope, elm, evt, grid) { if ($scope.selectionProvider.selectedItems === undefined) { return true; } var charCode = evt.which || evt.keyCode, newColumnIndex, lastInRow = false, firstInRow = false, rowIndex = $scope.selectionProvider.lastClickedRow.rowIndex, visibleCols = $scope.columns.filter(function(c) { return c.visible; }), pinnedCols = $scope.columns.filter(function(c) { return c.pinned; }); if ($scope.col) { newColumnIndex = visibleCols.indexOf($scope.col); } if(charCode != 37 && charCode != 38 && charCode != 39 && charCode != 40 && charCode != 9 && charCode != 13){ return true; } if($scope.enableCellSelection){ if(charCode == 9){ //tab key evt.preventDefault(); } var focusedOnFirstColumn = $scope.showSelectionCheckbox ? $scope.col.index == 1 : $scope.col.index == 0; var focusedOnFirstVisibleColumns = $scope.$index == 1 || $scope.$index == 0; var focusedOnLastVisibleColumns = $scope.$index == ($scope.renderedColumns.length - 1) || $scope.$index == ($scope.renderedColumns.length - 2); var focusedOnLastColumn = visibleCols.indexOf($scope.col) == (visibleCols.length - 1); var focusedOnLastPinnedColumn = pinnedCols.indexOf($scope.col) == (pinnedCols.length - 1); if (charCode == 37 || charCode == 9 && evt.shiftKey) { var scrollTo = 0; if (!focusedOnFirstColumn) { newColumnIndex -= 1; } if (focusedOnFirstVisibleColumns) { if(focusedOnFirstColumn && charCode == 9 && evt.shiftKey){ scrollTo = grid.$canvas.width(); newColumnIndex = visibleCols.length - 1; firstInRow = true; } else { scrollTo = grid.$viewport.scrollLeft() - $scope.col.width; } } else if (pinnedCols.length > 0) { scrollTo = grid.$viewport.scrollLeft() - visibleCols[newColumnIndex].width; } grid.$viewport.scrollLeft(scrollTo); } else if(charCode == 39 || charCode == 9 && !evt.shiftKey){ if (focusedOnLastVisibleColumns) { if(focusedOnLastColumn && charCode == 9 && !evt.shiftKey){ grid.$viewport.scrollLeft(0); newColumnIndex = $scope.showSelectionCheckbox ? 1 : 0; lastInRow = true; } else { grid.$viewport.scrollLeft(grid.$viewport.scrollLeft() + $scope.col.width); } } else if (focusedOnLastPinnedColumn) { grid.$viewport.scrollLeft(0); } if(!focusedOnLastColumn){ newColumnIndex += 1; } } } var items; if ($scope.configGroups.length > 0) { items = grid.rowFactory.parsedData.filter(function (row) { return !row.isAggRow; }); } else { items = grid.filteredRows; } var offset = 0; if(rowIndex != 0 && (charCode == 38 || charCode == 13 && evt.shiftKey || charCode == 9 && evt.shiftKey && firstInRow)){ //arrow key up or shift enter or tab key and first item in row offset = -1; } else if(rowIndex != items.length - 1 && (charCode == 40 || charCode == 13 && !evt.shiftKey || charCode == 9 && lastInRow)){//arrow key down, enter, or tab key and last item in row? offset = 1; } if (offset) { var r = items[rowIndex + offset]; if (r.beforeSelectionChange(r, evt)) { r.continueSelection(evt); $scope.$emit('ngGridEventDigestGridParent'); if ($scope.selectionProvider.lastClickedRow.renderedRowIndex >= $scope.renderedRows.length - EXCESS_ROWS - 2) { grid.$viewport.scrollTop(grid.$viewport.scrollTop() + $scope.rowHeight); } else if ($scope.selectionProvider.lastClickedRow.renderedRowIndex <= EXCESS_ROWS + 2) { grid.$viewport.scrollTop(grid.$viewport.scrollTop() - $scope.rowHeight); } } } if($scope.enableCellSelection){ setTimeout(function(){ $scope.domAccessProvider.focusCellElement($scope, $scope.renderedColumns.indexOf(visibleCols[newColumnIndex])); },3); } return false; }; if (!String.prototype.trim) { String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }; } if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(elt /*, from*/) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) { from += len; } for (; from < len; from++) { if (from in this && this[from] === elt) { return from; } } return -1; }; } if (!Array.prototype.filter) { Array.prototype.filter = function(fun /*, thisp */) { "use strict"; var t = Object(this); var len = t.length >>> 0; if (typeof fun !== "function") { throw new TypeError(); } var res = []; var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in t) { var val = t[i]; // in case fun mutates this if (fun.call(thisp, val, i, t)) { res.push(val); } } } return res; }; } ngGridFilters.filter('checkmark', function() { return function(input) { return input ? '\u2714' : '\u2718'; }; }); ngGridFilters.filter('ngColumns', function() { return function(input) { return input.filter(function(col) { return !col.isAggCol; }); }; }); ngGridServices.factory('$domUtilityService',['$utilityService', function($utils) { var domUtilityService = {}; var regexCache = {}; var getWidths = function() { var $testContainer = $('
'); $testContainer.appendTo('body'); // 1. Run all the following measurements on startup! //measure Scroll Bars $testContainer.height(100).width(100).css("position", "absolute").css("overflow", "scroll"); $testContainer.append('
'); domUtilityService.ScrollH = ($testContainer.height() - $testContainer[0].clientHeight); domUtilityService.ScrollW = ($testContainer.width() - $testContainer[0].clientWidth); $testContainer.empty(); //clear styles $testContainer.attr('style', ''); //measure letter sizes using a pretty typical font size and fat font-family $testContainer.append('M'); domUtilityService.LetterW = $testContainer.children().first().width(); $testContainer.remove(); }; domUtilityService.eventStorage = {}; domUtilityService.AssignGridContainers = function($scope, rootEl, grid) { grid.$root = $(rootEl); //Headers grid.$topPanel = grid.$root.find(".ngTopPanel"); grid.$groupPanel = grid.$root.find(".ngGroupPanel"); grid.$headerContainer = grid.$topPanel.find(".ngHeaderContainer"); $scope.$headerContainer = grid.$headerContainer; grid.$headerScroller = grid.$topPanel.find(".ngHeaderScroller"); grid.$headers = grid.$headerScroller.children(); //Viewport grid.$viewport = grid.$root.find(".ngViewport"); //Canvas grid.$canvas = grid.$viewport.find(".ngCanvas"); //Footers grid.$footerPanel = grid.$root.find(".ngFooterPanel"); $scope.$watch(function () { return grid.$viewport.scrollLeft(); }, function (newLeft) { return grid.$headerContainer.scrollLeft(newLeft); }); domUtilityService.UpdateGridLayout($scope, grid); }; domUtilityService.getRealWidth = function (obj) { var width = 0; var props = { visibility: "hidden", display: "block" }; var hiddenParents = obj.parents().andSelf().not(':visible'); $.swap(hiddenParents[0], props, function () { width = obj.outerWidth(); }); return width; }; domUtilityService.UpdateGridLayout = function($scope, grid) { //catch this so we can return the viewer to their original scroll after the resize! var scrollTop = grid.$viewport.scrollTop(); grid.elementDims.rootMaxW = grid.$root.width(); if (grid.$root.is(':hidden')) { grid.elementDims.rootMaxW = domUtilityService.getRealWidth(grid.$root); } grid.elementDims.rootMaxH = grid.$root.height(); //check to see if anything has changed grid.refreshDomSizes(); $scope.adjustScrollTop(scrollTop, true); //ensure that the user stays scrolled where they were }; domUtilityService.numberOfGrids = 0; domUtilityService.BuildStyles = function($scope, grid, digest) { var rowHeight = grid.config.rowHeight, $style = grid.$styleSheet, gridId = grid.gridId, css, cols = $scope.columns, sumWidth = 0; if (!$style) { $style = $('#' + gridId); if (!$style[0]) { $style = $("