UNPKG

angular-ui-grid

Version:

A data grid for Angular

1,103 lines (928 loc) 482 kB
/*! * ui-grid - v4.12.0-9c6a9c83 - 2023-01-19 * http://ui-grid.info/ * Copyright (c) 2023 UI Grid Team; License: MIT */ /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ 5747: /***/ ((module) => { module.exports = "<div\n class=\"ui-grid-filter-container\"\n ng-style=\"col.extraStyle\"\n ng-repeat=\"colFilter in col.filters\"\n ng-class=\"{'ui-grid-filter-cancel-button-hidden' : colFilter.disableCancelFilterButton === true }\">\n <div\n ng-if=\"colFilter.type !== 'select'\">\n <input\n type=\"text\"\n class=\"ui-grid-filter-input ui-grid-filter-input-{{$index}}\"\n ng-model=\"colFilter.term\"\n ng-attr-placeholder=\"{{colFilter.placeholder || ''}}\"\n aria-label=\"{{colFilter.ariaLabel || aria.defaultFilterLabel}}\" />\n\n <div\n role=\"button\"\n class=\"ui-grid-filter-button\"\n ng-click=\"removeFilter(colFilter, $index)\"\n ng-if=\"!colFilter.disableCancelFilterButton\"\n ng-disabled=\"colFilter.term === undefined || colFilter.term === null || colFilter.term === ''\"\n ng-show=\"colFilter.term !== undefined && colFilter.term !== null && colFilter.term !== ''\">\n <i\n class=\"ui-grid-icon-cancel\"\n ui-grid-one-bind-aria-label=\"aria.removeFilter\">\n &nbsp;\n </i>\n </div>\n </div>\n\n <div\n ng-if=\"colFilter.type === 'select'\">\n <select\n class=\"ui-grid-filter-select ui-grid-filter-input-{{$index}}\"\n ng-model=\"colFilter.term\"\n ng-show=\"colFilter.selectOptions.length > 0\"\n ng-attr-placeholder=\"{{colFilter.placeholder || aria.defaultFilterLabel}}\"\n aria-label=\"{{colFilter.ariaLabel || ''}}\"\n ng-options=\"option.value as option.label for option in colFilter.selectOptions\">\n <option value=\"\"></option>\n </select>\n\n <div\n role=\"button\"\n class=\"ui-grid-filter-button-select\"\n ng-click=\"removeFilter(colFilter, $index)\"\n ng-if=\"!colFilter.disableCancelFilterButton\"\n ng-disabled=\"colFilter.term === undefined || colFilter.term === null || colFilter.term === ''\"\n ng-show=\"colFilter.term !== undefined && colFilter.term != null\">\n <i\n class=\"ui-grid-icon-cancel\"\n ui-grid-one-bind-aria-label=\"aria.removeFilter\">\n &nbsp;\n </i>\n </div>\n </div>\n</div>\n" /***/ }), /***/ 2834: /***/ ((module) => { module.exports = "<div\n class=\"ui-grid-footer-panel ui-grid-footer-aggregates-row\"> <!-- tfooter -->\n <div\n class=\"ui-grid-footer ui-grid-footer-viewport\">\n <div\n class=\"ui-grid-footer-canvas\">\n <div\n class=\"ui-grid-footer-cell-wrapper\"\n ng-style=\"colContainer.headerCellWrapperStyle()\">\n <div\n role=\"row\"\n class=\"ui-grid-footer-cell-row\">\n <div\n ui-grid-footer-cell\n role=\"gridcell\"\n ng-repeat=\"col in colContainer.renderedColumns track by col.uid\"\n col=\"col\"\n render-index=\"$index\"\n class=\"ui-grid-footer-cell ui-grid-clearfix\">\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n" /***/ }), /***/ 5123: /***/ ((module) => { module.exports = "<div class=\"ui-grid-footer-info ui-grid-grid-footer\">\n <span>{{'search.totalItems' | t}} {{grid.rows.length}}</span>\n <span\n ng-if=\"grid.renderContainers.body.visibleRowCache.length !== grid.rows.length\"\n class=\"ngLabel\">\n ({{\"search.showingItems\" | t}} {{grid.renderContainers.body.visibleRowCache.length}})\n </span>\n</div>\n" /***/ }), /***/ 5847: /***/ ((module) => { module.exports = "<div\n role=\"rowgroup\"\n class=\"ui-grid-header\"> <!-- theader -->\n <div\n class=\"ui-grid-top-panel\">\n <div\n class=\"ui-grid-header-viewport\">\n <div\n class=\"ui-grid-header-canvas\">\n <div\n class=\"ui-grid-header-cell-wrapper\"\n ng-style=\"colContainer.headerCellWrapperStyle()\">\n <div\n role=\"row\"\n class=\"ui-grid-header-cell-row\">\n <div\n role=\"columnheader\"\n class=\"ui-grid-header-cell ui-grid-clearfix\"\n ng-repeat=\"col in colContainer.renderedColumns track by col.uid\"\n ui-grid-header-cell\n col=\"col\"\n render-index=\"$index\">\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n" /***/ }), /***/ 5195: /***/ ((module) => { module.exports = "<div class=\"ui-grid-menu-button\">\n <div role='button'\n ui-grid-one-bind-id-grid=\"'grid-menu'\"\n ui-grid-one-bind-aria-label=\"i18n.aria.buttonLabel\"\n tabindex=\"0\"\n class=\"ui-grid-icon-container\"\n ng-click=\"toggleMenu()\"\n ng-keydown=\"toggleOnKeydown($event)\"\n aria-expanded=\"{{shown}}\"\n aria-haspopup=\"true\">\n <i class=\"ui-grid-icon-menu\"\n ui-grid-one-bind-aria-label=\"i18n.aria.buttonLabel\">&nbsp;</i>\n </div>\n <div ui-grid-menu menu-items=\"menuItems\"></div>\n</div>\n" /***/ }), /***/ 4095: /***/ ((module) => { module.exports = "<li role=\"menuitem\">\n\t<div\n\t\tclass=\"ui-grid-menu-item\"\n\t\trole=\"heading\"\n\t\taria-level=\"2\"\n\t\tng-show=\"itemShown()\">\n\t\t<i aria-hidden='true'>\n\t\t\t&nbsp;\n\t\t</i>\n\t\t<span ng-bind=\"label()\"></span>\n\t</div>\n</li>" /***/ }), /***/ 2056: /***/ ((module) => { module.exports = "<div class=\"ui-grid-top-panel\">\n</div>" /***/ }), /***/ 5004: /***/ ((module) => { module.exports = " <div\n ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.uid\"\n ui-grid-one-bind-id-grid=\"rowRenderIndex + '-' + col.uid + '-cell'\"\n class=\"ui-grid-cell\"\n ng-class=\"{ 'ui-grid-row-header-cell': col.isRowHeader }\"\n role=\"{{col.isRowHeader ? 'rowheader' : 'gridcell'}}\"\n ui-grid-cell>\n</div>\n" /***/ }), /***/ 2194: /***/ ((module) => { module.exports = "<div ui-i18n=\"en\" class=\"ui-grid\">\n <!-- TODO (c0bra): add \"scoped\" attr here, eventually? -->\n <style ui-grid-style>\n .grid{{ grid.id }} {\n /* Styles for the grid */\n }\n\n .grid{{ grid.id }} .ui-grid-row, .grid{{ grid.id }} .ui-grid-cell, .grid{{ grid.id }} .ui-grid-cell .ui-grid-vertical-bar {\n height: {{ grid.options.rowHeight }}px;\n }\n\n .grid{{ grid.id }} .ui-grid-row:last-child .ui-grid-cell {\n border-bottom-width: {{ (((grid.getVisibleRowCount() * grid.options.rowHeight) < grid.getViewportHeight()) && '1') || '0' }}px;\n }\n\n {{ grid.verticalScrollbarStyles }}\n {{ grid.horizontalScrollbarStyles }}\n\n /*\n .ui-grid[dir=rtl] .ui-grid-viewport {\n padding-left: {{ grid.verticalScrollbarWidth }}px;\n }\n */\n\n {{ grid.customStyles }}\n </style>\n\n <div class=\"ui-grid-contents-wrapper\" role=\"grid\">\n <div ui-grid-menu-button ng-if=\"grid.options.enableGridMenu\"></div>\n\n <div ng-if=\"grid.hasLeftContainer()\" style=\"width: 0\" ui-grid-pinned-container=\"'left'\"></div>\n\n <div ui-grid-render-container\n container-id=\"'body'\"\n col-container-name=\"'body'\"\n row-container-name=\"'body'\"\n bind-scroll-horizontal=\"true\"\n bind-scroll-vertical=\"true\"\n enable-horizontal-scrollbar=\"grid.options.enableHorizontalScrollbar\"\n enable-vertical-scrollbar=\"grid.options.enableVerticalScrollbar\">\n </div>\n\n <div ng-if=\"grid.hasRightContainer()\" style=\"width: 0\" ui-grid-pinned-container=\"'right'\"></div>\n\n\n <div ui-grid-grid-footer ng-if=\"grid.options.showGridFooter\"></div>\n\n <div ui-grid-column-menu ng-if=\"grid.options.enableColumnMenus\"></div>\n\n <div ng-transclude></div>\n </div>\n</div>\n" /***/ }), /***/ 5352: /***/ ((module) => { module.exports = "<div\n class=\"ui-grid-cell-contents\"\n title=\"TOOLTIP\">\n {{COL_FIELD CUSTOM_FILTERS}}\n</div>\n" /***/ }), /***/ 8350: /***/ ((module) => { module.exports = "<div class=\"ui-grid-column-menu\">\n <div ui-grid-menu menu-items=\"menuItems\" col=\"col\">\n <!-- <div class=\"ui-grid-column-menu\">\n <div class=\"inner\" ng-show=\"menuShown\">\n <ul>\n <div ng-show=\"grid.options.enableSorting\">\n <li ng-click=\"sortColumn($event, asc)\" ng-class=\"{ 'selected' : col.sort.direction == asc }\"><i class=\"ui-grid-icon-sort-alt-up\"></i> Sort Ascending</li>\n <li ng-click=\"sortColumn($event, desc)\" ng-class=\"{ 'selected' : col.sort.direction == desc }\"><i class=\"ui-grid-icon-sort-alt-down\"></i> Sort Descending</li>\n <li ng-show=\"col.sort.direction\" ng-click=\"unsortColumn()\"><i class=\"ui-grid-icon-cancel\"></i> Remove Sort</li>\n </div>\n </ul>\n </div>\n </div> -->\n </div>\n</div>" /***/ }), /***/ 4358: /***/ ((module) => { module.exports = "<div\n class=\"ui-grid-cell-contents\"\n col-index=\"renderIndex\">\n <div>\n {{ col.getAggregationText() + ( col.getAggregationValue() CUSTOM_FILTERS ) }}\n </div>\n</div>\n" /***/ }), /***/ 6715: /***/ ((module) => { module.exports = "<div\n role=\"columnheader\"\n ng-class=\"{ 'sortable': sortable, 'ui-grid-header-cell-last-col': isLastCol }\"\n ui-grid-one-bind-aria-labelledby-grid=\"col.uid + '-header-text ' + col.uid + '-sortdir-text'\"\n aria-sort=\"{{col.sort.direction == asc ? 'ascending' : ( col.sort.direction == desc ? 'descending' : (!col.sort.direction ? 'none' : 'other'))}}\">\n <div\n role=\"button\"\n tabindex=\"0\"\n ng-keydown=\"handleKeyDown($event)\"\n class=\"ui-grid-cell-contents ui-grid-header-cell-primary-focus\"\n col-index=\"renderIndex\"\n title=\"TOOLTIP\">\n <span class=\"ui-grid-header-cell-label\" ui-grid-one-bind-id-grid=\"col.uid + '-header-text'\">{{ col.displayName CUSTOM_FILTERS }}</span>\n\n <span\n ui-grid-one-bind-id-grid=\"col.uid + '-sortdir-text'\"\n ui-grid-visible=\"col.sort.direction\"\n aria-label=\"{{getSortDirectionAriaLabel()}}\">\n <i\n ng-class=\"{ 'ui-grid-icon-up-dir': col.sort.direction == asc, 'ui-grid-icon-down-dir': col.sort.direction == desc, 'ui-grid-icon-blank': !col.sort.direction }\"\n title=\"{{isSortPriorityVisible() ? i18n.headerCell.priority + ' ' + ( col.sort.priority + 1 ) : null}}\"\n aria-hidden=\"true\">\n </i>\n <sub\n ui-grid-visible=\"isSortPriorityVisible()\"\n class=\"ui-grid-sort-priority-number\">\n {{col.sort.priority + 1}}\n </sub>\n </span>\n </div>\n\n <div\n role=\"button\"\n tabindex=\"0\"\n ui-grid-one-bind-id-grid=\"col.uid + '-menu-button'\"\n class=\"ui-grid-column-menu-button\"\n ng-if=\"grid.options.enableColumnMenus && !col.isRowHeader && col.colDef.enableColumnMenu !== false\"\n ng-click=\"toggleMenu($event)\"\n ng-keydown=\"headerCellArrowKeyDown($event)\"\n ui-grid-one-bind-aria-label=\"i18n.headerCell.aria.columnMenuButtonLabel\"\n aria-expanded=\"{{col.menuShown}}\"\n aria-haspopup=\"true\">\n <i\n class=\"ui-grid-icon-angle-down\"\n aria-hidden=\"true\">\n &nbsp;\n </i>\n </div>\n\n <div ui-grid-filter ng-hide=\"col.filterContainer === 'columnMenu'\"></div>\n</div>\n" /***/ }), /***/ 5760: /***/ ((module) => { module.exports = "<div\n class=\"ui-grid-menu\"\n ng-keydown=\"checkKeyDown($event)\"\n ng-show=\"shown\">\n <style ui-grid-style>\n {{dynamicStyles}}\n </style>\n <div\n class=\"ui-grid-menu-mid\"\n ng-show=\"shownMid\">\n <div\n class=\"ui-grid-menu-inner\"\n ng-if=\"shown\">\n <ul\n role=\"menu\"\n class=\"ui-grid-menu-items\">\n <li\n ng-repeat=\"item in menuItems\"\n role=\"menuitem\"\n ui-grid-menu-item\n ui-grid-one-bind-id=\"'menuitem-'+$index\"\n action=\"item.action\"\n name=\"item.title\"\n active=\"item.active\"\n icon=\"item.icon\"\n shown=\"item.shown\"\n context=\"item.context\"\n template-url=\"item.templateUrl\"\n leave-open=\"item.leaveOpen\"\n screen-reader-only=\"item.screenReaderOnly\">\n </li>\n <li ng-if=\"col.filterable && col.filterContainer === 'columnMenu'\">\n <div ui-grid-filter></div>\n </li>\n </ul>\n </div>\n </div>\n</div>\n" /***/ }), /***/ 9000: /***/ ((module) => { module.exports = "<button\n type=\"button\"\n class=\"ui-grid-menu-item\"\n ng-click=\"itemAction($event, title)\"\n ng-show=\"itemShown()\"\n ng-class=\"{ 'ui-grid-menu-item-active': active(), 'ui-grid-sr-only': (!focus && screenReaderOnly) }\"\n aria-pressed=\"{{active()}}\"\n tabindex=\"0\"\n ng-focus=\"focus=true\"\n ng-blur=\"focus=false\">\n <i\n ng-class=\"icon\"\n aria-hidden='true'>\n &nbsp;\n </i>\n {{ label() }}\n</button>\n" /***/ }), /***/ 2043: /***/ ((module) => { module.exports = "<div\n role=\"presentation\"\n ui-grid-one-bind-id-grid=\"containerId + '-grid-container'\"\n class=\"ui-grid-render-container\"\n ng-style=\"{ 'margin-left': colContainer.getMargin('left') + 'px', 'margin-right': colContainer.getMargin('right') + 'px' }\">\n <!-- All of these dom elements are replaced in place -->\n <div ui-grid-header></div>\n <div ui-grid-viewport></div>\n <div\n ng-if=\"colContainer.needsHScrollbarPlaceholder()\"\n class=\"ui-grid-scrollbar-placeholder\"\n ng-style=\"{height: colContainer.grid.scrollbarHeight + 'px'}\">\n </div>\n <ui-grid-footer\n ng-if=\"grid.options.showColumnFooter\">\n </ui-grid-footer>\n</div>\n" /***/ }), /***/ 7451: /***/ ((module) => { module.exports = "<div\n role=\"rowgroup\"\n class=\"ui-grid-viewport\"\n ng-style=\"colContainer.getViewportStyle()\"><!-- tbody -->\n <div\n class=\"ui-grid-canvas\">\n <div\n ng-repeat=\"(rowRenderIndex, row) in rowContainer.renderedRows track by $index\"\n class=\"ui-grid-row\"\n ng-style=\"Viewport.rowStyle(rowRenderIndex)\">\n <div\n role=\"row\"\n ui-grid-row=\"row\"\n row-render-index=\"rowRenderIndex\">\n </div>\n </div>\n </div>\n</div>\n" /***/ }), /***/ 7194: /***/ (() => { (function() { 'use strict'; angular.module('ui.grid.i18n', []); angular.module('ui.grid', ['ui.grid.i18n']); })(); /***/ }), /***/ 975: /***/ (() => { (function () { 'use strict'; /** * @ngdoc object * @name ui.grid.service:uiGridConstants * @description Constants for use across many grid features * */ angular.module('ui.grid').constant('uiGridConstants', { LOG_DEBUG_MESSAGES: true, LOG_WARN_MESSAGES: true, LOG_ERROR_MESSAGES: true, CUSTOM_FILTERS: /CUSTOM_FILTERS/g, COL_FIELD: /COL_FIELD/g, MODEL_COL_FIELD: /MODEL_COL_FIELD/g, TOOLTIP: /title=\"TOOLTIP\"/g, DISPLAY_CELL_TEMPLATE: /DISPLAY_CELL_TEMPLATE/g, TEMPLATE_REGEXP: /<.+>/, FUNC_REGEXP: /(\([^)]*\))?$/, DOT_REGEXP: /\./g, APOS_REGEXP: /'/g, BRACKET_REGEXP: /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/, COL_CLASS_PREFIX: 'ui-grid-col', ENTITY_BINDING: '$$this', events: { GRID_SCROLL: 'uiGridScroll', COLUMN_MENU_SHOWN: 'uiGridColMenuShown', ITEM_DRAGGING: 'uiGridItemDragStart', // For any item being dragged COLUMN_HEADER_CLICK: 'uiGridColumnHeaderClick' }, // copied from http://www.lsauer.com/2011/08/javascript-keymap-keycodes-in-json.html keymap: { TAB: 9, STRG: 17, CAPSLOCK: 20, CTRL: 17, CTRLRIGHT: 18, CTRLR: 18, SHIFT: 16, RETURN: 13, ENTER: 13, BACKSPACE: 8, BCKSP: 8, ALT: 18, ALTR: 17, ALTRIGHT: 17, SPACE: 32, WIN: 91, MAC: 91, FN: null, PG_UP: 33, PG_DOWN: 34, UP: 38, DOWN: 40, LEFT: 37, RIGHT: 39, ESC: 27, DEL: 46, F1: 112, F2: 113, F3: 114, F4: 115, F5: 116, F6: 117, F7: 118, F8: 119, F9: 120, F10: 121, F11: 122, F12: 123 }, /** * @ngdoc object * @name ASC * @propertyOf ui.grid.service:uiGridConstants * @description Used in {@link ui.grid.class:GridOptions.columnDef#properties_sort columnDef.sort} and * {@link ui.grid.class:GridOptions.columnDef#properties_sortDirectionCycle columnDef.sortDirectionCycle} * to configure the sorting direction of the column */ ASC: 'asc', /** * @ngdoc object * @name DESC * @propertyOf ui.grid.service:uiGridConstants * @description Used in {@link ui.grid.class:GridOptions.columnDef#properties_sort columnDef.sort} and * {@link ui.grid.class:GridOptions.columnDef#properties_sortDirectionCycle columnDef.sortDirectionCycle} * to configure the sorting direction of the column */ DESC: 'desc', /** * @ngdoc object * @name filter * @propertyOf ui.grid.service:uiGridConstants * @description Used in {@link ui.grid.class:GridOptions.columnDef#properties_filter columnDef.filter} * to configure filtering on the column * * `SELECT` and `INPUT` are used with the `type` property of the filter, the rest are used to specify * one of the built-in conditions. * * Available `condition` options are: * - `uiGridConstants.filter.STARTS_WITH` * - `uiGridConstants.filter.ENDS_WITH` * - `uiGridConstants.filter.CONTAINS` * - `uiGridConstants.filter.GREATER_THAN` * - `uiGridConstants.filter.GREATER_THAN_OR_EQUAL` * - `uiGridConstants.filter.LESS_THAN` * - `uiGridConstants.filter.LESS_THAN_OR_EQUAL` * - `uiGridConstants.filter.NOT_EQUAL` * * * Available `type` options are: * - `uiGridConstants.filter.SELECT` - use a dropdown box for the cell header filter field * - `uiGridConstants.filter.INPUT` - use a text box for the cell header filter field */ filter: { STARTS_WITH: 2, ENDS_WITH: 4, EXACT: 8, CONTAINS: 16, GREATER_THAN: 32, GREATER_THAN_OR_EQUAL: 64, LESS_THAN: 128, LESS_THAN_OR_EQUAL: 256, NOT_EQUAL: 512, SELECT: 'select', INPUT: 'input' }, /** * @ngdoc object * @name aggregationTypes * @propertyOf ui.grid.service:uiGridConstants * @description Used in {@link ui.grid.class:GridOptions.columnDef#properties_aggregationType columnDef.aggregationType} * to specify the type of built-in aggregation the column should use. * * Available options are: * - `uiGridConstants.aggregationTypes.sum` - add the values in this column to produce the aggregated value * - `uiGridConstants.aggregationTypes.count` - count the number of rows to produce the aggregated value * - `uiGridConstants.aggregationTypes.avg` - average the values in this column to produce the aggregated value * - `uiGridConstants.aggregationTypes.min` - use the minimum value in this column as the aggregated value * - `uiGridConstants.aggregationTypes.max` - use the maximum value in this column as the aggregated value */ aggregationTypes: { sum: 2, count: 4, avg: 8, min: 16, max: 32 }, /** * @ngdoc array * @name CURRENCY_SYMBOLS * @propertyOf ui.grid.service:uiGridConstants * @description A list of all presently circulating currency symbols that was copied from * https://en.wikipedia.org/wiki/Currency_symbol#List_of_presently-circulating_currency_symbols * * Can be used on {@link ui.grid.class:rowSorter} to create a number string regex that ignores currency symbols. */ CURRENCY_SYMBOLS: ['¤', '؋', 'Ar', 'Ƀ', '฿', 'B/.', 'Br', 'Bs.', 'Bs.F.', 'GH₵', '¢', 'c', 'Ch.', '₡', 'C$', 'D', 'ден', 'دج', '.د.ب', 'د.ع', 'JD', 'د.ك', 'ل.د', 'дин', 'د.ت', 'د.م.', 'د.إ', 'Db', '$', '₫', 'Esc', '€', 'ƒ', 'Ft', 'FBu', 'FCFA', 'CFA', 'Fr', 'FRw', 'G', 'gr', '₲', 'h', '₴', '₭', 'Kč', 'kr', 'kn', 'MK', 'ZK', 'Kz', 'K', 'L', 'Le', 'лв', 'E', 'lp', 'M', 'KM', 'MT', '₥', 'Nfk', '₦', 'Nu.', 'UM', 'T$', 'MOP$', '₱', 'Pt.', '£', 'ج.م.', 'LL', 'LS', 'P', 'Q', 'q', 'R', 'R$', 'ر.ع.', 'ر.ق', 'ر.س', '៛', 'RM', 'p', 'Rf.', '₹', '₨', 'SRe', 'Rp', '₪', 'Ksh', 'Sh.So.', 'USh', 'S/', 'SDR', 'сом', '৳ ', 'WS$', '₮', 'VT', '₩', '¥', 'zł'], /** * @ngdoc object * @name scrollDirection * @propertyOf ui.grid.service:uiGridConstants * @description Set on {@link ui.grid.class:Grid#properties_scrollDirection Grid.scrollDirection}, * to indicate the direction the grid is currently scrolling in * * Available options are: * - `uiGridConstants.scrollDirection.UP` - set when the grid is scrolling up * - `uiGridConstants.scrollDirection.DOWN` - set when the grid is scrolling down * - `uiGridConstants.scrollDirection.LEFT` - set when the grid is scrolling left * - `uiGridConstants.scrollDirection.RIGHT` - set when the grid is scrolling right * - `uiGridConstants.scrollDirection.NONE` - set when the grid is not scrolling, this is the default */ scrollDirection: { UP: 'up', DOWN: 'down', LEFT: 'left', RIGHT: 'right', NONE: 'none' }, /** * @ngdoc object * @name dataChange * @propertyOf ui.grid.service:uiGridConstants * @description Used with {@link ui.grid.api:PublicApi#methods_notifyDataChange PublicApi.notifyDataChange}, * {@link ui.grid.class:Grid#methods_callDataChangeCallbacks Grid.callDataChangeCallbacks}, * and {@link ui.grid.class:Grid#methods_registerDataChangeCallback Grid.registerDataChangeCallback} * to specify the type of the event(s). * * Available options are: * - `uiGridConstants.dataChange.ALL` - listeners fired on any of these events, fires listeners on all events. * - `uiGridConstants.dataChange.EDIT` - fired when the data in a cell is edited * - `uiGridConstants.dataChange.ROW` - fired when a row is added or removed * - `uiGridConstants.dataChange.COLUMN` - fired when the column definitions are modified * - `uiGridConstants.dataChange.OPTIONS` - fired when the grid options are modified */ dataChange: { ALL: 'all', EDIT: 'edit', ROW: 'row', COLUMN: 'column', OPTIONS: 'options' }, /** * @ngdoc object * @name scrollbars * @propertyOf ui.grid.service:uiGridConstants * @description Used with {@link ui.grid.class:GridOptions#properties_enableHorizontalScrollbar GridOptions.enableHorizontalScrollbar} * and {@link ui.grid.class:GridOptions#properties_enableVerticalScrollbar GridOptions.enableVerticalScrollbar} * to specify the scrollbar policy for that direction. * * Available options are: * - `uiGridConstants.scrollbars.NEVER` - never show scrollbars in this direction * - `uiGridConstants.scrollbars.ALWAYS` - always show scrollbars in this direction * - `uiGridConstants.scrollbars.WHEN_NEEDED` - shows scrollbars in this direction when needed */ scrollbars: { NEVER: 0, ALWAYS: 1, WHEN_NEEDED: 2 } }); })(); /***/ }), /***/ 2905: /***/ (() => { angular.module('ui.grid').directive('uiGridCell', ['$compile', '$parse', 'gridUtil', 'uiGridConstants', function ($compile, $parse, gridUtil, uiGridConstants) { return { priority: 0, scope: false, require: '?^uiGrid', compile: function() { return { pre: function($scope, $elm, $attrs, uiGridCtrl) { function compileTemplate() { var compiledElementFn = $scope.col.compiledElementFn; compiledElementFn($scope, function(clonedElement, scope) { $elm.append(clonedElement); }); } // If the grid controller is present, use it to get the compiled cell template function if (uiGridCtrl && $scope.col.compiledElementFn) { compileTemplate(); } // No controller, compile the element manually (for unit tests) else { if ( uiGridCtrl && !$scope.col.compiledElementFn ) { $scope.col.getCompiledElementFn() .then(function (compiledElementFn) { compiledElementFn($scope, function(clonedElement, scope) { $elm.append(clonedElement); }); }).catch(angular.noop); } else { var html = $scope.col.cellTemplate .replace(uiGridConstants.MODEL_COL_FIELD, 'row.entity.' + gridUtil.preEval($scope.col.field)) .replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)'); var cellElement = $compile(html)($scope); $elm.append(cellElement); } } }, post: function($scope, $elm) { var initColClass = $scope.col.getColClass(false), classAdded; $elm.addClass(initColClass); function updateClass( grid ) { var contents = $elm; if ( classAdded ) { contents.removeClass( classAdded ); classAdded = null; } if (angular.isFunction($scope.col.cellClass)) { classAdded = $scope.col.cellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex); } else { classAdded = $scope.col.cellClass; } contents.addClass(classAdded); } if ($scope.col.cellClass) { updateClass(); } // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs var dataChangeDereg = $scope.grid.registerDataChangeCallback( updateClass, [uiGridConstants.dataChange.COLUMN, uiGridConstants.dataChange.EDIT]); // watch the col and row to see if they change - which would indicate that we've scrolled or sorted or otherwise // changed the row/col that this cell relates to, and we need to re-evaluate cell classes and maybe other things function cellChangeFunction( n, o ) { if ( n !== o ) { if ( classAdded || $scope.col.cellClass ) { updateClass(); } // See if the column's internal class has changed var newColClass = $scope.col.getColClass(false); if (newColClass !== initColClass) { $elm.removeClass(initColClass); $elm.addClass(newColClass); initColClass = newColClass; } } } // TODO(c0bra): Turn this into a deep array watch var rowWatchDereg = $scope.$watch( 'row', cellChangeFunction ); function deregisterFunction() { dataChangeDereg(); rowWatchDereg(); } $scope.$on('$destroy', deregisterFunction); $elm.on('$destroy', deregisterFunction); } }; } }; }]); /***/ }), /***/ 7662: /***/ (() => { (function() { angular.module('ui.grid') .service('uiGridColumnMenuService', [ 'i18nService', 'uiGridConstants', 'gridUtil', function ( i18nService, uiGridConstants, gridUtil ) { /** * @ngdoc service * @name ui.grid.service:uiGridColumnMenuService * * @description Services for working with column menus, factored out * to make the code easier to understand */ var service = { /** * @ngdoc method * @methodOf ui.grid.service:uiGridColumnMenuService * @name initialize * @description Sets defaults, puts a reference to the $scope on * the uiGridController * @param {$scope} $scope the $scope from the uiGridColumnMenu * @param {controller} uiGridCtrl the uiGridController for the grid * we're on * */ initialize: function( $scope, uiGridCtrl ) { $scope.grid = uiGridCtrl.grid; // Store a reference to this link/controller in the main uiGrid controller // to allow showMenu later uiGridCtrl.columnMenuScope = $scope; // Save whether we're shown or not so the columns can check $scope.menuShown = false; }, /** * @ngdoc method * @methodOf ui.grid.service:uiGridColumnMenuService * @name setColMenuItemWatch * @description Setup a watch on $scope.col.menuItems, and update * menuItems based on this. $scope.col needs to be set by the column * before calling the menu. * @param {$scope} $scope the $scope from the uiGridColumnMenu */ setColMenuItemWatch: function ( $scope ) { var deregFunction = $scope.$watch('col.menuItems', function (n) { if (typeof(n) !== 'undefined' && n && angular.isArray(n)) { n.forEach(function (item) { if (typeof(item.context) === 'undefined' || !item.context) { item.context = {}; } item.context.col = $scope.col; }); $scope.menuItems = $scope.defaultMenuItems.concat(n); } else { $scope.menuItems = $scope.defaultMenuItems; } }); $scope.$on( '$destroy', deregFunction ); }, getGridOption: function( $scope, option ) { return typeof($scope.grid) !== 'undefined' && $scope.grid && $scope.grid.options && $scope.grid.options[option]; }, /** * @ngdoc boolean * @name enableSorting * @propertyOf ui.grid.class:GridOptions.columnDef * @description (optional) True by default. When enabled, this setting adds sort * widgets to the column header, allowing sorting of the data in the individual column. */ /** * @ngdoc method * @methodOf ui.grid.service:uiGridColumnMenuService * @name sortable * @description determines whether this column is sortable * @param {$scope} $scope the $scope from the uiGridColumnMenu * */ sortable: function( $scope ) { return Boolean( this.getGridOption($scope, 'enableSorting') && typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.enableSorting); }, /** * @ngdoc method * @methodOf ui.grid.service:uiGridColumnMenuService * @name isActiveSort * @description determines whether the requested sort direction is current active, to * allow highlighting in the menu * @param {$scope} $scope the $scope from the uiGridColumnMenu * @param {string} direction the direction that we'd have selected for us to be active * */ isActiveSort: function( $scope, direction ) { return Boolean(typeof($scope.col) !== 'undefined' && typeof($scope.col.sort) !== 'undefined' && typeof($scope.col.sort.direction) !== 'undefined' && $scope.col.sort.direction === direction); }, /** * @ngdoc method * @methodOf ui.grid.service:uiGridColumnMenuService * @name suppressRemoveSort * @description determines whether we should suppress the removeSort option * @param {$scope} $scope the $scope from the uiGridColumnMenu * */ suppressRemoveSort: function( $scope ) { return Boolean($scope.col && $scope.col.suppressRemoveSort); }, /** * @ngdoc boolean * @name enableHiding * @propertyOf ui.grid.class:GridOptions.columnDef * @description (optional) True by default. When set to false, this setting prevents a user from hiding the column * using the column menu or the grid menu. */ /** * @ngdoc method * @methodOf ui.grid.service:uiGridColumnMenuService * @name hideable * @description determines whether a column can be hidden, by checking the enableHiding columnDef option * @param {$scope} $scope the $scope from the uiGridColumnMenu * */ hideable: function( $scope ) { return Boolean( (this.getGridOption($scope, 'enableHiding') && typeof($scope.col) !== 'undefined' && $scope.col && ($scope.col.colDef && $scope.col.colDef.enableHiding !== false || !$scope.col.colDef)) || (!this.getGridOption($scope, 'enableHiding') && $scope.col && $scope.col.colDef && $scope.col.colDef.enableHiding) ); }, /** * @ngdoc method * @methodOf ui.grid.service:uiGridColumnMenuService * @name getDefaultMenuItems * @description returns the default menu items for a column menu * @param {$scope} $scope the $scope from the uiGridColumnMenu * */ getDefaultMenuItems: function( $scope ) { return [ { title: function() {return i18nService.getSafeText('sort.ascending');}, icon: 'ui-grid-icon-sort-alt-up', action: function($event) { $event.stopPropagation(); $scope.sortColumn($event, uiGridConstants.ASC); }, shown: function () { return service.sortable( $scope ); }, active: function() { return service.isActiveSort( $scope, uiGridConstants.ASC); } }, { title: function() {return i18nService.getSafeText('sort.descending');}, icon: 'ui-grid-icon-sort-alt-down', action: function($event) { $event.stopPropagation(); $scope.sortColumn($event, uiGridConstants.DESC); }, shown: function() { return service.sortable( $scope ); }, active: function() { return service.isActiveSort( $scope, uiGridConstants.DESC); } }, { title: function() {return i18nService.getSafeText('sort.remove');}, icon: 'ui-grid-icon-cancel', action: function ($event) { $event.stopPropagation(); $scope.unsortColumn(); }, shown: function() { return service.sortable( $scope ) && typeof($scope.col) !== 'undefined' && (typeof($scope.col.sort) !== 'undefined' && typeof($scope.col.sort.direction) !== 'undefined') && $scope.col.sort.direction !== null && !service.suppressRemoveSort( $scope ); } }, { title: function() {return i18nService.getSafeText('column.hide');}, icon: 'ui-grid-icon-cancel', shown: function() { return service.hideable( $scope ); }, action: function ($event) { $event.stopPropagation(); $scope.hideColumn(); } } ]; }, /** * @ngdoc method * @methodOf ui.grid.service:uiGridColumnMenuService * @name getColumnElementPosition * @description gets the position information needed to place the column * menu below the column header * @param {$scope} $scope the $scope from the uiGridColumnMenu * @param {GridColumn} column the column we want to position below * @param {element} $columnElement the column element we want to position below * @returns {hash} containing left, top, offset, height, width * */ getColumnElementPosition: function( $scope, column, $columnElement ) { var positionData = {}; positionData.left = $columnElement[0].offsetLeft; positionData.top = $columnElement[0].offsetTop; positionData.parentLeft = $columnElement[0].offsetParent.offsetLeft; // Get the grid scrollLeft positionData.offset = 0; if (column.grid.options.offsetLeft) { positionData.offset = column.grid.options.offsetLeft; } positionData.height = gridUtil.elementHeight($columnElement, true); positionData.width = gridUtil.elementWidth($columnElement, true); return positionData; }, /** * @ngdoc method * @methodOf ui.grid.service:uiGridColumnMenuService * @name repositionMenu * @description Reposition the menu below the new column. If the menu has no child nodes * (i.e. it's not currently visible) then we guess it's width at 100, we'll be called again * later to fix it * @param {$scope} $scope the $scope from the uiGridColumnMenu * @param {GridColumn} column the column we want to position below * @param {hash} positionData a hash containing left, top, offset, height, width * @param {element} $elm the column menu element that we want to reposition * @param {element} $columnElement the column element that we want to reposition underneath * */ repositionMenu: function( $scope, column, positionData, $elm, $columnElement ) { var menu = $elm[0].querySelectorAll('.ui-grid-menu'); // It's possible that the render container of the column we're attaching to is // offset from the grid (i.e. pinned containers), we need to get the difference in the offsetLeft // between the render container and the grid var renderContainerElm = gridUtil.closestElm($columnElement, '.ui-grid-render-container'), renderContainerOffset = renderContainerElm.getBoundingClientRect().left - $scope.grid.element[0].getBoundingClientRect().left, containerScrollLeft = renderContainerElm.querySelectorAll('.ui-grid-viewport')[0].scrollLeft; // repositionMenu is now always called after it's visible in the DOM, // allowing us to simply get the width every time the menu is opened var myWidth = gridUtil.elementWidth(menu, true), paddingRight = column.lastMenuPaddingRight ? column.lastMenuPaddingRight : ( $scope.lastMenuPaddingRight ? $scope.lastMenuPaddingRight : 10); if ( menu.length !== 0 ) { var mid = menu[0].querySelectorAll('.ui-grid-menu-mid'); if ( mid.length !== 0 ) { // TODO(c0bra): use padding-left/padding-right based on document direction (ltr/rtl), place menu on proper side // Get the column menu right padding paddingRight = parseInt(gridUtil.getStyles(angular.element(menu)[0])['paddingRight'], 10); $scope.lastMenuPaddingRight = paddingRight; column.lastMenuPaddingRight = paddingRight; } } var left = positionData.left + renderContainerOffset - containerScrollLeft + positionData.parentLeft + positionData.width + paddingRight; if (left < positionData.offset + myWidth) { left = Math.max(positionData.left - containerScrollLeft + positionData.parentLeft - paddingRight + myWidth, positionData.offset + myWidth); } $elm.css('left', left + 'px'); $elm.css('top', (positionData.top + positionData.height) + 'px'); } }; return service; }]) .directive('uiGridColumnMenu', ['$timeout', 'gridUtil', 'uiGridConstants', 'uiGridColumnMenuService', '$document', function ($timeout, gridUtil, uiGridConstants, uiGridColumnMenuService, $document) { /** * @ngdoc directive * @name ui.grid.directive:uiGridColumnMenu * @description Provides the column menu framework, leverages uiGridMenu underneath * */ return { priority: 0, scope: true, require: '^uiGrid', templateUrl: 'ui-grid/uiGridColumnMenu', replace: true, link: function ($scope, $elm, $attrs, uiGridCtrl) { uiGridColumnMenuService.initialize( $scope, uiGridCtrl ); $scope.defaultMenuItems = uiGridColumnMenuService.getDefaultMenuItems( $scope ); // Set the menu items for use with the column menu. The user can later add additional items via the watch $scope.menuItems = $scope.defaultMenuItems; uiGridColumnMenuService.setColMenuItemWatch( $scope ); function updateCurrentColStatus(menuShown) { if ($scope.col) { $scope.col.menuShown = menuShown; } } /** * @ngdoc method * @methodOf ui.grid.directive:uiGridColumnMenu * @name showMenu * @description Shows the column menu. If the menu is already displayed it * calls the menu to ask it to hide (it will animate), then it repositions the menu * to the right place whilst hidden (it will make an assumption on menu width), * then it asks the menu to show (it will animate), then it repositions the menu again * once we can calculate it's size. * @param {GridColumn} column the column we want to position below * @param {element} $columnElement the column element we want to position below */ $scope.showMenu = function(column, $columnElement, event) { // Update the menu status for the current column updateCurrentColStatus(false); // Swap to this column $scope.col = column; updateCurrentColStatus(true); // Get the position information for the column element var colElementPosition = uiGridColumnMenuService.getColumnElementPosition( $scope, column, $columnElement ); if ($scope.menuShown) { // we want to hide, then reposition, then show, but we want to wait for animations // we set a variable, and then rely on the menu-hidden event to call the reposition and show $scope.colElement = $columnElement; $scope.colElementPosition = colElementPosition; $scope.hideThenShow = true; $scope.$broadcast('hide-menu', { originalEvent: event }); } else { $scope.menuShown = true; $scope.colElement = $columnElement; $scope.colElementPosition = colElementPosition; $scope.$broadcast('show-menu', { originalEvent: event }); } }; /** * @ngdoc method * @methodOf ui.grid.directive:uiGridColumnMenu * @name hideMenu * @description Hides the column menu. * @param {boolean} broadcastTrigger true if we were triggered by a broadcast * from the menu itself - in which case don't broadcast again as we'll get * an infinite loop */ $scope.hideMenu = function( broadcastTrigger ) { $scope.menuShown = false; updateCurrentColStatus(false); if ( !broadcastTrigger ) { $scope.$broadcast('hide-menu'); } }; $scope.$on('menu-hidden', function() { var menuItems = angular.element($elm[0].querySelector('.ui-grid-menu-items'))[0]; $elm[0].removeAttribute('style'); if ( $scope.hideThenShow ) { delete $scope.hideThenShow; $scope.$broadcast('show-menu'); $scope.menuShown = true; } else { $scope.hideMenu( true ); if ($scope.col && $scope.col.visible) { // Focus on the menu button gridUtil.focus.bySelector($document, '.ui-grid-header-cell.' + $scope.col.getColClass()+ ' .ui-grid-column-menu-button', $scope.col.grid, false) .catch(angular.noop); } } if (menuItems) { menuItems.onkeydown = null; angular.forEach(menuItems.children, function removeHandlers(item) { item.onkeydown = null; }); } }); $scope.$on('menu-shown', function() { $timeout(function() { uiGridColumnMenuService.repositionMenu( $scope, $scope.col, $scope.colElementPosition, $elm, $scope.colElement ); var hasVisibleMenuItems = $scope.menuItems.some(function (menuItem) { return menuItem.shown(); }); // automatically set the focus to the first button element in the now open menu. if (hasVisibleMenuItems) { gridUtil.focus.bySelector($document, '.ui-grid-menu-items .ui-grid-menu-item:not(.ng-hide)', true) .catch(angular.noop); } delete $scope.colElementPosition; delete $scope.columnElement; addKeydownHandlersToMenu(); }); }); /* Column methods */ $scope.sortColumn = function (event, dir) { event.stopPropagation(); $scope.grid.sortColumn($scope.col, dir, true) .then(function () { $scope.grid.refresh(); $scope.hideMenu(); }).catch(angular.noop); }; $scope.unsortColumn = function () { $scope.col.unsort(); $scope.grid.refresh(); $scope.hideMenu(); }; function addKeydownHandlersToMenu() { var menu = angular.element($elm[0].querySelector('.ui-grid-menu-items'))[0], menuItems, visibleMenuItems = []; if (menu) { menu.onkeydown = function closeMenu(event) { if (event.keyCode === uiGridConstants.keymap.ESC) { event.preventDefault(); $scope.hideMenu(); } }; menuItems = menu.querySelectorAll('.ui-grid-menu-item:not(.ng-hide)'); angular.forEach(menuItems, function filterVisibleItems(item) { if (item.offsetParent !== null) { this.push(item); } }, visibleMenuItems); if (visibleMenuItems.length) { if (visibleMenuItems.length === 1) { visibleMenuItems[0].onkeydown = function singleItemHandler(event) { circularFocusHandler(event, true); }; } else { visibleMenuItems[0].onkeydown = function firstItemHandler(event) { circularFocusHandler(event, false, event.shiftKey, visibleMenuItems.length - 1); }; visibleMenuItems[visibleMenuItems.length - 1].onkeydown = function lastItemHandler(event) { circularFocusHandler(event, false, !event.shiftKey, 0); }; } } } function circularFocusHandler(event, isSingleItem, shiftKeyStatus, index) { if (event.keyCode === uiGridConstants.keymap.TAB) { if (isSingleItem) { event.preventDefault(); } else if (shiftKeyStatus) { event.preventDefault(); visibleMenuItems[index].focus(); } } } } // Since we are hiding this column the default hide action will fail so we need to focus somewhere else. var setFocusOnHideColumn = function() { $timeout(function() { // Get the UID of the first var focusToGridMenu = function() { return gridUtil.focus.byId('grid-menu', $scope.grid); }; var thisIndex; $scope.grid.columns.some(function(element, index) { if (angular.equals(element, $scope.col)) { thisIndex = index; return true; } }); var previousVisibleCol; // Try and find the next lower or nearest column to focus on $scope.grid.columns.some(function(element, index) { if (!element.visible) { return false; } // This columns index is below the current column index else if ( index < thisIndex) { previousVisibleCol = element; } // This elements index is above this column index and we haven't found one that is lower else if ( index > thisIndex && !previousVisibleCol) { // This is the next best thing previousVisibleCol = element; // We've found one so use it. return true; } // We've reached an element with an index above this column and the previousVisibleCol variable has been set else if (index > thisIndex && previousVisibleCol) { // We are done. return true; } }); // If found then focus on it if (previousVisibleCol) { var colClass = previousVisibleCol.getColClass(); gridUtil.focus.bySelector($document, '.ui-grid-header-cell.' + colClass+ ' .ui-grid-header-cell-primary-focus', true).then(angular.noop, function(reason) { if (reason !== 'canceled') { // If this is canceled then don't perform the action // The fallback action is to focus on the grid menu return focusToGridMenu(); } }).catch(angular.noop); } else { // Fallback action to focus on the grid menu focusToGridMenu(); } }); }; $scope.hideColumn = function () { $scope.col.colDef.visible = false; $scope.col.visible = false; $scope.grid.queueGridRefresh(); $scope.hideMenu(); $scope.grid.api.core.notifyDataChange( uiGridConstants.dataChange.COLUMN ); $scope.grid.api.core.raise.columnVisibilityChanged( $scope.col ); // We are hiding so the default action of focusing on the button that opened this menu will fail. setFocusOnHideColumn(); }; }, controller: ['$scope', function ($scope) { var self = this; $scope.$watch('menuItems', function (n) { self.menuItems = n; }); }] }; }]); })(); /***/ }), /***/ 6425: /***/ (() => { (function() { 'use strict'; angular.module('ui.grid').directive('uiGridFilter', ['$compile', '$templateCache', 'i18nService', 'gridUtil', function ($compile, $templateCache, i18nService, gridUtil) { return { compile: function() { return { pre: function ($scope, $elm) { $scope.col.updateFilters = function( filterable ) { $elm.children().remove(); if ( filterable ) { var template = $scope.col.filterHeaderTemplate; if (template === undefined && $scope.col.providedFilterHeaderTemplate !== '') { if ($scope.col.filterHeaderTemplatePromise) { $scope.col.filterHeaderTemplatePromise.then(function () { template = $scope.col.filterHeaderTemplate; $elm.append($c