From 33a81fc2ab4e0233a34ec31eda1def04c3fbdf74 Mon Sep 17 00:00:00 2001 From: skozlov Date: Wed, 6 Jul 2016 16:03:45 +0300 Subject: [PATCH 01/40] Fixed inintial request for server pagination, clear dates for material and some other minor fixes1 --- demo/bootstrap/css/loading-bar.min.css | 1 + demo/bootstrap/js/serverPaginationApp.js | 2 +- demo/bootstrap/server-pagination.html | 8 +- demo/material/css/loading-bar.min.css | 1 + demo/material/index.html | 2 +- dist/dataGrid.js | 11 +- dist/dataGrid.min.js | 2 +- dist/loading-bar.js | 324 +++++++++++++++++++++++ dist/loading-bar.min.js | 1 + src/js/dataGrid.js | 11 +- src/js/vendors/loading-bar.js | 324 +++++++++++++++++++++++ 11 files changed, 673 insertions(+), 14 deletions(-) create mode 100644 demo/bootstrap/css/loading-bar.min.css create mode 100644 demo/material/css/loading-bar.min.css create mode 100644 dist/loading-bar.js create mode 100644 dist/loading-bar.min.js create mode 100644 src/js/vendors/loading-bar.js diff --git a/demo/bootstrap/css/loading-bar.min.css b/demo/bootstrap/css/loading-bar.min.css new file mode 100644 index 0000000..db06f19 --- /dev/null +++ b/demo/bootstrap/css/loading-bar.min.css @@ -0,0 +1 @@ +#loading-bar,#loading-bar-spinner{-webkit-transition:350ms linear all;-moz-transition:350ms linear all;-o-transition:350ms linear all;transition:350ms linear all}#loading-bar .ng-enter,#loading-bar .ng-leave.ng-leave-active,#loading-bar-spinner .ng-enter,#loading-bar-spinner .ng-leave.ng-leave-active{opacity:0}#loading-bar .ng-enter.ng-enter-active,#loading-bar .ng-leave,#loading-bar-spinner .ng-enter.ng-enter-active,#loading-bar-spinner .ng-leave{opacity:1}#loading-bar{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.25);z-index:11002}#loading-bar .bar{-webkit-transition:width 350ms;-moz-transition:width 350ms;-o-transition:width 350ms;transition:width 350ms;background:#29d;position:fixed;z-index:11002;top:0;left:0;width:100%;height:2px;border-bottom-right-radius:1px;border-top-right-radius:1px}#loading-bar .peg{position:absolute;width:70px;right:0;top:0;height:2px}#loading-bar-spinner{display:block;position:fixed;z-index:11002;top:50%;left:50%;margin-left:-15px;margin-right:-15px}#loading-bar-spinner .spinner-icon{width:34px;height:34px;border:solid 2px transparent;border-top-color:#fff;border-left-color:#fff;-webkit-border-radius:17px;-moz-border-radius:17px;border-radius:17px;-webkit-animation:loading-bar-spinner .8s linear infinite;-moz-animation:loading-bar-spinner .8s linear infinite;-ms-animation:loading-bar-spinner .8s linear infinite;-o-animation:loading-bar-spinner .8s linear infinite;animation:loading-bar-spinner .8s linear infinite}@-webkit-keyframes loading-bar-spinner{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes loading-bar-spinner{0%{-moz-transform:rotate(0);transform:rotate(0)}100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes loading-bar-spinner{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes loading-bar-spinner{0%{-ms-transform:rotate(0);transform:rotate(0)}100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-bar-spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/demo/bootstrap/js/serverPaginationApp.js b/demo/bootstrap/js/serverPaginationApp.js index dc46500..c175e45 100644 --- a/demo/bootstrap/js/serverPaginationApp.js +++ b/demo/bootstrap/js/serverPaginationApp.js @@ -2,7 +2,7 @@ 'use strict'; angular - .module('myApp', ['ui.bootstrap', 'dataGrid', 'pagination']) + .module('myApp', ['ui.bootstrap', 'dataGrid', 'pagination', 'angular-loading-bar']) .controller('myAppController', MyAppController) .factory('myAppFactory', MyAppFactory); diff --git a/demo/bootstrap/server-pagination.html b/demo/bootstrap/server-pagination.html index f9b25a8..c3d5b73 100644 --- a/demo/bootstrap/server-pagination.html +++ b/demo/bootstrap/server-pagination.html @@ -23,6 +23,7 @@ + -
+
+
+

Angular Data Grid - UI Router Server Pagination.

+ UI Router plus all features for server pagination.
+ UI Router can be used in both modes (hash and html5). + Project GitHub +
+
+
+
diff --git a/demo/bootstrap/views/anotherView.html b/demo/bootstrap/views/anotherView.html new file mode 100644 index 0000000..427c2e4 --- /dev/null +++ b/demo/bootstrap/views/anotherView.html @@ -0,0 +1,4 @@ +

Another View

+
+ +
\ No newline at end of file diff --git a/demo/bootstrap/views/router-server-pagination.html b/demo/bootstrap/views/router-server-pagination.html index d916b5f..1d112af 100644 --- a/demo/bootstrap/views/router-server-pagination.html +++ b/demo/bootstrap/views/router-server-pagination.html @@ -1,12 +1,7 @@
-
-

Angular Data Grid - UI Router Server Pagination.

- UI Router plus all features for server pagination
- Features enabled: sorting, filtering (using both in-grid and external controls), pagination and items-per-page functionality. - Angular UI Datepicker used for date controls, although you can use any other framework, plugin or styling. - Project GitHub +
+
-
@@ -117,8 +112,8 @@

Angular Data Grid - UI Router Server Pagination.

- - + + - + From 21e04e49794fdc06735fd9a44b35be1d4b3c24f5 Mon Sep 17 00:00:00 2001 From: AlexZ Date: Tue, 28 Mar 2017 15:31:05 +0300 Subject: [PATCH 13/40] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6d10e41..e0416b4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ ##Angular Data Grid + Light, flexible and performant Data Grid for AngularJS apps, with built-in sorting, pagination and filtering options, unified API for client-side and server-side data fetching, seamless synchronization with browser address bar and total freedom in mark-up and styling suitable for your application. Angular 1.3 - 1.6 compliant. From a5eb370d0131ff34995ab201be31224085bf7397 Mon Sep 17 00:00:00 2001 From: AlexZ Date: Tue, 28 Mar 2017 15:31:25 +0300 Subject: [PATCH 14/40] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e0416b4..48ba5dd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -##Angular Data Grid +## Angular Data Grid Light, flexible and performant Data Grid for AngularJS apps, with built-in sorting, pagination and filtering options, unified API for client-side and server-side data fetching, seamless synchronization with browser address bar and total freedom in mark-up and styling suitable for your application. Angular 1.3 - 1.6 compliant. From d6e0508dd54ce84f43c6a6ef7dcbdb81c94a7a4a Mon Sep 17 00:00:00 2001 From: AlexZ Date: Tue, 28 Mar 2017 15:37:16 +0300 Subject: [PATCH 15/40] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 48ba5dd..90c54c6 100644 --- a/README.md +++ b/README.md @@ -239,3 +239,6 @@ Then create in `gridOptions.customFilters` variable named as `ng-model` with fil All filters have optional parameter `disable-url`. If you set it to **true**, URL-synchronization for this filter will be disabled. If you need to use 2 or more grids on page, please add `id` to grids, and then use `grid-id` attribute on filters to specify their corresponding grid. [Example](http://angular-data-grid.github.io/demo/bootstrap/multiple.html) + +### Next / Future + - Port data grid to Angular2? From 3ad18336fe65f0464fd4640156f7ba7515b39dd1 Mon Sep 17 00:00:00 2001 From: Alexander Zhuk Date: Tue, 28 Mar 2017 16:07:41 +0300 Subject: [PATCH 16/40] updating package.json with new version --- package.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3e5963a..260e070 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-data-grid", - "version": "0.1.0", + "version": "1.0.0", "scripts": { "start": "gulp serve", "prebuild": "npm install" @@ -14,7 +14,7 @@ "gulp-sass": "^2.1.0", "gulp-uglify": "^1.4.2" }, - "description": "Light, flexible and performant Data Grid for AngularJS apps, with built-in sorting, pagination and filtering options, unified API for client-side and server-side data fetching, \r seamless synchronization with browser address bar and total freedom in mark-up and styling suitable for your application. Angular 1.3 - 1.5 compliant.", + "description": "Light, flexible and performant Data Grid for AngularJS apps, with built-in sorting, pagination and filtering options, unified API for client-side and server-side data fetching, \r seamless synchronization with browser address bar and total freedom in mark-up and styling suitable for your application. Angular 1.3 - 1.6 compliant.", "main": "index.html", "devDependencies": {}, "repository": { @@ -23,12 +23,15 @@ }, "keywords": [ "angular data grid", + "angular-data-grid", + "angular grid", + "angular-grid", "data grid", "data grid for angular", "ng-data-grid", "ng-table", "angular table", - "bootstra data grid", + "bootstrap data grid", "material design grid", "data table" ], From 60dda0ebc73ae391a4c43f3b5ef100c08fc24ce1 Mon Sep 17 00:00:00 2001 From: skozlov Date: Tue, 28 Mar 2017 17:04:55 +0300 Subject: [PATCH 17/40] Readme file was updated (urlSync) --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 90c54c6..55011cd 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Demo Angular UI Router: http://angular-data-grid.github.io/demo/bootstrap/ui-rou ### Features - Does not have any hard-coded template so you can choose any mark-up you need, from basic `
Order #Date PlacedOrder # Date Placed TotalTotal
` layout to any `
` structure. - Easily switch between the most popular Bootstrap and Google Material theming, or apply your own CSS theme just by changing several CSS classes. - - Built-in sync with browser address bar (URL), so you can copy-n-paste sorting/filtering/pagination results URL and open it in other browser / send to anyone - even if pagination / filtering are done on a client-side. + - Built-in sync with browser address bar (URL), so you can copy-n-paste sorting/filtering/pagination results URL and open it in other browser / send to anyone - even if pagination / filtering are done on a client-side. [See details](#url-synchronization) - Support of [Angular UI Router](https://github.com/angular-ui/ui-router) navigation. - Unlike most part of other Angular DataGrids, we intentionally use non-isolated scope of the directive to maximize flexibility, so it can be easily synchronized with any data changes inside your controller. NOTE! With great power comes great responsibility, so use non-isolated API wisely. @@ -235,9 +235,12 @@ Then create in `gridOptions.customFilters` variable named as `ng-model` with fil ``` -### Others -All filters have optional parameter `disable-url`. If you set it to **true**, URL-synchronization for this filter will be disabled. +### Url Synchronization +You can disable/enable URL-synchronization for whole grid. Just set `gridOptions.urlSync` to **false**/**true** +All filters have optional parameter `disable-url`. If you set it to **true**, URL-synchronization for this filter will be disabled. + +### Others If you need to use 2 or more grids on page, please add `id` to grids, and then use `grid-id` attribute on filters to specify their corresponding grid. [Example](http://angular-data-grid.github.io/demo/bootstrap/multiple.html) ### Next / Future From 16f87e1acd126a526ccd635afb401548436d1e87 Mon Sep 17 00:00:00 2001 From: AlexZ Date: Tue, 28 Mar 2017 17:26:53 +0300 Subject: [PATCH 18/40] Update README.md --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 55011cd..e10d9c3 100644 --- a/README.md +++ b/README.md @@ -235,13 +235,16 @@ Then create in `gridOptions.customFilters` variable named as `ng-model` with fil ``` -### Url Synchronization -You can disable/enable URL-synchronization for whole grid. Just set `gridOptions.urlSync` to **false**/**true** -All filters have optional parameter `disable-url`. If you set it to **true**, URL-synchronization for this filter will be disabled. +### URL Synchronization +You can disable/enable URL synchronization for the whole grid or on a level of particular filter. +Global parameter `gridOptions.urlSync` (boolean) works for the whole grid. -### Others +Each filter has optional parameter `disable-url` (boolean). If you set it to **true**, URL-synchronization for this particular filter will be disabled. + + +### Multiple grids on page If you need to use 2 or more grids on page, please add `id` to grids, and then use `grid-id` attribute on filters to specify their corresponding grid. [Example](http://angular-data-grid.github.io/demo/bootstrap/multiple.html) ### Next / Future - - Port data grid to Angular2? + - Port to Angular2? From c39897d759abf3437b8b676d1e56236628884310 Mon Sep 17 00:00:00 2001 From: AlexZ Date: Tue, 28 Mar 2017 17:28:23 +0300 Subject: [PATCH 19/40] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e10d9c3..094fab6 100644 --- a/README.md +++ b/README.md @@ -240,7 +240,7 @@ You can disable/enable URL synchronization for the whole grid or on a level of p Global parameter `gridOptions.urlSync` (boolean) works for the whole grid. -Each filter has optional parameter `disable-url` (boolean). If you set it to **true**, URL-synchronization for this particular filter will be disabled. +Each filter has optional parameter `disable-url` (boolean, default is 'false'). If you set it to **true**, URL-synchronization for this particular filter will be disabled. ### Multiple grids on page From 219d41d792e16def3a6fdda3d64491ddc88f31e2 Mon Sep 17 00:00:00 2001 From: AlexZ Date: Tue, 28 Mar 2017 17:28:45 +0300 Subject: [PATCH 20/40] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 094fab6..a453e66 100644 --- a/README.md +++ b/README.md @@ -238,7 +238,7 @@ Then create in `gridOptions.customFilters` variable named as `ng-model` with fil ### URL Synchronization You can disable/enable URL synchronization for the whole grid or on a level of particular filter. -Global parameter `gridOptions.urlSync` (boolean) works for the whole grid. +Global parameter `gridOptions.urlSync` (boolean, default is 'false') works for the whole grid. Each filter has optional parameter `disable-url` (boolean, default is 'false'). If you set it to **true**, URL-synchronization for this particular filter will be disabled. From 1842d577b3d94b888498a1e6fdd54a4a723bd962 Mon Sep 17 00:00:00 2001 From: AndreyChayko Date: Mon, 10 Apr 2017 12:33:25 +0300 Subject: [PATCH 21/40] Support fixed header columns (#33) * Fix Issue #29: Added initial structure * Fix #29: Added samples for bootstrap and material-design themes. Added dataGridUtils module and fixed-header directive * Fix #29: Code refactoring * Fix Issue #29: Modifications to css for fixed-header * Fix Issue #29: Removed unused code * Fix Issue #29: Changed file structure * Fix Issue #29: Added documentation for fixed header to bootstrap sample * Fix Issue #29: Added documentation to material sample * Fix Issue #29: Fixed description of the issue with md-content * Fix Issue #29: Applied changes to documentation. --- demo/fixed-header/angular-md-grid.html | 270 +++++++++++++++ demo/fixed-header/bootstrap-grid.html | 307 ++++++++++++++++++ .../css/fixed-header.bootstrap.css | 16 + .../css/fixed-header.material.css | 8 + demo/fixed-header/js/bootstrap/demoApp.js | 24 ++ .../js/material-design/demoApp.js | 23 ++ .../scss/fixed-header.bootstrap.scss | 25 ++ .../scss/fixed-header.material.scss | 14 + dist/css/fixedHeader/fixed-header.css | 10 + dist/dataGrid.js | 3 +- dist/dataGrid.min.js | 2 +- dist/dataGridUtils.js | 89 +++++ dist/dataGridUtils.min.js | 1 + dist/loading-bar.min.js | 2 +- dist/pagination.min.js | 2 +- gulpfile.js | 20 +- src/js/dataGrid.js | 3 +- src/js/directives/dataGridUtils.js | 4 + .../directives/fixedHeader/fixed-header.scss | 15 + src/js/directives/fixedHeader/fixedHeader.js | 85 +++++ 20 files changed, 917 insertions(+), 6 deletions(-) create mode 100644 demo/fixed-header/angular-md-grid.html create mode 100644 demo/fixed-header/bootstrap-grid.html create mode 100644 demo/fixed-header/css/fixed-header.bootstrap.css create mode 100644 demo/fixed-header/css/fixed-header.material.css create mode 100644 demo/fixed-header/js/bootstrap/demoApp.js create mode 100644 demo/fixed-header/js/material-design/demoApp.js create mode 100644 demo/fixed-header/scss/fixed-header.bootstrap.scss create mode 100644 demo/fixed-header/scss/fixed-header.material.scss create mode 100644 dist/css/fixedHeader/fixed-header.css create mode 100644 dist/dataGridUtils.js create mode 100644 dist/dataGridUtils.min.js create mode 100644 src/js/directives/dataGridUtils.js create mode 100644 src/js/directives/fixedHeader/fixed-header.scss create mode 100644 src/js/directives/fixedHeader/fixedHeader.js diff --git a/demo/fixed-header/angular-md-grid.html b/demo/fixed-header/angular-md-grid.html new file mode 100644 index 0000000..134befc --- /dev/null +++ b/demo/fixed-header/angular-md-grid.html @@ -0,0 +1,270 @@ + + + + + Angular Data Grid - Material Design + + + + + + + + + +
+ +
+ Angular Data Grid — Material Design + + + + + Change theme + arrow_drop_down + + + + + Bootstrap Design + + + Material Design + + + +
+
+ +
+
+

Angular Data Grid sample using Material Design styling

+ +

Features enabled: sorting, filtering, sync with browser URLs, pagination and item-per-page functionality. + Out-of-box Angular Material layout and + input controls used, + along with Material Design Light default CSS for + grid styling. + Project GitHub

+ +
+

How To Freeze Table Header

+

Using HTML Layout

+
+

The first option is to split table header and table body in two tables. + One way to do this is to follow the next steps:

+
    +
  • Use the next styles (with any fixed height) applied to table body container to make it scrollable:
    + .div-table-body { height: 600px; overflow-x: auto; overflow-y: scroll; }
    +
  • +
  • Make sure that th elements have the same padding as td elements have.
  • +
  • Use padding-right with the value of scroll bar width to make an offset for the table contains header.
  • +
  • Use width attribute for columns to sync widths.
  • +
+

Code Sample: +

+<table>
+    <thead>
+        ...
+    </thead>
+</table>
+<table>
+    <tbody class="div-table-body">
+        ...
+    </tbody>
+</table>
+        
+

+
+

Using Stand-alone Directive

+
+

Another option is to use the directive fixed-header that can be injected to the Data Grid like a separate module dataGridUtils.

+

To make it work it is needed to perform next steps:

+
    +
  • Include script to your application:
    + <script src="bower_components/angular-data-grid/dist/dataGridUtils.min.js"></script> +
  • +
  • Include css stylesheets to your application:
    + <link rel="stylesheet" href="bower_components/angular-data-grid/css/fixedHeader/fixed-header.css"> +
  • +
  • Inject dataGridUtils dependency in your module:
    + angular.module('myApp', ['dataGrid', ‘dataGridUtils.fixedHeader’]) +
  • +
  • Apply the directive fixed-header to the grid table:
    + <table class="table" fixed-header> +
  • +
+

The directive uses z-index: 99 if your page uses the same value or higher please make appropriate changes to fixed-header.scss file.

+

The directive also has additional attribute offset-from-element. + It is needed if you already have some other elements with fixed position above the table. + In this case you need to pass a class or id of the very last element (if there are several) to this attribute + to make the directive take + into consideration that header needs to be fixed with offset from above elements.

+

Example:
+ <table class="table" fixed-header offset-from-element + =”.the-class-on-above-fixed-element”>
+ or
+ <table class="table" fixed-header offset-from-element + =”=”#the-id-on-above-fixed-element”> +

+
+

The directive subscribes on scroll event, but the event is not fired when directive is used inside <md-content>, so to make it work please use the directive outside the <md-content> container. + For more information about this problem please review this issue. +

+
+
+
+
+
+
+ + + +
+
+ +
+
+ +
+
+ Clear Dates + +
+
+
+
+
+ {{filtered.length}} items total +
+
+
+ + + + 10 + 25 + 50 + 75 + + +
+
+
+
+
+ + + + + + + + + + + + + + + + +
+ Order # + + + All Statuses + + {{option.text}} + + + + Date Placed + + Total +
+ +
+
+
+ + + + 10 + 25 + 50 + 75 + + +
+
+
+ CodePen +
+

See the Pen eJWWpM by AngularDataGrid (@AngularDataGrid) on CodePen. +

+ +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/demo/fixed-header/bootstrap-grid.html b/demo/fixed-header/bootstrap-grid.html new file mode 100644 index 0000000..bf2d003 --- /dev/null +++ b/demo/fixed-header/bootstrap-grid.html @@ -0,0 +1,307 @@ + + + + + Angular Data Grid - Bootstrap Design + + + + + + + + + +
+
+

Angular Data Grid sample using out-of-box Bootstrap styling

+ Features enabled: sorting, filtering (using both in-grid and external controls), sync with browser URLs, pagination and items-per-page functionality. + Angular UI Datepicker used for date controls, although you can use any other framework, plugin or styling. + Project GitHub +
+
+

How To Freeze Table Header

+

Using HTML Layout

+
+

The first option is to split table header and table body in two tables. + One way to do this is to follow the next steps:

+
    +
  • Use the next styles (with any fixed height) applied to table body container to make it scrollable:
    + .div-table-body { height: 600px; overflow-x: auto; overflow-y: scroll; } +
  • +
  • Make sure that th elements have the same padding as td elements have.
  • +
  • Use padding-right with the value of scroll bar width to make an offset for the table contains header.
  • +
  • Use width attribute for columns to sync widths.
  • +
+

Code Sample: +

+<table>
+    <thead>
+        ...
+    </thead>
+</table>
+<table>
+    <tbody class="div-table-body">
+        ...
+    </tbody>
+</table>
+        
+

+
+

Using Stand-alone Directive

+
+

Another option is to use the directive fixed-header that can be injected to the Data Grid like a separate module dataGridUtils.

+

To make it work it is needed to perform next steps:

+
    +
  • Include script to your application:
    + <script src="bower_components/angular-data-grid/dist/dataGridUtils.min.js"></script> +
  • +
  • Include css stylesheets to your application:
    + <link rel="stylesheet" href="bower_components/angular-data-grid/css/fixedHeader/fixed-header.css"> +
  • +
  • Inject dataGridUtils dependency in your module:
    + angular.module('myApp', ['dataGrid', ‘dataGridUtils.fixedHeader’]) +
  • +
  • Apply the directive fixed-header to the grid table:
    + <table class="table" fixed-header> +
  • +
+

The directive uses z-index: 99 if your page uses the same value or higher please make appropriate changes to fixed-header.scss file.

+

The directive also has additional attribute offset-from-element. + It is needed if you already have some other elements with fixed position above the table. + In this case you need to pass a class or id of the very last element (if there are several) to this attribute + to make the directive take + into consideration that header needs to be fixed with offset from above elements.

+

Example:
+ <table class="table" fixed-header offset-from-element + =”.the-class-on-above-fixed-element”>
+ or
+ <table class="table" fixed-header offset-from-element + =”=”#the-id-on-above-fixed-element”> +

+
+
+

Additional Demos

+ +
+
+
+
+
+ + +
+
+
+
+ + +
+ + + + +
+
+
+
+
+ + +
+ + + + +
+
+ +
+
+
+
+
+
+
+
+
+ {{filtered.length}} items total +
+
+
+
+ +
+
+ + +
+
+
+
+ + + + + + + + + + + + + + + + + +
+ Order # + + Date Placed + + + + Total +
+
+
+ +
+
+ + +
+
+
+
+
+
+
+ +
+

See the Pen xZddZm by AngularDataGrid (@AngularDataGrid) on CodePen.

+ +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/demo/fixed-header/css/fixed-header.bootstrap.css b/demo/fixed-header/css/fixed-header.bootstrap.css new file mode 100644 index 0000000..421dc34 --- /dev/null +++ b/demo/fixed-header/css/fixed-header.bootstrap.css @@ -0,0 +1,16 @@ +.fixed-header { + border: none; } + .fixed-header tr { + background-color: #fff; } + +.tbody-offset:before { + color: white; + height: 60px; } + +.fixed-nav { + position: fixed; + width: 100%; + z-index: 5; } + +.padding-top-50 { + padding-top: 50px; } diff --git a/demo/fixed-header/css/fixed-header.material.css b/demo/fixed-header/css/fixed-header.material.css new file mode 100644 index 0000000..d1ce846 --- /dev/null +++ b/demo/fixed-header/css/fixed-header.material.css @@ -0,0 +1,8 @@ +.fixed-header { + border: 1px solid rgba(0, 0, 0, 0.12); } + .fixed-header tr { + background-color: #fff; } + +.tbody-offset:before { + color: white; + height: 60px; } diff --git a/demo/fixed-header/js/bootstrap/demoApp.js b/demo/fixed-header/js/bootstrap/demoApp.js new file mode 100644 index 0000000..042d439 --- /dev/null +++ b/demo/fixed-header/js/bootstrap/demoApp.js @@ -0,0 +1,24 @@ +angular.module('myApp', ['ui.bootstrap', 'dataGrid', 'pagination', 'dataGridUtils.fixedHeader']) + .controller('myAppController', ['$scope', 'myAppFactory', function ($scope, myAppFactory) { + + $scope.gridOptions = { + data: [], + urlSync: true + }; + + myAppFactory.getData().then(function (responseData) { + $scope.gridOptions.data = responseData.data; + }); + + }]) + .factory('myAppFactory', function ($http) { + return { + getData: function () { + return $http({ + method: 'GET', + url: 'https://angular-data-grid.github.io/demo/data.json' + }); + } + } + }); + diff --git a/demo/fixed-header/js/material-design/demoApp.js b/demo/fixed-header/js/material-design/demoApp.js new file mode 100644 index 0000000..2f108af --- /dev/null +++ b/demo/fixed-header/js/material-design/demoApp.js @@ -0,0 +1,23 @@ +angular.module('myApp', ['dataGrid', 'pagination', 'ngMaterial', 'dataGridUtils.fixedHeader']) + .controller('myAppController', ['$scope', 'myAppFactory', function ($scope, myAppFactory) { + + $scope.gridOptions = { + data: [], + urlSync: true + }; + myAppFactory.getData().then(function (responseData) { + $scope.gridOptions.data = responseData.data; + }); + + }]) + .factory('myAppFactory', function ($http) { + return { + getData: function () { + return $http({ + method: 'GET', + url: 'https://angular-data-grid.github.io/demo/data.json' + }); + } + } + }); + diff --git a/demo/fixed-header/scss/fixed-header.bootstrap.scss b/demo/fixed-header/scss/fixed-header.bootstrap.scss new file mode 100644 index 0000000..8c6ff62 --- /dev/null +++ b/demo/fixed-header/scss/fixed-header.bootstrap.scss @@ -0,0 +1,25 @@ +//styles specific to bootstrap sample (not required) +.fixed-header { + border: none; + tr { + background-color: #fff; + } +} + +.tbody-offset { + &:before { + color: white; + height: 60px; + } +} + +.fixed-nav { + position: fixed; + width: 100%; + z-index: 5; +} + +.padding-top-50 { + padding-top: 50px; +} + diff --git a/demo/fixed-header/scss/fixed-header.material.scss b/demo/fixed-header/scss/fixed-header.material.scss new file mode 100644 index 0000000..b1dfee6 --- /dev/null +++ b/demo/fixed-header/scss/fixed-header.material.scss @@ -0,0 +1,14 @@ +//styles specific to material design sample (not required) +.fixed-header { + border: 1px solid rgba(0,0,0,.12); + tr { + background-color: #fff; + } +} + +.tbody-offset { + &:before { + color: white; + height: 60px; + } +} \ No newline at end of file diff --git a/dist/css/fixedHeader/fixed-header.css b/dist/css/fixedHeader/fixed-header.css new file mode 100644 index 0000000..29c52fc --- /dev/null +++ b/dist/css/fixedHeader/fixed-header.css @@ -0,0 +1,10 @@ +.fixed-header { + top: 0; + position: fixed; + width: auto; + display: table; + z-index: 99; } + +.tbody-offset:before { + content: " "; + display: block; } diff --git a/dist/dataGrid.js b/dist/dataGrid.js index 1ae356c..7ed9847 100644 --- a/dist/dataGrid.js +++ b/dist/dataGrid.js @@ -12,7 +12,7 @@ return []; } }) - .controller('gridController', ['$scope', '$element', '$filter', '$location', 'filtersFactory', function ($scope, $element, $filter, $location, filtersFactory) { + .controller('gridController', ['$scope', '$rootScope', '$element', '$filter', '$location', 'filtersFactory', function ($scope, $rootScope, $element, $filter, $location, filtersFactory) { // values by default $scope._gridOptions = $scope.$eval($element.attr('grid-options')); $scope._gridActions = $scope.$eval($element.attr('grid-actions')); @@ -84,6 +84,7 @@ } else { applyFilters(); } + $rootScope.$broadcast('gridReloaded'); }; $scope._gridActions.refresh = $scope.reloadGrid; diff --git a/dist/dataGrid.min.js b/dist/dataGrid.min.js index c0ba104..2789310 100644 --- a/dist/dataGrid.min.js +++ b/dist/dataGrid.min.js @@ -1 +1 @@ -!function(){"use strict";function t(t,e){var i=[];return t?(t.forEach(function(t){~i.indexOf(t[e])||i.push(t[e])}),i.map(function(t){return{text:t,value:t}})):void 0}angular.module("dataGrid",[]).filter("startFrom",function(){return function(t,e){return t?(e=+e,t.slice(e)):[]}}).controller("gridController",["$scope","$element","$filter","$location","filtersFactory",function(e,i,r,n,a){function o(){(e.urlSync||e.serverPagination)&&(e.serverPagination&&(clearTimeout(e.getDataTimeout),e.getDataTimeout=setTimeout(l,e.getDataDelay)),e.filtered&&c())}function s(t){var i,r=!1;i="page="+e.paginationOptions.currentPage,e.paginationOptions.itemsPerPage!==e.defaultsPaginationOptions.itemsPerPage&&(i+="&itemsPerPage="+e.paginationOptions.itemsPerPage),e.sortOptions.predicate&&(i+="&sort="+encodeURIComponent(e.sortOptions.predicate+"-"+e.sortOptions.direction)),e.filters.forEach(function(t){var n=t.model,a=t.isInScope?e.$eval(n):e.$parent.$eval(n);if(t.disableUrl)return void(r=!0);if(a){var o;if(a instanceof Date){if(isNaN(a.getTime()))return;o=a.getFullYear()+"-",o+=a.getMonth()<9?"0"+(a.getMonth()+1)+"-":a.getMonth()+1+"-",o+=a.getDate()<10?"0"+a.getDate():a.getDate(),a=o}i+="&"+encodeURIComponent(n)+"="+encodeURIComponent(a)}}),r&&p(),n.search(i),t&&e.$apply()}function c(){var t=n.search(),i={};if(Object.keys(t).forEach(function(e){"page"!==e&&"sort"!==e&&"itemsPerPage"!==e&&(i[e]=t[e])}),e.filters.forEach(function(t){var r=t.model,n=i[r];if(!t.disableUrl){if(~t.filterType.toLowerCase().indexOf("date"))return e.$parent.__evaltmp=n?new Date(n):null,void e.$parent.$eval(r+"=__evaltmp");"select"!==t.filterType||n||(n=""),n&&(t.isInScope?(e.__evaltmp=n,e.$eval(r+"=__evaltmp")):(e.$parent.__evaltmp=n,e.$parent.$eval(r+"=__evaltmp")))}}),e.paginationOptions.itemsPerPage=e.defaultsPaginationOptions.itemsPerPage,e.paginationOptions.currentPage=e.defaultsPaginationOptions.currentPage,t.itemsPerPage&&(e.paginationOptions.itemsPerPage=t.itemsPerPage),t.page&&(!e.serverPagination&&(t.page-1)*e.paginationOptions.itemsPerPage>e.filtered.length?e.paginationOptions.currentPage=1:e.paginationOptions.currentPage=t.page),t.sort){var r=t.sort.split("-");e.sortOptions.predicate=decodeURIComponent(r[0]),e.sortOptions.direction=decodeURIComponent(r[1])}e.serverPagination||p()}function l(){var t="",i=n.search();Object.keys(i).forEach(function(e){t+=e+"="+i[e]+"&"}),t=t.slice(0,-1),!t&&e.sortOptions.predicate?e.sort(e.sortOptions.predicate,!0):e._gridOptions.getData("?"+t,function(t,i){e.filtered=t,e.paginationOptions.totalItems=i})}function p(){var t=Date.now(),i=!1;e._time={},e.sortOptions.predicate&&e.sortCache&&e.sortCache.predicate===e.sortOptions.predicate&&e.sortCache.direction===e.sortOptions.direction?(e.filtered=e.sortCache.data.slice(),i=!0):e.filtered=e._gridOptions.data.slice(),e._time.copy=Date.now()-t;var n=Date.now();d(),e._time.filters=Date.now()-n;var a=Date.now();e.sortOptions.predicate&&!i&&(e.filtered=r("orderBy")(e.filtered,e.sortOptions.predicate,"desc"===e.sortOptions.direction),e.sortCache={data:e.filtered.slice(),predicate:e.sortOptions.predicate,direction:e.sortOptions.direction}),e._time.sort=Date.now()-a,e._time.all=Date.now()-t,e.paginationOptions.totalItems=e.filtered.length}function d(){e.filters.forEach(function(t){var i=t.filterBy,r=t.model,n=t.isInScope?e.$eval(r):e.$parent.$eval(r),o=t.filterType;if(e.customFilters[r])e.filtered=e.customFilters[r](e.filtered,n,i);else if(n&&o){var s=a.getFilterByType(o);s&&(e.filtered=s(e.filtered,n,i))}})}e._gridOptions=e.$eval(i.attr("grid-options")),e._gridActions=e.$eval(i.attr("grid-actions")),e.serverPagination="true"===i.attr("server-pagination"),e.getDataDelay=i.attr("get-delay")||350,e._gridActions||(e.$parent.$eval(i.attr("grid-actions")+"= {}"),e._gridActions=e.$parent.$eval(i.attr("grid-actions"))),e._gridOptions.grid=e,e.filtered=e._gridOptions.data.slice(),e.paginationOptions=e._gridOptions.pagination?angular.copy(e._gridOptions.pagination):{},e.defaultsPaginationOptions={itemsPerPage:e.paginationOptions.itemsPerPage||"10",currentPage:e.paginationOptions.currentPage||1},e.paginationOptions=angular.copy(e.defaultsPaginationOptions),e.sortOptions=e._gridOptions.sort?angular.copy(e._gridOptions.sort):{},e.customFilters=e._gridOptions.customFilters?angular.copy(e._gridOptions.customFilters):{},e.urlSync=e._gridOptions.urlSync,e.$watch("_gridOptions.data",function(i){i&&i.length>-1&&(e.sortCache={},e.filtered=e._gridOptions.data.slice(),e.filters.forEach(function(i){"select"===i.filterType&&(e[i.model+"Options"]=t(e.filtered,i.filterBy))}),e.urlSync?c():p())}),e.sort=function(t,i){if(!i){var r=e.sortOptions.predicate===t&&"desc"===e.sortOptions.direction?"asc":"desc";e.sortOptions.direction=r,e.sortOptions.predicate=t}e.paginationOptions.currentPage=1,e.reloadGrid(i)},e.filter=function(){e.paginationOptions.currentPage=1,e.reloadGrid()},e.$on("$locationChangeSuccess",function(){o()}),e.$on("$stateChangeSuccess",function(t,e){o()}),e.reloadGrid=function(t){e.urlSync||e.serverPagination?s(t):p()},e._gridActions.refresh=e.reloadGrid,e._gridActions.filter=e.filter,e._gridActions.sort=e.sort}]).directive("gridItem",["$compile",function(t){return{restrict:"EA",terminal:!0,scope:!1,link:function(e,i,r,n,a){e.serverPagination?i.attr("ng-repeat","item in filtered"):i.attr("ng-repeat","item in filtered | startFrom:(paginationOptions.currentPage-1)*paginationOptions.itemsPerPage | limitTo:paginationOptions.itemsPerPage track by $index"),i.removeAttr("grid-item");var o=i[0].outerHTML;i.replaceWith(t(o)(e))}}}]).directive("gridData",["$compile","$animate",function(e){return{restrict:"EA",scope:!0,controller:"gridController",link:function(i,r,n){var a=[],o=r.parent(),s=n.id,c="true"===n.serverPagination;i.serverPagination=c,angular.forEach(angular.element(o[0].querySelectorAll("[sortable]")),function(t){var r=angular.element(t),n=r.attr("sortable");r.attr("ng-class","{'sort-ascent' : sortOptions.predicate ==='"+n+"' && sortOptions.direction === 'asc', 'sort-descent' : sortOptions.predicate === '"+n+"' && sortOptions.direction === 'desc'}"),r.attr("ng-click","sort('"+n+"')"),e(r)(i)}),angular.forEach(document.querySelectorAll("[filter-by]"),function(e){var n=angular.element(e),o=n.attr("filter-by"),c=document.querySelectorAll("[grid-data]")[0],l=c.querySelectorAll('[filter-by="'+o+'"]').length>0,p=n.attr("filter-type")||"",d=n.attr("ng-model"),g=n.attr("disable-url");s&&n.attr("grid-id")&&s!=n.attr("grid-id")||("select"!==p||(i[d+"Options"]=t(i.$eval(r.attr("grid-options")+".data"),o)),!~p.indexOf("date")||n.attr("ng-focus")||n.attr("ng-blur")||(n.attr("ng-focus","filter('{"+d+" : this."+d+"}')"),n.attr("ng-blur","filter('{"+d+" : this."+d+"}')")),d||(d=o,n.attr("ng-model",o),n.attr("ng-change","filter()")),a.push({model:d,isInScope:l,filterBy:o,filterType:p,disableUrl:g}))}),i.filters=a}}}]).factory("filtersFactory",function(){function t(t,e,i){return t.filter(function(t){return e&&t[i]?t[i]===e:!0})}function e(t,e,i){return t.filter(function(t){return e&&t[i]?~(t[i]+"").toLowerCase().indexOf((e+"").toLowerCase()):!!t[i]})}function i(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return e&&t[i]?t[i]<=e+86399999:!0})}function r(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return e&&t[i]?t[i]>=e:!0})}return{getFilterByType:function(n){switch(n){case"select":return t;case"text":return e;case"dateTo":return i;case"dateFrom":return r;default:return null}}}})}(); \ No newline at end of file +!function(){"use strict";function t(t,e){var i=[];if(t)return t.forEach(function(t){~i.indexOf(t[e])||i.push(t[e])}),i.map(function(t){return{text:t,value:t}})}angular.module("dataGrid",[]).filter("startFrom",function(){return function(t,e){return t?(e=+e,t.slice(e)):[]}}).controller("gridController",["$scope","$rootScope","$element","$filter","$location","filtersFactory",function(e,i,r,n,a,o){function s(){(e.urlSync||e.serverPagination)&&(e.serverPagination&&(clearTimeout(e.getDataTimeout),e.getDataTimeout=setTimeout(p,e.getDataDelay)),e.filtered&&l())}function c(t){var i,r=!1;i="page="+e.paginationOptions.currentPage,e.paginationOptions.itemsPerPage!==e.defaultsPaginationOptions.itemsPerPage&&(i+="&itemsPerPage="+e.paginationOptions.itemsPerPage),e.sortOptions.predicate&&(i+="&sort="+encodeURIComponent(e.sortOptions.predicate+"-"+e.sortOptions.direction)),e.filters.forEach(function(t){var n=t.model,a=t.isInScope?e.$eval(n):e.$parent.$eval(n);if(t.disableUrl)return void(r=!0);if(a){var o;if(a instanceof Date){if(isNaN(a.getTime()))return;o=a.getFullYear()+"-",o+=a.getMonth()<9?"0"+(a.getMonth()+1)+"-":a.getMonth()+1+"-",o+=a.getDate()<10?"0"+a.getDate():a.getDate(),a=o}i+="&"+encodeURIComponent(n)+"="+encodeURIComponent(a)}}),r&&d(),a.search(i),t&&e.$apply()}function l(){var t=a.search(),i={};if(Object.keys(t).forEach(function(e){"page"!==e&&"sort"!==e&&"itemsPerPage"!==e&&(i[e]=t[e])}),e.filters.forEach(function(t){var r=t.model,n=i[r];if(!t.disableUrl){if(~t.filterType.toLowerCase().indexOf("date"))return e.$parent.__evaltmp=n?new Date(n):null,void e.$parent.$eval(r+"=__evaltmp");"select"!==t.filterType||n||(n=""),n&&(t.isInScope?(e.__evaltmp=n,e.$eval(r+"=__evaltmp")):(e.$parent.__evaltmp=n,e.$parent.$eval(r+"=__evaltmp")))}}),e.paginationOptions.itemsPerPage=e.defaultsPaginationOptions.itemsPerPage,e.paginationOptions.currentPage=e.defaultsPaginationOptions.currentPage,t.itemsPerPage&&(e.paginationOptions.itemsPerPage=t.itemsPerPage),t.page&&(!e.serverPagination&&(t.page-1)*e.paginationOptions.itemsPerPage>e.filtered.length?e.paginationOptions.currentPage=1:e.paginationOptions.currentPage=t.page),t.sort){var r=t.sort.split("-");e.sortOptions.predicate=decodeURIComponent(r[0]),e.sortOptions.direction=decodeURIComponent(r[1])}e.serverPagination||d()}function p(){var t="",i=a.search();Object.keys(i).forEach(function(e){t+=e+"="+i[e]+"&"}),t=t.slice(0,-1),!t&&e.sortOptions.predicate?e.sort(e.sortOptions.predicate,!0):e._gridOptions.getData("?"+t,function(t,i){e.filtered=t,e.paginationOptions.totalItems=i})}function d(){var t=Date.now(),i=!1;e._time={},e.sortOptions.predicate&&e.sortCache&&e.sortCache.predicate===e.sortOptions.predicate&&e.sortCache.direction===e.sortOptions.direction?(e.filtered=e.sortCache.data.slice(),i=!0):e.filtered=e._gridOptions.data.slice(),e._time.copy=Date.now()-t;var r=Date.now();g(),e._time.filters=Date.now()-r;var a=Date.now();e.sortOptions.predicate&&!i&&(e.filtered=n("orderBy")(e.filtered,e.sortOptions.predicate,"desc"===e.sortOptions.direction),e.sortCache={data:e.filtered.slice(),predicate:e.sortOptions.predicate,direction:e.sortOptions.direction}),e._time.sort=Date.now()-a,e._time.all=Date.now()-t,e.paginationOptions.totalItems=e.filtered.length}function g(){e.filters.forEach(function(t){var i=t.filterBy,r=t.model,n=t.isInScope?e.$eval(r):e.$parent.$eval(r),a=t.filterType;if(e.customFilters[r])e.filtered=e.customFilters[r](e.filtered,n,i);else if(n&&a){var s=o.getFilterByType(a);s&&(e.filtered=s(e.filtered,n,i))}})}e._gridOptions=e.$eval(r.attr("grid-options")),e._gridActions=e.$eval(r.attr("grid-actions")),e.serverPagination="true"===r.attr("server-pagination"),e.getDataDelay=r.attr("get-delay")||350,e._gridActions||(e.$parent.$eval(r.attr("grid-actions")+"= {}"),e._gridActions=e.$parent.$eval(r.attr("grid-actions"))),e._gridOptions.grid=e,e.filtered=e._gridOptions.data.slice(),e.paginationOptions=e._gridOptions.pagination?angular.copy(e._gridOptions.pagination):{},e.defaultsPaginationOptions={itemsPerPage:e.paginationOptions.itemsPerPage||"10",currentPage:e.paginationOptions.currentPage||1},e.paginationOptions=angular.copy(e.defaultsPaginationOptions),e.sortOptions=e._gridOptions.sort?angular.copy(e._gridOptions.sort):{},e.customFilters=e._gridOptions.customFilters?angular.copy(e._gridOptions.customFilters):{},e.urlSync=e._gridOptions.urlSync,e.$watch("_gridOptions.data",function(i){i&&i.length>-1&&(e.sortCache={},e.filtered=e._gridOptions.data.slice(),e.filters.forEach(function(i){"select"===i.filterType&&(e[i.model+"Options"]=t(e.filtered,i.filterBy))}),e.urlSync?l():d())}),e.sort=function(t,i){if(!i){var r=e.sortOptions.predicate===t&&"desc"===e.sortOptions.direction?"asc":"desc";e.sortOptions.direction=r,e.sortOptions.predicate=t}e.paginationOptions.currentPage=1,e.reloadGrid(i)},e.filter=function(){e.paginationOptions.currentPage=1,e.reloadGrid()},e.$on("$locationChangeSuccess",function(){s()}),e.$on("$stateChangeSuccess",function(t,e){s()}),e.reloadGrid=function(t){e.urlSync||e.serverPagination?c(t):d(),i.$broadcast("gridReloaded")},e._gridActions.refresh=e.reloadGrid,e._gridActions.filter=e.filter,e._gridActions.sort=e.sort}]).directive("gridItem",["$compile",function(t){return{restrict:"EA",terminal:!0,scope:!1,link:function(e,i,r,n,a){e.serverPagination?i.attr("ng-repeat","item in filtered"):i.attr("ng-repeat","item in filtered | startFrom:(paginationOptions.currentPage-1)*paginationOptions.itemsPerPage | limitTo:paginationOptions.itemsPerPage track by $index"),i.removeAttr("grid-item");var o=i[0].outerHTML;i.replaceWith(t(o)(e))}}}]).directive("gridData",["$compile","$animate",function(e){return{restrict:"EA",scope:!0,controller:"gridController",link:function(i,r,n){var a=[],o=r.parent(),s=n.id,c="true"===n.serverPagination;i.serverPagination=c,angular.forEach(angular.element(o[0].querySelectorAll("[sortable]")),function(t){var r=angular.element(t),n=r.attr("sortable");r.attr("ng-class","{'sort-ascent' : sortOptions.predicate ==='"+n+"' && sortOptions.direction === 'asc', 'sort-descent' : sortOptions.predicate === '"+n+"' && sortOptions.direction === 'desc'}"),r.attr("ng-click","sort('"+n+"')"),e(r)(i)}),angular.forEach(document.querySelectorAll("[filter-by]"),function(e){var n=angular.element(e),o=n.attr("filter-by"),c=document.querySelectorAll("[grid-data]")[0],l=c.querySelectorAll('[filter-by="'+o+'"]').length>0,p=n.attr("filter-type")||"",d=n.attr("ng-model"),g=n.attr("disable-url");s&&n.attr("grid-id")&&s!=n.attr("grid-id")||("select"!==p||(i[d+"Options"]=t(i.$eval(r.attr("grid-options")+".data"),o)),!~p.indexOf("date")||n.attr("ng-focus")||n.attr("ng-blur")||(n.attr("ng-focus","filter('{"+d+" : this."+d+"}')"),n.attr("ng-blur","filter('{"+d+" : this."+d+"}')")),d||(d=o,n.attr("ng-model",o),n.attr("ng-change","filter()")),a.push({model:d,isInScope:l,filterBy:o,filterType:p,disableUrl:g}))}),i.filters=a}}}]).factory("filtersFactory",function(){function t(t,e,i){return t.filter(function(t){return!e||!t[i]||t[i]===e})}function e(t,e,i){return t.filter(function(t){return e&&t[i]?~(t[i]+"").toLowerCase().indexOf((e+"").toLowerCase()):!!t[i]})}function i(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return!e||!t[i]||t[i]<=e+86399999})}function r(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return!e||!t[i]||t[i]>=e})}return{getFilterByType:function(n){switch(n){case"select":return t;case"text":return e;case"dateTo":return i;case"dateFrom":return r;default:return null}}}})}(); \ No newline at end of file diff --git a/dist/dataGridUtils.js b/dist/dataGridUtils.js new file mode 100644 index 0000000..06f4061 --- /dev/null +++ b/dist/dataGridUtils.js @@ -0,0 +1,89 @@ +(function () { + 'use strict'; + angular.module('dataGridUtils', []); +})(); +(function () { + 'use strict'; + angular.module('dataGridUtils.fixedHeader', []) + .directive('fixedHeader', FixedHeader); + + FixedHeader.$inject = ['$window', '$timeout']; + + function FixedHeader($window, $timeout) { + var window = angular.element($window); + + return { + restrict: 'A', + link: link + }; + + function link(scope, element, attrs) { + var elementOffsetFrom = attrs.offsetFromElement ? + document.querySelector(attrs.offsetFromElement) : + window; + + function onResize() { + var thElements = element.find("th"); + for (var i = 0; i < thElements.length; i++) { + var tdElement = element.find("td").eq(i)[0]; + if (!tdElement) { + return; + } + var tdElementWidth = tdElement.offsetWidth; + angular.element(thElements[i]).css({'width': tdElementWidth + 'px'}); + } + } + + function bindFixedToHeader() { + var thead = element.find("thead"), + tbody = element.find("tbody"), + tbodyLeftPos = tbody[0].getBoundingClientRect().left; + thead.addClass('fixed-header'); + if (attrs.offsetFromElement) { + var topElement = document.querySelector(attrs.offsetFromElement); + var offset = topElement.getBoundingClientRect().top + topElement.offsetHeight; + thead.css({"top": offset}); + } + thead.css({"left": tbodyLeftPos}); + tbody.addClass("tbody-offset"); + } + + function unBindFixedToHeader() { + var thead = element.find("thead"), + tbody = element.find("tbody"); + thead.removeClass('fixed-header'); + thead.css({"left": ""}); + thead.css({"top": ""}); + tbody.removeClass("tbody-offset"); + } + + function onScroll() { + var offset = attrs.offsetFromElement ? + elementOffsetFrom.getBoundingClientRect().top + elementOffsetFrom.offsetHeight : + $window.pageYOffset, + tableOffsetTop = attrs.offsetFromElement ? + element[0].getBoundingClientRect().top : + element[0].getBoundingClientRect().top + offset, + tableOffsetBottom = tableOffsetTop + element[0].offsetHeight - element.find("thead")[0].offsetHeight; + + if (offset < tableOffsetTop || offset > tableOffsetBottom) { + unBindFixedToHeader(); + } + else if (offset >= tableOffsetTop && offset <= tableOffsetBottom) { + bindFixedToHeader(); + } + onResize(); + } + + scope.$on('gridReloaded', function () { + $timeout(function () { + onResize(); + onScroll(); + }, 0); + }); + window.on('resize', onResize); + window.on('scroll', onScroll); + } + } + +})(); \ No newline at end of file diff --git a/dist/dataGridUtils.min.js b/dist/dataGridUtils.min.js new file mode 100644 index 0000000..fa1410f --- /dev/null +++ b/dist/dataGridUtils.min.js @@ -0,0 +1 @@ +!function(){"use strict";angular.module("dataGridUtils",[])}(),function(){"use strict";function e(e,t){function n(n,f,i){function d(){for(var e=f.find("th"),t=0;to?s():t>=n&&t<=o&&r(),d()}var l=i.offsetFromElement?document.querySelector(i.offsetFromElement):o;n.$on("gridReloaded",function(){t(function(){d(),a()},0)}),o.on("resize",d),o.on("scroll",a)}var o=angular.element(e);return{restrict:"A",link:n}}angular.module("dataGridUtils.fixedHeader",[]).directive("fixedHeader",e),e.$inject=["$window","$timeout"]}(); \ No newline at end of file diff --git a/dist/loading-bar.min.js b/dist/loading-bar.min.js index f0fdc27..2d76439 100644 --- a/dist/loading-bar.min.js +++ b/dist/loading-bar.min.js @@ -1 +1 @@ -!function(){"use strict";angular.module("angular-loading-bar",["cfp.loadingBarInterceptor"]),angular.module("chieffancypants.loadingBar",["cfp.loadingBarInterceptor"]),angular.module("cfp.loadingBarInterceptor",["cfp.loadingBar"]).config(["$httpProvider",function(e){var n=["$q","$cacheFactory","$timeout","$rootScope","$log","cfpLoadingBar",function(n,t,a,r,i,c){function o(){a.cancel(d),c.complete(),u=0,s=0}function l(n){var a,r=t.get("$http"),i=e.defaults;!n.cache&&!i.cache||n.cache===!1||"GET"!==n.method&&"JSONP"!==n.method||(a=angular.isObject(n.cache)?n.cache:angular.isObject(i.cache)?i.cache:r);var c=void 0!==a?void 0!==a.get(n.url):!1;return void 0!==n.cached&&c!==n.cached?n.cached:(n.cached=c,c)}var d,s=0,u=0,g=c.latencyThreshold;return{request:function(e){return e.ignoreLoadingBar||l(e)||(r.$broadcast("cfpLoadingBar:loading",{url:e.url}),0===s&&(d=a(function(){c.start()},g)),s++,c.set(u/s)),e},response:function(e){return e&&e.config?(e.config.ignoreLoadingBar||l(e.config)||(u++,r.$broadcast("cfpLoadingBar:loaded",{url:e.config.url,result:e}),u>=s?o():c.set(u/s)),e):(i.error("Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),e)},responseError:function(e){return e&&e.config?(e.config.ignoreLoadingBar||l(e.config)||(u++,r.$broadcast("cfpLoadingBar:loaded",{url:e.config.url,result:e}),u>=s?o():c.set(u/s)),n.reject(e)):(i.error("Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),n.reject(e))}}}];e.interceptors.push(n)}]),angular.module("cfp.loadingBar",[]).provider("cfpLoadingBar",function(){this.includeSpinner=!0,this.includeBar=!0,this.latencyThreshold=100,this.startSize=.02,this.parentSelector="body",this.spinnerTemplate='
',this.loadingBarTemplate='
',this.$get=["$injector","$document","$timeout","$rootScope",function(e,n,t,a){function r(){s||(s=e.get("$animate"));var r=n.find(h).eq(0);t.cancel(g),m||(a.$broadcast("cfpLoadingBar:started"),m=!0,b&&s.enter(p,r,angular.element(r[0].lastChild)),$&&s.enter(v,r,angular.element(r[0].lastChild)),i(S))}function i(e){if(m){var n=100*e+"%";f.css("width",n),B=e,t.cancel(u),u=t(function(){c()},250)}}function c(){if(!(o()>=1)){var e=0,n=o();e=n>=0&&.25>n?(3*Math.random()+3)/100:n>=.25&&.65>n?3*Math.random()/100:n>=.65&&.9>n?2*Math.random()/100:n>=.9&&.99>n?.005:0;var t=o()+e;i(t)}}function o(){return B}function l(){B=0,m=!1}function d(){s||(s=e.get("$animate")),a.$broadcast("cfpLoadingBar:completed"),i(1),t.cancel(g),g=t(function(){var e=s.leave(p,l);e&&e.then&&e.then(l),s.leave(v)},500)}var s,u,g,h=this.parentSelector,p=angular.element(this.loadingBarTemplate),f=p.find("div").eq(0),v=angular.element(this.spinnerTemplate),m=!1,B=0,$=this.includeSpinner,b=this.includeBar,S=this.startSize;return{start:r,set:i,status:o,inc:c,complete:d,includeSpinner:this.includeSpinner,latencyThreshold:this.latencyThreshold,parentSelector:this.parentSelector,startSize:this.startSize}}]})}(); \ No newline at end of file +!function(){"use strict";angular.module("angular-loading-bar",["cfp.loadingBarInterceptor"]),angular.module("chieffancypants.loadingBar",["cfp.loadingBarInterceptor"]),angular.module("cfp.loadingBarInterceptor",["cfp.loadingBar"]).config(["$httpProvider",function(e){var n=["$q","$cacheFactory","$timeout","$rootScope","$log","cfpLoadingBar",function(n,t,a,r,i,c){function o(){a.cancel(d),c.complete(),u=0,s=0}function l(n){var a,r=t.get("$http"),i=e.defaults;!n.cache&&!i.cache||n.cache===!1||"GET"!==n.method&&"JSONP"!==n.method||(a=angular.isObject(n.cache)?n.cache:angular.isObject(i.cache)?i.cache:r);var c=void 0!==a&&void 0!==a.get(n.url);return void 0!==n.cached&&c!==n.cached?n.cached:(n.cached=c,c)}var d,s=0,u=0,g=c.latencyThreshold;return{request:function(e){return e.ignoreLoadingBar||l(e)||(r.$broadcast("cfpLoadingBar:loading",{url:e.url}),0===s&&(d=a(function(){c.start()},g)),s++,c.set(u/s)),e},response:function(e){return e&&e.config?(e.config.ignoreLoadingBar||l(e.config)||(u++,r.$broadcast("cfpLoadingBar:loaded",{url:e.config.url,result:e}),u>=s?o():c.set(u/s)),e):(i.error("Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),e)},responseError:function(e){return e&&e.config?(e.config.ignoreLoadingBar||l(e.config)||(u++,r.$broadcast("cfpLoadingBar:loaded",{url:e.config.url,result:e}),u>=s?o():c.set(u/s)),n.reject(e)):(i.error("Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),n.reject(e))}}}];e.interceptors.push(n)}]),angular.module("cfp.loadingBar",[]).provider("cfpLoadingBar",function(){this.includeSpinner=!0,this.includeBar=!0,this.latencyThreshold=100,this.startSize=.02,this.parentSelector="body",this.spinnerTemplate='
',this.loadingBarTemplate='
',this.$get=["$injector","$document","$timeout","$rootScope",function(e,n,t,a){function r(){s||(s=e.get("$animate"));var r=n.find(h).eq(0);t.cancel(g),m||(a.$broadcast("cfpLoadingBar:started"),m=!0,b&&s.enter(p,r,angular.element(r[0].lastChild)),$&&s.enter(v,r,angular.element(r[0].lastChild)),i(S))}function i(e){if(m){var n=100*e+"%";f.css("width",n),B=e,t.cancel(u),u=t(function(){c()},250)}}function c(){if(!(o()>=1)){var e=0,n=o();e=n>=0&&n<.25?(3*Math.random()+3)/100:n>=.25&&n<.65?3*Math.random()/100:n>=.65&&n<.9?2*Math.random()/100:n>=.9&&n<.99?.005:0;var t=o()+e;i(t)}}function o(){return B}function l(){B=0,m=!1}function d(){s||(s=e.get("$animate")),a.$broadcast("cfpLoadingBar:completed"),i(1),t.cancel(g),g=t(function(){var e=s.leave(p,l);e&&e.then&&e.then(l),s.leave(v)},500)}var s,u,g,h=this.parentSelector,p=angular.element(this.loadingBarTemplate),f=p.find("div").eq(0),v=angular.element(this.spinnerTemplate),m=!1,B=0,$=this.includeSpinner,b=this.includeBar,S=this.startSize;return{start:r,set:i,status:o,inc:c,complete:d,includeSpinner:this.includeSpinner,latencyThreshold:this.latencyThreshold,parentSelector:this.parentSelector,startSize:this.startSize}}]})}(); \ No newline at end of file diff --git a/dist/pagination.min.js b/dist/pagination.min.js index 3dcecb4..eea082a 100644 --- a/dist/pagination.min.js +++ b/dist/pagination.min.js @@ -1 +1 @@ -!function(){"use strict";angular.module("paging",[]).factory("paging",["$parse",function(e){return{create:function(a,n,t){a.setNumPages=t.numPages?e(t.numPages).assign:angular.noop,a.ngModelCtrl={$setViewValue:angular.noop},a.init=function(i,r){a.ngModelCtrl=i,a.config=r,i.$render=function(){a.render()},t.itemsPerPage?n.$parent.$watch(e(t.itemsPerPage),function(e){a.itemsPerPage=parseInt(e,10),n.totalPages=a.calculateTotalPages(),a.updatePage()}):a.itemsPerPage=r.itemsPerPage,n.$watch("totalItems",function(e,t){(angular.isDefined(e)||e!==t)&&(n.totalPages=a.calculateTotalPages(),a.updatePage())})},a.calculateTotalPages=function(){var e=a.itemsPerPage<1?1:Math.ceil(n.totalItems/a.itemsPerPage);return Math.max(e||0,1)},a.render=function(){n.page=parseInt(a.ngModelCtrl.$viewValue,10)||1},n.selectPage=function(e,t){t&&t.preventDefault();var i=!n.ngDisabled||!t;i&&n.page!==e&&e>0&&e<=n.totalPages&&(t&&t.target&&t.target.blur(),a.ngModelCtrl.$setViewValue(e),a.ngModelCtrl.$render())},n.getText=function(e){return n[e+"Text"]||a.config[e+"Text"]},n.noPrevious=function(){return 1===n.page},n.noNext=function(){return n.page===n.totalPages},a.updatePage=function(){a.setNumPages(n.$parent,n.totalPages),n.page>n.totalPages?n.selectPage(n.totalPages):a.ngModelCtrl.$render()}}}}]),angular.module("pagination",["paging"]).controller("PaginationController",["$scope","$attrs","$parse","paging","paginationConfig",function(e,a,n,t,i){function r(e,a,n){return{number:e,text:a,active:n}}function s(e,a){var n=[],t=1,i=a,s=angular.isDefined(g)&&a>g;s&&(o?(t=Math.max(e-Math.floor(g/2),1),i=t+g-1,i>a&&(i=a,t=i-g+1)):(t=(Math.ceil(e/g)-1)*g+1,i=Math.min(t+g-1,a)));for(var l=t;i>=l;l++){var p=r(l,l,l===e);n.push(p)}if(s&&g>0&&(!o||u||c)){if(t>1){if(!c||t>3){var f=r(t-1,"...",!1);n.unshift(f)}if(c){if(3===t){var d=r(2,"2",!1);n.unshift(d)}var P=r(1,"1",!1);n.unshift(P)}}if(a>i){if(!c||a-2>i){var v=r(i+1,"...",!1);n.push(v)}if(c){if(i===a-2){var m=r(a-1,a-1,!1);n.push(m)}var $=r(a,a,!1);n.push($)}}}return n}var l=this,g=angular.isDefined(a.maxSize)?e.$parent.$eval(a.maxSize):i.maxSize,o=angular.isDefined(a.rotate)?e.$parent.$eval(a.rotate):i.rotate,u=angular.isDefined(a.forceEllipses)?e.$parent.$eval(a.forceEllipses):i.forceEllipses,c=angular.isDefined(a.boundaryLinkNumbers)?e.$parent.$eval(a.boundaryLinkNumbers):i.boundaryLinkNumbers;e.boundaryLinks=angular.isDefined(a.boundaryLinks)?e.$parent.$eval(a.boundaryLinks):i.boundaryLinks,e.directionLinks=angular.isDefined(a.directionLinks)?e.$parent.$eval(a.directionLinks):i.directionLinks,t.create(this,e,a),a.maxSize&&e.$parent.$watch(n(a.maxSize),function(e){g=parseInt(e,10),l.render()});var p=this.render;this.render=function(){p(),e.page>0&&e.page<=e.totalPages&&(e.pages=s(e.page,e.totalPages))}}]).constant("paginationConfig",{itemsPerPage:10,boundaryLinks:!1,boundaryLinkNumbers:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0,forceEllipses:!1}).directive("gridPagination",["$parse","paginationConfig",function(e,a){return{scope:{totalItems:"=",firstText:"@",previousText:"@",nextText:"@",lastText:"@",ngDisabled:"="},require:["gridPagination","?ngModel"],controller:"PaginationController",controllerAs:"pagination",templateUrl:function(e,a){return a.templateUrl||"src/template/pagination/pagination.html"},replace:!0,link:function(e,n,t,i){var r=i[0],s=i[1];s&&r.init(s,a)}}}]).run(["$templateCache",function(e){e.put("src/template/pagination/pagination.html","")}])}(); \ No newline at end of file +!function(){"use strict";angular.module("paging",[]).factory("paging",["$parse",function(e){return{create:function(a,n,t){a.setNumPages=t.numPages?e(t.numPages).assign:angular.noop,a.ngModelCtrl={$setViewValue:angular.noop},a.init=function(i,r){a.ngModelCtrl=i,a.config=r,i.$render=function(){a.render()},t.itemsPerPage?n.$parent.$watch(e(t.itemsPerPage),function(e){a.itemsPerPage=parseInt(e,10),n.totalPages=a.calculateTotalPages(),a.updatePage()}):a.itemsPerPage=r.itemsPerPage,n.$watch("totalItems",function(e,t){(angular.isDefined(e)||e!==t)&&(n.totalPages=a.calculateTotalPages(),a.updatePage())})},a.calculateTotalPages=function(){var e=a.itemsPerPage<1?1:Math.ceil(n.totalItems/a.itemsPerPage);return Math.max(e||0,1)},a.render=function(){n.page=parseInt(a.ngModelCtrl.$viewValue,10)||1},n.selectPage=function(e,t){t&&t.preventDefault();var i=!n.ngDisabled||!t;i&&n.page!==e&&e>0&&e<=n.totalPages&&(t&&t.target&&t.target.blur(),a.ngModelCtrl.$setViewValue(e),a.ngModelCtrl.$render())},n.getText=function(e){return n[e+"Text"]||a.config[e+"Text"]},n.noPrevious=function(){return 1===n.page},n.noNext=function(){return n.page===n.totalPages},a.updatePage=function(){a.setNumPages(n.$parent,n.totalPages),n.page>n.totalPages?n.selectPage(n.totalPages):a.ngModelCtrl.$render()}}}}]),angular.module("pagination",["paging"]).controller("PaginationController",["$scope","$attrs","$parse","paging","paginationConfig",function(e,a,n,t,i){function r(e,a,n){return{number:e,text:a,active:n}}function s(e,a){var n=[],t=1,i=a,s=angular.isDefined(g)&&ga&&(i=a,t=i-g+1)):(t=(Math.ceil(e/g)-1)*g+1,i=Math.min(t+g-1,a)));for(var l=t;l<=i;l++){var p=r(l,l,l===e);n.push(p)}if(s&&g>0&&(!o||u||c)){if(t>1){if(!c||t>3){var f=r(t-1,"...",!1);n.unshift(f)}if(c){if(3===t){var d=r(2,"2",!1);n.unshift(d)}var P=r(1,"1",!1);n.unshift(P)}}if(i0&&e.page<=e.totalPages&&(e.pages=s(e.page,e.totalPages))}}]).constant("paginationConfig",{itemsPerPage:10,boundaryLinks:!1,boundaryLinkNumbers:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0,forceEllipses:!1}).directive("gridPagination",["$parse","paginationConfig",function(e,a){return{scope:{totalItems:"=",firstText:"@",previousText:"@",nextText:"@",lastText:"@",ngDisabled:"="},require:["gridPagination","?ngModel"],controller:"PaginationController",controllerAs:"pagination",templateUrl:function(e,a){return a.templateUrl||"src/template/pagination/pagination.html"},replace:!0,link:function(e,n,t,i){var r=i[0],s=i[1];s&&r.init(s,a)}}}]).run(["$templateCache",function(e){e.put("src/template/pagination/pagination.html","")}])}(); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index d3a2af8..cea1115 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -21,7 +21,7 @@ } gulp.task('js', function () { - gulp.src(['./src/**/*.js']) + gulp.src(['./src/js/vendors/*.js', './src/js/*.js']) .pipe(rename({dirname: ''})) .pipe(gulp.dest('./dist')) .pipe(uglify()) @@ -29,6 +29,15 @@ suffix: ".min" })) .pipe(gulp.dest('./dist')); + + gulp.src(['./src/js/directives/**/*.js']) + .pipe(concat('dataGridUtils.js')) + .pipe(gulp.dest('./dist')) + .pipe(uglify()) + .pipe(rename({ + suffix: ".min" + })) + .pipe(gulp.dest('./dist')); }); gulp.task('sass', function () { @@ -41,6 +50,15 @@ gulp.src('./demo/100k/scss/angular-data-grid.bootstrap.scss') .pipe(sass().on('error', sass.logError)) .pipe(gulp.dest('./demo/100k/css/')); + gulp.src('./demo/fixed-header/scss/fixed-header.bootstrap.scss') + .pipe(sass().on('error', sass.logError)) + .pipe(gulp.dest('./demo/fixed-header/css/')); + gulp.src('./demo/fixed-header/scss/fixed-header.material.scss') + .pipe(sass().on('error', sass.logError)) + .pipe(gulp.dest('./demo/fixed-header/css/')); + gulp.src('./src/js/directives/fixedHeader/fixed-header.scss') + .pipe(sass().on('error', sass.logError)) + .pipe(gulp.dest('./dist/css/fixedHeader/')); }); gulp.task('build', ['js', 'sass']); diff --git a/src/js/dataGrid.js b/src/js/dataGrid.js index 1ae356c..7ed9847 100644 --- a/src/js/dataGrid.js +++ b/src/js/dataGrid.js @@ -12,7 +12,7 @@ return []; } }) - .controller('gridController', ['$scope', '$element', '$filter', '$location', 'filtersFactory', function ($scope, $element, $filter, $location, filtersFactory) { + .controller('gridController', ['$scope', '$rootScope', '$element', '$filter', '$location', 'filtersFactory', function ($scope, $rootScope, $element, $filter, $location, filtersFactory) { // values by default $scope._gridOptions = $scope.$eval($element.attr('grid-options')); $scope._gridActions = $scope.$eval($element.attr('grid-actions')); @@ -84,6 +84,7 @@ } else { applyFilters(); } + $rootScope.$broadcast('gridReloaded'); }; $scope._gridActions.refresh = $scope.reloadGrid; diff --git a/src/js/directives/dataGridUtils.js b/src/js/directives/dataGridUtils.js new file mode 100644 index 0000000..11f7813 --- /dev/null +++ b/src/js/directives/dataGridUtils.js @@ -0,0 +1,4 @@ +(function () { + 'use strict'; + angular.module('dataGridUtils', []); +})(); \ No newline at end of file diff --git a/src/js/directives/fixedHeader/fixed-header.scss b/src/js/directives/fixedHeader/fixed-header.scss new file mode 100644 index 0000000..eeea5eb --- /dev/null +++ b/src/js/directives/fixedHeader/fixed-header.scss @@ -0,0 +1,15 @@ +//Here are described styles that are used bu fixed-header directive +.fixed-header { + top: 0; + position: fixed; + width: auto; + display: table; + z-index: 99; +} + +.tbody-offset { + &:before { + content: " "; + display: block; + } +} \ No newline at end of file diff --git a/src/js/directives/fixedHeader/fixedHeader.js b/src/js/directives/fixedHeader/fixedHeader.js new file mode 100644 index 0000000..8242357 --- /dev/null +++ b/src/js/directives/fixedHeader/fixedHeader.js @@ -0,0 +1,85 @@ +(function () { + 'use strict'; + angular.module('dataGridUtils.fixedHeader', []) + .directive('fixedHeader', FixedHeader); + + FixedHeader.$inject = ['$window', '$timeout']; + + function FixedHeader($window, $timeout) { + var window = angular.element($window); + + return { + restrict: 'A', + link: link + }; + + function link(scope, element, attrs) { + var elementOffsetFrom = attrs.offsetFromElement ? + document.querySelector(attrs.offsetFromElement) : + window; + + function onResize() { + var thElements = element.find("th"); + for (var i = 0; i < thElements.length; i++) { + var tdElement = element.find("td").eq(i)[0]; + if (!tdElement) { + return; + } + var tdElementWidth = tdElement.offsetWidth; + angular.element(thElements[i]).css({'width': tdElementWidth + 'px'}); + } + } + + function bindFixedToHeader() { + var thead = element.find("thead"), + tbody = element.find("tbody"), + tbodyLeftPos = tbody[0].getBoundingClientRect().left; + thead.addClass('fixed-header'); + if (attrs.offsetFromElement) { + var topElement = document.querySelector(attrs.offsetFromElement); + var offset = topElement.getBoundingClientRect().top + topElement.offsetHeight; + thead.css({"top": offset}); + } + thead.css({"left": tbodyLeftPos}); + tbody.addClass("tbody-offset"); + } + + function unBindFixedToHeader() { + var thead = element.find("thead"), + tbody = element.find("tbody"); + thead.removeClass('fixed-header'); + thead.css({"left": ""}); + thead.css({"top": ""}); + tbody.removeClass("tbody-offset"); + } + + function onScroll() { + var offset = attrs.offsetFromElement ? + elementOffsetFrom.getBoundingClientRect().top + elementOffsetFrom.offsetHeight : + $window.pageYOffset, + tableOffsetTop = attrs.offsetFromElement ? + element[0].getBoundingClientRect().top : + element[0].getBoundingClientRect().top + offset, + tableOffsetBottom = tableOffsetTop + element[0].offsetHeight - element.find("thead")[0].offsetHeight; + + if (offset < tableOffsetTop || offset > tableOffsetBottom) { + unBindFixedToHeader(); + } + else if (offset >= tableOffsetTop && offset <= tableOffsetBottom) { + bindFixedToHeader(); + } + onResize(); + } + + scope.$on('gridReloaded', function () { + $timeout(function () { + onResize(); + onScroll(); + }, 0); + }); + window.on('resize', onResize); + window.on('scroll', onScroll); + } + } + +})(); \ No newline at end of file From 647e08141e17f237cddfe7bec6433aefdeed423d Mon Sep 17 00:00:00 2001 From: Andrey Chayko Date: Mon, 10 Apr 2017 13:11:41 +0300 Subject: [PATCH 22/40] Added links to codepen, updated readme.md, added links to additional demos --- README.md | 3 ++- demo/bootstrap/index.html | 3 +++ demo/fixed-header/angular-md-grid.html | 4 ++-- demo/fixed-header/bootstrap-grid.html | 4 ++-- demo/material/index.html | 6 ++++++ 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a453e66..8dc4aab 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ Demo Angular UI Router: http://angular-data-grid.github.io/demo/bootstrap/ui-rou - Does not have any hard-coded template so you can choose any mark-up you need, from basic `` layout to any `
` structure. - Easily switch between the most popular Bootstrap and Google Material theming, or apply your own CSS theme just by changing several CSS classes. - Built-in sync with browser address bar (URL), so you can copy-n-paste sorting/filtering/pagination results URL and open it in other browser / send to anyone - even if pagination / filtering are done on a client-side. [See details](#url-synchronization) - - Support of [Angular UI Router](https://github.com/angular-ui/ui-router) navigation. + - Support of [Angular UI Router](https://github.com/angular-ui/ui-router) navigation. + - Optional support of fixed header table: [bootstrap Demo](https://github.com/angular-data-grid/demo/fixed-header/bootstrap-grid.html) [Material Design Demo](https://github.com/angular-data-grid/demo/fixed-header/angular-md-grid.html) - Unlike most part of other Angular DataGrids, we intentionally use non-isolated scope of the directive to maximize flexibility, so it can be easily synchronized with any data changes inside your controller. NOTE! With great power comes great responsibility, so use non-isolated API wisely. diff --git a/demo/bootstrap/index.html b/demo/bootstrap/index.html index b0919de..4bbbed7 100644 --- a/demo/bootstrap/index.html +++ b/demo/bootstrap/index.html @@ -48,6 +48,9 @@

Additional Demos

  • UI Router plus server pagination
  • +
  • + Fixed header table +

  • diff --git a/demo/fixed-header/angular-md-grid.html b/demo/fixed-header/angular-md-grid.html index 134befc..6d47d72 100644 --- a/demo/fixed-header/angular-md-grid.html +++ b/demo/fixed-header/angular-md-grid.html @@ -245,9 +245,9 @@

    Using Stand-alone Directive


    CodePen
    -

    See the Pen eJWWpM by AngularDataGrid (eJWWpM by AngularDataGrid (@AngularDataGrid) on CodePen.

    diff --git a/demo/fixed-header/bootstrap-grid.html b/demo/fixed-header/bootstrap-grid.html index bf2d003..6a13d59 100644 --- a/demo/fixed-header/bootstrap-grid.html +++ b/demo/fixed-header/bootstrap-grid.html @@ -285,8 +285,8 @@

    Additional Demos

    -

    See the Pen xZddZm by AngularDataGrid (@AngularDataGrid) on CodePen.

    +

    See the Pen xZddZm by AngularDataGrid (@AngularDataGrid) on CodePen.

    diff --git a/demo/material/index.html b/demo/material/index.html index 9702465..d14dafa 100644 --- a/demo/material/index.html +++ b/demo/material/index.html @@ -44,6 +44,12 @@

    Angular Data Grid sample using Material Design styling

    Project GitHub

    +

    Additional Demos

    +
    From 9872f03409a7c5c60cbde9b19019fc52f3c31a7a Mon Sep 17 00:00:00 2001 From: Andrey Chayko Date: Mon, 10 Apr 2017 13:16:56 +0300 Subject: [PATCH 23/40] Updated readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8dc4aab..1ea0f5b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Demo Angular UI Router: http://angular-data-grid.github.io/demo/bootstrap/ui-rou - Easily switch between the most popular Bootstrap and Google Material theming, or apply your own CSS theme just by changing several CSS classes. - Built-in sync with browser address bar (URL), so you can copy-n-paste sorting/filtering/pagination results URL and open it in other browser / send to anyone - even if pagination / filtering are done on a client-side. [See details](#url-synchronization) - Support of [Angular UI Router](https://github.com/angular-ui/ui-router) navigation. - - Optional support of fixed header table: [bootstrap Demo](https://github.com/angular-data-grid/demo/fixed-header/bootstrap-grid.html) [Material Design Demo](https://github.com/angular-data-grid/demo/fixed-header/angular-md-grid.html) + - Optional support of fixed header table: [Bootstrap Demo](http://angular-data-grid.github.io/demo/fixed-header/bootstrap-grid.html) [Material Design Demo](http://angular-data-grid.github.io/demo/fixed-header/angular-md-grid.html) - Unlike most part of other Angular DataGrids, we intentionally use non-isolated scope of the directive to maximize flexibility, so it can be easily synchronized with any data changes inside your controller. NOTE! With great power comes great responsibility, so use non-isolated API wisely. From d8492cd0ecb10a448212cfa78bca9e23f4d8b35e Mon Sep 17 00:00:00 2001 From: Andrey Chayko Date: Mon, 10 Apr 2017 14:37:34 +0300 Subject: [PATCH 24/40] Modified fixed-header sample links structure --- demo/bootstrap/index.html | 2 +- demo/fixed-header/angular-md-grid.html | 21 +++------------ demo/fixed-header/bootstrap-grid.html | 36 ++++---------------------- demo/material/index.html | 2 +- 4 files changed, 10 insertions(+), 51 deletions(-) diff --git a/demo/bootstrap/index.html b/demo/bootstrap/index.html index 4bbbed7..061eb5b 100644 --- a/demo/bootstrap/index.html +++ b/demo/bootstrap/index.html @@ -49,7 +49,7 @@

    Additional Demos

    UI Router plus server pagination
  • - Fixed header table + Fixed header table

  • diff --git a/demo/fixed-header/angular-md-grid.html b/demo/fixed-header/angular-md-grid.html index 6d47d72..d828b6c 100644 --- a/demo/fixed-header/angular-md-grid.html +++ b/demo/fixed-header/angular-md-grid.html @@ -17,30 +17,15 @@
    Angular Data Grid — Material Design - - - - Change theme - arrow_drop_down - - - - - Bootstrap Design - - - Material Design - - - +
    -

    Angular Data Grid sample using Material Design styling

    +

    Fix Header Table

    -

    Features enabled: sorting, filtering, sync with browser URLs, pagination and item-per-page functionality. +

    Features enabled: sorting, filtering, sync with browser URLs, pagination, item-per-page and fixed-header functionality. Out-of-box Angular Material layout and input controls used, along with Material Design Light default CSS for diff --git a/demo/fixed-header/bootstrap-grid.html b/demo/fixed-header/bootstrap-grid.html index 6a13d59..d56420c 100644 --- a/demo/fixed-header/bootstrap-grid.html +++ b/demo/fixed-header/bootstrap-grid.html @@ -14,25 +14,15 @@

    -

    Angular Data Grid sample using out-of-box Bootstrap styling

    - Features enabled: sorting, filtering (using both in-grid and external controls), sync with browser URLs, pagination and items-per-page functionality. +

    Fix Header Table

    + Features enabled: sorting, filtering (using both in-grid and external controls), sync with browser URLs, pagination, items-per-page and fixed-header functionality. Angular UI Datepicker used for date controls, although you can use any other framework, plugin or styling. Project GitHub
    @@ -98,22 +88,6 @@

    Using Stand-alone Directive


    -

    Additional Demos

    - -
    diff --git a/demo/material/index.html b/demo/material/index.html index d14dafa..a9846db 100644 --- a/demo/material/index.html +++ b/demo/material/index.html @@ -47,7 +47,7 @@

    Angular Data Grid sample using Material Design styling

    Additional Demos


    From 616677792f6a671f9ec4e6c4e51d6eee72f4271c Mon Sep 17 00:00:00 2001 From: Igor Korshuk Date: Tue, 11 Apr 2017 16:43:38 +0300 Subject: [PATCH 25/40] #34 reloading the grid after changes in the grid-data --- dist/dataGrid.js | 2 +- dist/dataGrid.min.js | 2 +- src/js/dataGrid.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/dataGrid.js b/dist/dataGrid.js index 7ed9847..14ee687 100644 --- a/dist/dataGrid.js +++ b/dist/dataGrid.js @@ -37,7 +37,7 @@ $scope.customFilters = $scope._gridOptions.customFilters ? angular.copy($scope._gridOptions.customFilters) : {}; $scope.urlSync = $scope._gridOptions.urlSync; - $scope.$watch('_gridOptions.data', function (newValue) { + $scope.$watchCollection('_gridOptions.data', function (newValue) { if (newValue && newValue.length > -1) { $scope.sortCache = {}; $scope.filtered = $scope._gridOptions.data.slice(); diff --git a/dist/dataGrid.min.js b/dist/dataGrid.min.js index 2789310..0aa1794 100644 --- a/dist/dataGrid.min.js +++ b/dist/dataGrid.min.js @@ -1 +1 @@ -!function(){"use strict";function t(t,e){var i=[];if(t)return t.forEach(function(t){~i.indexOf(t[e])||i.push(t[e])}),i.map(function(t){return{text:t,value:t}})}angular.module("dataGrid",[]).filter("startFrom",function(){return function(t,e){return t?(e=+e,t.slice(e)):[]}}).controller("gridController",["$scope","$rootScope","$element","$filter","$location","filtersFactory",function(e,i,r,n,a,o){function s(){(e.urlSync||e.serverPagination)&&(e.serverPagination&&(clearTimeout(e.getDataTimeout),e.getDataTimeout=setTimeout(p,e.getDataDelay)),e.filtered&&l())}function c(t){var i,r=!1;i="page="+e.paginationOptions.currentPage,e.paginationOptions.itemsPerPage!==e.defaultsPaginationOptions.itemsPerPage&&(i+="&itemsPerPage="+e.paginationOptions.itemsPerPage),e.sortOptions.predicate&&(i+="&sort="+encodeURIComponent(e.sortOptions.predicate+"-"+e.sortOptions.direction)),e.filters.forEach(function(t){var n=t.model,a=t.isInScope?e.$eval(n):e.$parent.$eval(n);if(t.disableUrl)return void(r=!0);if(a){var o;if(a instanceof Date){if(isNaN(a.getTime()))return;o=a.getFullYear()+"-",o+=a.getMonth()<9?"0"+(a.getMonth()+1)+"-":a.getMonth()+1+"-",o+=a.getDate()<10?"0"+a.getDate():a.getDate(),a=o}i+="&"+encodeURIComponent(n)+"="+encodeURIComponent(a)}}),r&&d(),a.search(i),t&&e.$apply()}function l(){var t=a.search(),i={};if(Object.keys(t).forEach(function(e){"page"!==e&&"sort"!==e&&"itemsPerPage"!==e&&(i[e]=t[e])}),e.filters.forEach(function(t){var r=t.model,n=i[r];if(!t.disableUrl){if(~t.filterType.toLowerCase().indexOf("date"))return e.$parent.__evaltmp=n?new Date(n):null,void e.$parent.$eval(r+"=__evaltmp");"select"!==t.filterType||n||(n=""),n&&(t.isInScope?(e.__evaltmp=n,e.$eval(r+"=__evaltmp")):(e.$parent.__evaltmp=n,e.$parent.$eval(r+"=__evaltmp")))}}),e.paginationOptions.itemsPerPage=e.defaultsPaginationOptions.itemsPerPage,e.paginationOptions.currentPage=e.defaultsPaginationOptions.currentPage,t.itemsPerPage&&(e.paginationOptions.itemsPerPage=t.itemsPerPage),t.page&&(!e.serverPagination&&(t.page-1)*e.paginationOptions.itemsPerPage>e.filtered.length?e.paginationOptions.currentPage=1:e.paginationOptions.currentPage=t.page),t.sort){var r=t.sort.split("-");e.sortOptions.predicate=decodeURIComponent(r[0]),e.sortOptions.direction=decodeURIComponent(r[1])}e.serverPagination||d()}function p(){var t="",i=a.search();Object.keys(i).forEach(function(e){t+=e+"="+i[e]+"&"}),t=t.slice(0,-1),!t&&e.sortOptions.predicate?e.sort(e.sortOptions.predicate,!0):e._gridOptions.getData("?"+t,function(t,i){e.filtered=t,e.paginationOptions.totalItems=i})}function d(){var t=Date.now(),i=!1;e._time={},e.sortOptions.predicate&&e.sortCache&&e.sortCache.predicate===e.sortOptions.predicate&&e.sortCache.direction===e.sortOptions.direction?(e.filtered=e.sortCache.data.slice(),i=!0):e.filtered=e._gridOptions.data.slice(),e._time.copy=Date.now()-t;var r=Date.now();g(),e._time.filters=Date.now()-r;var a=Date.now();e.sortOptions.predicate&&!i&&(e.filtered=n("orderBy")(e.filtered,e.sortOptions.predicate,"desc"===e.sortOptions.direction),e.sortCache={data:e.filtered.slice(),predicate:e.sortOptions.predicate,direction:e.sortOptions.direction}),e._time.sort=Date.now()-a,e._time.all=Date.now()-t,e.paginationOptions.totalItems=e.filtered.length}function g(){e.filters.forEach(function(t){var i=t.filterBy,r=t.model,n=t.isInScope?e.$eval(r):e.$parent.$eval(r),a=t.filterType;if(e.customFilters[r])e.filtered=e.customFilters[r](e.filtered,n,i);else if(n&&a){var s=o.getFilterByType(a);s&&(e.filtered=s(e.filtered,n,i))}})}e._gridOptions=e.$eval(r.attr("grid-options")),e._gridActions=e.$eval(r.attr("grid-actions")),e.serverPagination="true"===r.attr("server-pagination"),e.getDataDelay=r.attr("get-delay")||350,e._gridActions||(e.$parent.$eval(r.attr("grid-actions")+"= {}"),e._gridActions=e.$parent.$eval(r.attr("grid-actions"))),e._gridOptions.grid=e,e.filtered=e._gridOptions.data.slice(),e.paginationOptions=e._gridOptions.pagination?angular.copy(e._gridOptions.pagination):{},e.defaultsPaginationOptions={itemsPerPage:e.paginationOptions.itemsPerPage||"10",currentPage:e.paginationOptions.currentPage||1},e.paginationOptions=angular.copy(e.defaultsPaginationOptions),e.sortOptions=e._gridOptions.sort?angular.copy(e._gridOptions.sort):{},e.customFilters=e._gridOptions.customFilters?angular.copy(e._gridOptions.customFilters):{},e.urlSync=e._gridOptions.urlSync,e.$watch("_gridOptions.data",function(i){i&&i.length>-1&&(e.sortCache={},e.filtered=e._gridOptions.data.slice(),e.filters.forEach(function(i){"select"===i.filterType&&(e[i.model+"Options"]=t(e.filtered,i.filterBy))}),e.urlSync?l():d())}),e.sort=function(t,i){if(!i){var r=e.sortOptions.predicate===t&&"desc"===e.sortOptions.direction?"asc":"desc";e.sortOptions.direction=r,e.sortOptions.predicate=t}e.paginationOptions.currentPage=1,e.reloadGrid(i)},e.filter=function(){e.paginationOptions.currentPage=1,e.reloadGrid()},e.$on("$locationChangeSuccess",function(){s()}),e.$on("$stateChangeSuccess",function(t,e){s()}),e.reloadGrid=function(t){e.urlSync||e.serverPagination?c(t):d(),i.$broadcast("gridReloaded")},e._gridActions.refresh=e.reloadGrid,e._gridActions.filter=e.filter,e._gridActions.sort=e.sort}]).directive("gridItem",["$compile",function(t){return{restrict:"EA",terminal:!0,scope:!1,link:function(e,i,r,n,a){e.serverPagination?i.attr("ng-repeat","item in filtered"):i.attr("ng-repeat","item in filtered | startFrom:(paginationOptions.currentPage-1)*paginationOptions.itemsPerPage | limitTo:paginationOptions.itemsPerPage track by $index"),i.removeAttr("grid-item");var o=i[0].outerHTML;i.replaceWith(t(o)(e))}}}]).directive("gridData",["$compile","$animate",function(e){return{restrict:"EA",scope:!0,controller:"gridController",link:function(i,r,n){var a=[],o=r.parent(),s=n.id,c="true"===n.serverPagination;i.serverPagination=c,angular.forEach(angular.element(o[0].querySelectorAll("[sortable]")),function(t){var r=angular.element(t),n=r.attr("sortable");r.attr("ng-class","{'sort-ascent' : sortOptions.predicate ==='"+n+"' && sortOptions.direction === 'asc', 'sort-descent' : sortOptions.predicate === '"+n+"' && sortOptions.direction === 'desc'}"),r.attr("ng-click","sort('"+n+"')"),e(r)(i)}),angular.forEach(document.querySelectorAll("[filter-by]"),function(e){var n=angular.element(e),o=n.attr("filter-by"),c=document.querySelectorAll("[grid-data]")[0],l=c.querySelectorAll('[filter-by="'+o+'"]').length>0,p=n.attr("filter-type")||"",d=n.attr("ng-model"),g=n.attr("disable-url");s&&n.attr("grid-id")&&s!=n.attr("grid-id")||("select"!==p||(i[d+"Options"]=t(i.$eval(r.attr("grid-options")+".data"),o)),!~p.indexOf("date")||n.attr("ng-focus")||n.attr("ng-blur")||(n.attr("ng-focus","filter('{"+d+" : this."+d+"}')"),n.attr("ng-blur","filter('{"+d+" : this."+d+"}')")),d||(d=o,n.attr("ng-model",o),n.attr("ng-change","filter()")),a.push({model:d,isInScope:l,filterBy:o,filterType:p,disableUrl:g}))}),i.filters=a}}}]).factory("filtersFactory",function(){function t(t,e,i){return t.filter(function(t){return!e||!t[i]||t[i]===e})}function e(t,e,i){return t.filter(function(t){return e&&t[i]?~(t[i]+"").toLowerCase().indexOf((e+"").toLowerCase()):!!t[i]})}function i(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return!e||!t[i]||t[i]<=e+86399999})}function r(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return!e||!t[i]||t[i]>=e})}return{getFilterByType:function(n){switch(n){case"select":return t;case"text":return e;case"dateTo":return i;case"dateFrom":return r;default:return null}}}})}(); \ No newline at end of file +!function(){"use strict";function t(t,e){var i=[];if(t)return t.forEach(function(t){~i.indexOf(t[e])||i.push(t[e])}),i.map(function(t){return{text:t,value:t}})}angular.module("dataGrid",[]).filter("startFrom",function(){return function(t,e){return t?(e=+e,t.slice(e)):[]}}).controller("gridController",["$scope","$rootScope","$element","$filter","$location","filtersFactory",function(e,i,r,n,a,o){function s(){(e.urlSync||e.serverPagination)&&(e.serverPagination&&(clearTimeout(e.getDataTimeout),e.getDataTimeout=setTimeout(p,e.getDataDelay)),e.filtered&&l())}function c(t){var i,r=!1;i="page="+e.paginationOptions.currentPage,e.paginationOptions.itemsPerPage!==e.defaultsPaginationOptions.itemsPerPage&&(i+="&itemsPerPage="+e.paginationOptions.itemsPerPage),e.sortOptions.predicate&&(i+="&sort="+encodeURIComponent(e.sortOptions.predicate+"-"+e.sortOptions.direction)),e.filters.forEach(function(t){var n=t.model,a=t.isInScope?e.$eval(n):e.$parent.$eval(n);if(t.disableUrl)return void(r=!0);if(a){var o;if(a instanceof Date){if(isNaN(a.getTime()))return;o=a.getFullYear()+"-",o+=a.getMonth()<9?"0"+(a.getMonth()+1)+"-":a.getMonth()+1+"-",o+=a.getDate()<10?"0"+a.getDate():a.getDate(),a=o}i+="&"+encodeURIComponent(n)+"="+encodeURIComponent(a)}}),r&&d(),a.search(i),t&&e.$apply()}function l(){var t=a.search(),i={};if(Object.keys(t).forEach(function(e){"page"!==e&&"sort"!==e&&"itemsPerPage"!==e&&(i[e]=t[e])}),e.filters.forEach(function(t){var r=t.model,n=i[r];if(!t.disableUrl){if(~t.filterType.toLowerCase().indexOf("date"))return e.$parent.__evaltmp=n?new Date(n):null,void e.$parent.$eval(r+"=__evaltmp");"select"!==t.filterType||n||(n=""),n&&(t.isInScope?(e.__evaltmp=n,e.$eval(r+"=__evaltmp")):(e.$parent.__evaltmp=n,e.$parent.$eval(r+"=__evaltmp")))}}),e.paginationOptions.itemsPerPage=e.defaultsPaginationOptions.itemsPerPage,e.paginationOptions.currentPage=e.defaultsPaginationOptions.currentPage,t.itemsPerPage&&(e.paginationOptions.itemsPerPage=t.itemsPerPage),t.page&&(!e.serverPagination&&(t.page-1)*e.paginationOptions.itemsPerPage>e.filtered.length?e.paginationOptions.currentPage=1:e.paginationOptions.currentPage=t.page),t.sort){var r=t.sort.split("-");e.sortOptions.predicate=decodeURIComponent(r[0]),e.sortOptions.direction=decodeURIComponent(r[1])}e.serverPagination||d()}function p(){var t="",i=a.search();Object.keys(i).forEach(function(e){t+=e+"="+i[e]+"&"}),t=t.slice(0,-1),!t&&e.sortOptions.predicate?e.sort(e.sortOptions.predicate,!0):e._gridOptions.getData("?"+t,function(t,i){e.filtered=t,e.paginationOptions.totalItems=i})}function d(){var t=Date.now(),i=!1;e._time={},e.sortOptions.predicate&&e.sortCache&&e.sortCache.predicate===e.sortOptions.predicate&&e.sortCache.direction===e.sortOptions.direction?(e.filtered=e.sortCache.data.slice(),i=!0):e.filtered=e._gridOptions.data.slice(),e._time.copy=Date.now()-t;var r=Date.now();g(),e._time.filters=Date.now()-r;var a=Date.now();e.sortOptions.predicate&&!i&&(e.filtered=n("orderBy")(e.filtered,e.sortOptions.predicate,"desc"===e.sortOptions.direction),e.sortCache={data:e.filtered.slice(),predicate:e.sortOptions.predicate,direction:e.sortOptions.direction}),e._time.sort=Date.now()-a,e._time.all=Date.now()-t,e.paginationOptions.totalItems=e.filtered.length}function g(){e.filters.forEach(function(t){var i=t.filterBy,r=t.model,n=t.isInScope?e.$eval(r):e.$parent.$eval(r),a=t.filterType;if(e.customFilters[r])e.filtered=e.customFilters[r](e.filtered,n,i);else if(n&&a){var s=o.getFilterByType(a);s&&(e.filtered=s(e.filtered,n,i))}})}e._gridOptions=e.$eval(r.attr("grid-options")),e._gridActions=e.$eval(r.attr("grid-actions")),e.serverPagination="true"===r.attr("server-pagination"),e.getDataDelay=r.attr("get-delay")||350,e._gridActions||(e.$parent.$eval(r.attr("grid-actions")+"= {}"),e._gridActions=e.$parent.$eval(r.attr("grid-actions"))),e._gridOptions.grid=e,e.filtered=e._gridOptions.data.slice(),e.paginationOptions=e._gridOptions.pagination?angular.copy(e._gridOptions.pagination):{},e.defaultsPaginationOptions={itemsPerPage:e.paginationOptions.itemsPerPage||"10",currentPage:e.paginationOptions.currentPage||1},e.paginationOptions=angular.copy(e.defaultsPaginationOptions),e.sortOptions=e._gridOptions.sort?angular.copy(e._gridOptions.sort):{},e.customFilters=e._gridOptions.customFilters?angular.copy(e._gridOptions.customFilters):{},e.urlSync=e._gridOptions.urlSync,e.$watchCollection("_gridOptions.data",function(i){i&&i.length>-1&&(e.sortCache={},e.filtered=e._gridOptions.data.slice(),e.filters.forEach(function(i){"select"===i.filterType&&(e[i.model+"Options"]=t(e.filtered,i.filterBy))}),e.urlSync?l():d())}),e.sort=function(t,i){if(!i){var r=e.sortOptions.predicate===t&&"desc"===e.sortOptions.direction?"asc":"desc";e.sortOptions.direction=r,e.sortOptions.predicate=t}e.paginationOptions.currentPage=1,e.reloadGrid(i)},e.filter=function(){e.paginationOptions.currentPage=1,e.reloadGrid()},e.$on("$locationChangeSuccess",function(){s()}),e.$on("$stateChangeSuccess",function(t,e){s()}),e.reloadGrid=function(t){e.urlSync||e.serverPagination?c(t):d(),i.$broadcast("gridReloaded")},e._gridActions.refresh=e.reloadGrid,e._gridActions.filter=e.filter,e._gridActions.sort=e.sort}]).directive("gridItem",["$compile",function(t){return{restrict:"EA",terminal:!0,scope:!1,link:function(e,i,r,n,a){e.serverPagination?i.attr("ng-repeat","item in filtered"):i.attr("ng-repeat","item in filtered | startFrom:(paginationOptions.currentPage-1)*paginationOptions.itemsPerPage | limitTo:paginationOptions.itemsPerPage track by $index"),i.removeAttr("grid-item");var o=i[0].outerHTML;i.replaceWith(t(o)(e))}}}]).directive("gridData",["$compile","$animate",function(e){return{restrict:"EA",scope:!0,controller:"gridController",link:function(i,r,n){var a=[],o=r.parent(),s=n.id,c="true"===n.serverPagination;i.serverPagination=c,angular.forEach(angular.element(o[0].querySelectorAll("[sortable]")),function(t){var r=angular.element(t),n=r.attr("sortable");r.attr("ng-class","{'sort-ascent' : sortOptions.predicate ==='"+n+"' && sortOptions.direction === 'asc', 'sort-descent' : sortOptions.predicate === '"+n+"' && sortOptions.direction === 'desc'}"),r.attr("ng-click","sort('"+n+"')"),e(r)(i)}),angular.forEach(document.querySelectorAll("[filter-by]"),function(e){var n=angular.element(e),o=n.attr("filter-by"),c=document.querySelectorAll("[grid-data]")[0],l=c.querySelectorAll('[filter-by="'+o+'"]').length>0,p=n.attr("filter-type")||"",d=n.attr("ng-model"),g=n.attr("disable-url");s&&n.attr("grid-id")&&s!=n.attr("grid-id")||("select"!==p||(i[d+"Options"]=t(i.$eval(r.attr("grid-options")+".data"),o)),!~p.indexOf("date")||n.attr("ng-focus")||n.attr("ng-blur")||(n.attr("ng-focus","filter('{"+d+" : this."+d+"}')"),n.attr("ng-blur","filter('{"+d+" : this."+d+"}')")),d||(d=o,n.attr("ng-model",o),n.attr("ng-change","filter()")),a.push({model:d,isInScope:l,filterBy:o,filterType:p,disableUrl:g}))}),i.filters=a}}}]).factory("filtersFactory",function(){function t(t,e,i){return t.filter(function(t){return!e||!t[i]||t[i]===e})}function e(t,e,i){return t.filter(function(t){return e&&t[i]?~(t[i]+"").toLowerCase().indexOf((e+"").toLowerCase()):!!t[i]})}function i(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return!e||!t[i]||t[i]<=e+86399999})}function r(t,e,i){return e=new Date(e).getTime(),t.filter(function(t){return!e||!t[i]||t[i]>=e})}return{getFilterByType:function(n){switch(n){case"select":return t;case"text":return e;case"dateTo":return i;case"dateFrom":return r;default:return null}}}})}(); \ No newline at end of file diff --git a/src/js/dataGrid.js b/src/js/dataGrid.js index 7ed9847..14ee687 100644 --- a/src/js/dataGrid.js +++ b/src/js/dataGrid.js @@ -37,7 +37,7 @@ $scope.customFilters = $scope._gridOptions.customFilters ? angular.copy($scope._gridOptions.customFilters) : {}; $scope.urlSync = $scope._gridOptions.urlSync; - $scope.$watch('_gridOptions.data', function (newValue) { + $scope.$watchCollection('_gridOptions.data', function (newValue) { if (newValue && newValue.length > -1) { $scope.sortCache = {}; $scope.filtered = $scope._gridOptions.data.slice(); From b69697246e13f379186e8ac806dc0ec3791c01d3 Mon Sep 17 00:00:00 2001 From: AlexZ Date: Tue, 11 Apr 2017 17:22:52 +0300 Subject: [PATCH 26/40] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1ea0f5b..b20ed11 100644 --- a/README.md +++ b/README.md @@ -248,4 +248,6 @@ Each filter has optional parameter `disable-url` (boolean, default is 'false'). If you need to use 2 or more grids on page, please add `id` to grids, and then use `grid-id` attribute on filters to specify their corresponding grid. [Example](http://angular-data-grid.github.io/demo/bootstrap/multiple.html) ### Next / Future + - Migrate to Heroku + - Cover with unit / e2e tests - Port to Angular2? From 62e58195707e838920c9140970ef56b482adf67d Mon Sep 17 00:00:00 2001 From: Andrey Chayko Date: Wed, 12 Apr 2017 11:47:54 +0300 Subject: [PATCH 27/40] Changed pagination default value for items per page to 75 for both fixed header samples. --- demo/fixed-header/angular-md-grid.html | 4 ++-- demo/fixed-header/bootstrap-grid.html | 4 ++-- demo/fixed-header/js/bootstrap/demoApp.js | 6 +++++- demo/fixed-header/js/material-design/demoApp.js | 6 +++++- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/demo/fixed-header/angular-md-grid.html b/demo/fixed-header/angular-md-grid.html index d828b6c..adac9a9 100644 --- a/demo/fixed-header/angular-md-grid.html +++ b/demo/fixed-header/angular-md-grid.html @@ -156,7 +156,7 @@

    Using Stand-alone Directive

    ng-change="reloadGrid()" items-per-page="paginationOptions.itemsPerPage"> - 10 25 @@ -217,7 +217,7 @@

    Using Stand-alone Directive

    ng-change="reloadGrid()" items-per-page="paginationOptions.itemsPerPage"> - 10 25 diff --git a/demo/fixed-header/bootstrap-grid.html b/demo/fixed-header/bootstrap-grid.html index d56420c..f4b263f 100644 --- a/demo/fixed-header/bootstrap-grid.html +++ b/demo/fixed-header/bootstrap-grid.html @@ -186,7 +186,7 @@

    Using Stand-alone Directive

    - @@ -243,7 +243,7 @@

    Using Stand-alone Directive

    -
    + @@ -94,6 +106,7 @@

    First Grid

    +
    Date Of Birth + +
    @@ -182,6 +195,18 @@

    Second Grid

    Date Of Birth + + + @@ -190,6 +215,7 @@

    Second Grid

    + From 76b4865eb21e4e1063a4f170defd16cbec12209b Mon Sep 17 00:00:00 2001 From: Rowinson Gallego Date: Tue, 15 Aug 2017 09:54:50 -0500 Subject: [PATCH 30/40] Support for ES6 imports was added (#45) --- index.js | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 index.js diff --git a/index.js b/index.js new file mode 100644 index 0000000..6b85ad2 --- /dev/null +++ b/index.js @@ -0,0 +1,7 @@ +require('./dist/dataGrid'); +require('./dist/pagination'); + +module.exports = { + dataGrid: 'dataGrid', + pagination: 'pagination', +}; diff --git a/package.json b/package.json index 260e070..9aaf0b6 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "gulp-uglify": "^1.4.2" }, "description": "Light, flexible and performant Data Grid for AngularJS apps, with built-in sorting, pagination and filtering options, unified API for client-side and server-side data fetching, \r seamless synchronization with browser address bar and total freedom in mark-up and styling suitable for your application. Angular 1.3 - 1.6 compliant.", - "main": "index.html", + "main": "index.js", "devDependencies": {}, "repository": { "type": "git", From 52db8e025d4648a21c9a083242e1b914c7e0f762 Mon Sep 17 00:00:00 2001 From: Andrey Chayko Date: Wed, 16 Aug 2017 18:46:27 +0300 Subject: [PATCH 31/40] Updated samples for material design. Fixed sorting icons display issue for IE. Fixed content alignment for fixed header sample --- demo/fixed-header/angular-md-grid.html | 388 +++++++++--------- .../css/angular-data-grid.material.css | 42 +- demo/material/index.html | 46 ++- .../scss/angular-data-grid.material.scss | 44 +- .../scss/angular-data-grid.variables.scss | 3 +- 5 files changed, 251 insertions(+), 272 deletions(-) diff --git a/demo/fixed-header/angular-md-grid.html b/demo/fixed-header/angular-md-grid.html index 96aeb30..46dfd74 100644 --- a/demo/fixed-header/angular-md-grid.html +++ b/demo/fixed-header/angular-md-grid.html @@ -21,34 +21,35 @@
    -
    -
    -

    Fix Header Table

    +
    +
    +
    +

    Fix Header Table

    -

    Features enabled: sorting, filtering, sync with browser URLs, pagination, item-per-page and fixed-header functionality. - Out-of-box Angular Material layout and - input controls used, - along with Material Design Light default CSS for - grid styling. - Project GitHub

    +

    Features enabled: sorting, filtering, sync with browser URLs, pagination, item-per-page and fixed-header functionality. + Out-of-box Angular Material layout and + input controls used, + along with Material Design Light default CSS for + grid styling. + Project GitHub

    -
    -

    How To Freeze Table Header

    -

    Using HTML Layout

    -
    -

    The first option is to split table header and table body in two tables. - One way to do this is to follow the next steps:

    -
      -
    • Use the next styles (with any fixed height) applied to table body container to make it scrollable:
      - .div-table-body { height: 600px; overflow-x: auto; overflow-y: scroll; }
      -
    • -
    • Make sure that th elements have the same padding as td elements have.
    • -
    • Use padding-right with the value of scroll bar width to make an offset for the table contains header.
    • -
    • Use width attribute for columns to sync widths.
    • -
    -

    Code Sample: -

    +                
    +

    How To Freeze Table Header

    +

    Using HTML Layout

    +
    +

    The first option is to split table header and table body in two tables. + One way to do this is to follow the next steps:

    +
      +
    • Use the next styles (with any fixed height) applied to table body container to make it scrollable:
      + .div-table-body { height: 600px; overflow-x: auto; overflow-y: scroll; }
      +
    • +
    • Make sure that th elements have the same padding as td elements have.
    • +
    • Use padding-right with the value of scroll bar width to make an offset for the table contains header.
    • +
    • Use width attribute for columns to sync widths.
    • +
    +

    Code Sample: +

     <table>
         <thead>
             ...
    @@ -60,182 +61,187 @@ 

    Using HTML Layout

    </tbody> </table>
    -

    -
    -

    Using Stand-alone Directive

    -
    -

    Another option is to use the directive fixed-header that can be injected to the Data Grid like a separate module dataGridUtils.

    -

    To make it work it is needed to perform next steps:

    -
      -
    • Include script to your application:
      - <script src="bower_components/angular-data-grid/dist/dataGridUtils.min.js"></script> -
    • -
    • Include css stylesheets to your application:
      - <link rel="stylesheet" href="bower_components/angular-data-grid/css/fixedHeader/fixed-header.css"> -
    • -
    • Inject dataGridUtils dependency in your module:
      - angular.module('myApp', ['dataGrid', 'dataGridUtils.fixedHeader']) -
    • -
    • Apply the directive fixed-header to the grid table:
      - <table class="table" fixed-header> -
    • -
    -

    The directive uses z-index: 99 if your page uses the same value or higher please make appropriate changes to fixed-header.scss file.

    -

    The directive also has additional attribute offset-from-element. - It is needed if you already have some other elements with fixed position above the table. - In this case you need to pass a class or id of the very last element (if there are several) to this attribute - to make the directive take - into consideration that header needs to be fixed with offset from above elements.

    -

    Example:
    +

    +
    +

    Using Stand-alone Directive

    +
    +

    Another option is to use the directive fixed-header that can be injected to the Data Grid like a separate module dataGridUtils.

    +

    To make it work it is needed to perform next steps:

    +
      +
    • Include script to your application:
      + <script src="bower_components/angular-data-grid/dist/dataGridUtils.min.js"></script> +
    • +
    • Include css stylesheets to your application:
      + <link rel="stylesheet" href="bower_components/angular-data-grid/css/fixedHeader/fixed-header.css"> +
    • +
    • Inject dataGridUtils dependency in your module:
      + angular.module('myApp', ['dataGrid', 'dataGridUtils.fixedHeader']) +
    • +
    • Apply the directive fixed-header to the grid table:
      + <table class="table" fixed-header> +
    • +
    +

    The directive uses z-index: 99 if your page uses the same value or higher please make appropriate changes to fixed-header.scss file.

    +

    The directive also has additional attribute offset-from-element. + It is needed if you already have some other elements with fixed position above the table. + In this case you need to pass a class or id of the very last element (if there are several) to this attribute + to make the directive take + into consideration that header needs to be fixed with offset from above elements.

    +

    Example:

    <table class="table" fixed-header offset-from-element=".the-class-on-above-fixed-element">
    or
    <table class="table" fixed-header offset-from-element="#the-id-on-above-fixed-element”>
    -

    -
    -

    The directive subscribes on scroll event, but the event is not fired when directive is used inside <md-content>, so to make it work please use the directive outside the <md-content> container. - For more information about this problem please review this issue. -

    +

    +
    +

    The directive subscribes on scroll event, but the event is not fired when directive is used inside <md-content>, so to make it work please use the directive + outside the <md-content> container. + For more information about this problem please review this issue. +

    +

    -
    -
    -
    -
    - - - -
    -
    - -
    -
    - -
    -
    - Clear Dates - -
    -
    -
    -
    -
    - {{filtered.length}} items total +
    +
    + + +
    -
    -
    - - - - 10 - 25 - 50 - 75 - - -
    +
    + + +
    +
    + + +
    +
    + Clear Dates +
    -
    - - - - - - - - - - - - - - - - - -
    - Order # - - - All Statuses - - {{option.text}} - - - - Date Placed - - Total -
    - -
    +
    +
    +
    + {{filtered.length}} items total +
    +
    +
    + + + + 10 + 25 + 50 + 75 + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + +
    + Order # + + + + All Statuses + + {{option.text}} + + + + Date Placed + + + Total + +
    + +
    +
    +
    + + + + 10 + 25 + 50 + 75 + + +
    -
    - - - - 10 - 25 - 50 - 75 - - +
    + CodePen +
    +

    See the Pen eJWWpM by AngularDataGrid (@AngularDataGrid) on CodePen. +

    +
    +
    -
    - CodePen -
    -

    See the Pen eJWWpM by AngularDataGrid (@AngularDataGrid) on CodePen. -

    - -
    -
    diff --git a/demo/material/css/angular-data-grid.material.css b/demo/material/css/angular-data-grid.material.css index 7e6dc66..7edbd95 100644 --- a/demo/material/css/angular-data-grid.material.css +++ b/demo/material/css/angular-data-grid.material.css @@ -51,33 +51,19 @@ th md-select { .pagination-page.active a { color: #fff; } -.material-icons, .sortable span:before, .sortable span:after { - font-family: 'Material Icons'; - font-size: 18px; - -webkit-font-feature-settings: 'liga'; - -webkit-font-smoothing: antialiased; } +.sortable .arrow { + position: relative; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; } -.sortable span { - position: relative; } - .sortable span:before { - content: 'arrow_drop_down'; - position: absolute; - right: -18px; - top: -2px; } - .sortable span:after { - content: 'arrow_drop_up'; - position: absolute; - right: -18px; - top: -9px; } +.sortable.sort-ascent .arrow { + top: -10px; + left: 5px; + border-bottom: 4px solid #757575; } -.sortable.sort-ascent span:before { - display: none; } - -.sortable.sort-ascent span:after { - top: -5px; } - -.sortable.sort-descent span:before { - top: -5px; } - -.sortable.sort-descent span:after { - display: none; } +.sortable.sort-descent .arrow { + top: 10px; + left: 5px; + border-top: 4px solid #757575; } diff --git a/demo/material/index.html b/demo/material/index.html index a9846db..b457c91 100644 --- a/demo/material/index.html +++ b/demo/material/index.html @@ -14,7 +14,6 @@
    Angular Data Grid — Material Design - @@ -33,17 +32,15 @@
    - +
    -
    -

    Angular Data Grid sample using Material Design styling

    +

    Angular Data Grid sample using Material Design styling

    -

    Features enabled: sorting, filtering, sync with browser URLs, pagination and item-per-page functionality. - Out-of-box Angular Material layout and input controls used, - along with Material Design Light default CSS for grid styling. - Project GitHub

    -
    +

    Features enabled: sorting, filtering, sync with browser URLs, pagination and item-per-page functionality. + Out-of-box Angular Material layout and input controls used, + along with Material Design Light default CSS for grid styling. + Project GitHub

    Additional Demos

    • @@ -51,9 +48,10 @@

      Additional Demos


    +
    -
    - +
    + Additional Demos aria-invalid="false">
    -
    +
    + ng-change="gridActions.filter()"> +
    -
    +
    + ng-change="gridActions.filter()"> +
    -
    - Clear Dates +
    + Clear Dates +
    @@ -120,6 +121,7 @@

    Additional Demos

    Order # + Additional Demos Date Placed + Total + @@ -183,7 +187,7 @@

    Additional Demos


    - +
    diff --git a/demo/material/scss/angular-data-grid.material.scss b/demo/material/scss/angular-data-grid.material.scss index ff688a7..fdb8d81 100644 --- a/demo/material/scss/angular-data-grid.material.scss +++ b/demo/material/scss/angular-data-grid.material.scss @@ -64,44 +64,26 @@ th md-select { } } } -.material-icons { - font-family: 'Material Icons'; - font-size: 18px; - -webkit-font-feature-settings: 'liga'; - -webkit-font-smoothing: antialiased; -} .sortable { - span { + .arrow { position: relative; - &:before { - @extend .material-icons; - content: 'arrow_drop_down'; - position: absolute; - right: -18px; - top: -2px; - } - &:after { - @extend .material-icons; - content: 'arrow_drop_up'; - position: absolute; - right: -18px; - top: -9px; - } + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; } &.sort-ascent { - span:before { - display: none; - } - span:after { - top: -5px + .arrow { + top: -10px; + left: 5px; + border-bottom: 4px solid $backgroundArrows; } } &.sort-descent { - span:before { - top: -5px - } - span:after { - display: none; + .arrow { + top: 10px; + left: 5px; + border-top: 4px solid $backgroundArrows; } } } \ No newline at end of file diff --git a/demo/material/scss/angular-data-grid.variables.scss b/demo/material/scss/angular-data-grid.variables.scss index 60b1dda..2c7053a 100644 --- a/demo/material/scss/angular-data-grid.variables.scss +++ b/demo/material/scss/angular-data-grid.variables.scss @@ -2,4 +2,5 @@ $backgroundActive: rgb(63, 81, 181); $foregroundActive: #fff; $foregroundPagination: #ddd; $foregroundDefault: #444; -$backgroundIcons: #333; \ No newline at end of file +$backgroundIcons: #333; +$backgroundArrows: #757575; \ No newline at end of file From 4b2ace651c087bceac8952b49127c0ad739b219d Mon Sep 17 00:00:00 2001 From: Andrey Chayko Date: Thu, 17 Aug 2017 15:07:28 +0300 Subject: [PATCH 32/40] Updated angular material version to 1.1.4 and material design lite to version 1.3.0 --- demo/fixed-header/angular-md-grid.html | 22 +++++++++++----------- demo/material/index.html | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/demo/fixed-header/angular-md-grid.html b/demo/fixed-header/angular-md-grid.html index 46dfd74..78f4215 100644 --- a/demo/fixed-header/angular-md-grid.html +++ b/demo/fixed-header/angular-md-grid.html @@ -5,8 +5,8 @@ Angular Data Grid - Fix Header Table - - + + @@ -158,10 +158,10 @@

    Using Stand-alone Directive

    - 10 - 25 - 50 - 75 + 10 + 25 + 50 + 75
    @@ -222,10 +222,10 @@

    Using Stand-alone Directive

    - 10 - 25 - 50 - 75 + 10 + 25 + 50 + 75
    @@ -250,7 +250,7 @@

    Using Stand-alone Directive

    - + diff --git a/demo/material/index.html b/demo/material/index.html index b457c91..76acecd 100644 --- a/demo/material/index.html +++ b/demo/material/index.html @@ -5,8 +5,8 @@ Angular Data Grid - Material Design - - + + @@ -106,10 +106,10 @@

    Additional Demos

    items-per-page="paginationOptions.itemsPerPage"> - 10 - 25 - 50 - 75 + 10 + 25 + 50 + 75
    @@ -169,10 +169,10 @@

    Additional Demos

    items-per-page="paginationOptions.itemsPerPage"> - 10 - 25 - 50 - 75 + 10 + 25 + 50 + 75
    @@ -195,7 +195,7 @@

    Additional Demos

    - + From fa133e63aa54fc8260d445f19f69978c40452498 Mon Sep 17 00:00:00 2001 From: Alexander Zhuk Date: Thu, 17 Aug 2017 15:30:43 +0300 Subject: [PATCH 33/40] Export grid data #54 fix - feature added --- README.md | 1 + demo/bootstrap/index.html | 32 +- demo/bootstrap/js/demoApp.js | 15 +- demo/data.json | 1907 ++++++++++---------------- dist/JSONToCSVConvertor.js | 84 ++ src/js/vendors/JSONToCSVConvertor.js | 84 ++ 6 files changed, 956 insertions(+), 1167 deletions(-) create mode 100644 dist/JSONToCSVConvertor.js create mode 100644 src/js/vendors/JSONToCSVConvertor.js diff --git a/README.md b/README.md index b20ed11..b1dc410 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Demo Angular UI Router: http://angular-data-grid.github.io/demo/bootstrap/ui-rou - Built-in sync with browser address bar (URL), so you can copy-n-paste sorting/filtering/pagination results URL and open it in other browser / send to anyone - even if pagination / filtering are done on a client-side. [See details](#url-synchronization) - Support of [Angular UI Router](https://github.com/angular-ui/ui-router) navigation. - Optional support of fixed header table: [Bootstrap Demo](http://angular-data-grid.github.io/demo/fixed-header/bootstrap-grid.html) [Material Design Demo](http://angular-data-grid.github.io/demo/fixed-header/angular-md-grid.html) + - Optional support of CSV data exports: [Demo](http://angular-data-grid.github.io/demo/bootstrap/) - Unlike most part of other Angular DataGrids, we intentionally use non-isolated scope of the directive to maximize flexibility, so it can be easily synchronized with any data changes inside your controller. NOTE! With great power comes great responsibility, so use non-isolated API wisely. diff --git a/demo/bootstrap/index.html b/demo/bootstrap/index.html index 061eb5b..fecbd10 100644 --- a/demo/bootstrap/index.html +++ b/demo/bootstrap/index.html @@ -30,7 +30,8 @@

    Angular Data Grid sample using out-of-box Bootstrap styling

    - Features enabled: sorting, filtering (using both in-grid and external controls), sync with browser URLs, pagination and items-per-page functionality. + Features enabled: sorting, filtering (using both in-grid and external controls), sync with browser URLs, + pagination and items-per-page functionality, plus optional plugin for CSV exports. Angular UI Datepicker used for date controls, although you can use any other framework, plugin or styling. Project GitHub
    @@ -88,7 +89,7 @@

    Additional Demos

    ng-focus="gridActions.filter()" show-weeks="false" close-text="Close"/> - + @@ -118,7 +119,7 @@

    Additional Demos

    ng-focus="gridActions.filter()" show-weeks="false" close-text="Close"> - + @@ -131,6 +132,13 @@

    Additional Demos


    +
    + + +
    +
    @@ -151,7 +159,9 @@

    Additional Demos

    - @@ -208,7 +218,8 @@

    Additional Demos

    -