<style>
/* TODO: move me */
- .eg-grid > div:nth-child(odd) {background-color: rgb(248, 248, 248);}
- /*.eg-grid-row:hover > .eg-grid-cell {background-color: rgb(248, 248, 248)}*/
- .eg-grid-scroll {overflow-y:scroll; height: 600px}
- .eg-grid-header-row {
- font-weight: bold;
+ /* odd/even row styling */
+ .eg-grid > div:nth-child(odd):not(.eg-grid-header-row):not(.eg-grid-row-selected) {
+ background-color: rgb(248, 248, 248);
}
+
+ .eg-grid-scroll {overflow-y:scroll; height: 600px}
+
.eg-grid-row {
- display: flex;
width: 100%;
- border-left: 1px solid #ccc;
- border-right: 1px solid #ccc;
+ display: flex;
+ border: 1px solid #ccc;
}
- .eg-grid-header-row > .eg-grid-cell {
+ .eg-grid-action-row {
+ border: none;
+ justify-content:flex-end; /* i.e. float right */
+ }
+
+ .eg-grid-header-row {
+ font-weight: bold;
border-top: 1px solid #ccc;
}
- .eg-grid-action-row {
- display:flex;
- justify-content:flex-end;
- width:100%;
+ .eg-grid-header-row > .eg-grid-cell {
+ border-right: 1px solid #CCC;
+ text-align: center;
}
+
.eg-grid-cell {
- border-bottom: 1px solid #ccc;
- /*border-right: 1px solid #DDD;*/
- padding: 2px;
+ /* avoid text flowing into adjacent cells */
overflow: hidden;
}
+ /* in config display, make cells more obvious */
+ .eg-grid-as-conf .eg-grid-cell {
+ border-right: 1px solid #777;
+ }
/* stock columns need fixed-width controls */
.eg-grid-cell-1 {flex: 1}
.eg-grid-cell-2 {flex: 2}
- .eg-grid-row-selected > .eg-grid-cell {
+
+ .eg-grid-row-selected {
color: rgb(51, 51, 51);
- /*background-color: rgb(248, 248, 248);*/
background-color: rgb(201, 221, 225);
border-bottom: 1px solid #888;
}
+
+ .eg-grid-conf-cell-entry {
+ width:95%;
+ text-align:center;
+ }
+ .eg-grid-conf-cell-entry:not(:first-child) {
+ border-top:1px solid #ccc;
+ }
+
</style>
<div ng-if="showGridConf">
- <style>
- .eg-grid-cell {
- border-right: 1px solid #DDD;
- }
- </style>
+ <!-- when the grid conf row is visible, give all cells a
+ border so that vertical alignment is easier to visualize
+ TODO: move this into an .eg-grid-cell-bordered class and
+ apply use ng-class on each cell instead -->
+ <style>.eg-grid-cell {border-right: 1px solid #888}</style>
</div>
-<div class="eg-grid">
+<div class="eg-grid" ng-class="{'eg-grid-as-conf' : showGridConf}">
<!-- import embedded eg-grid-field defs via no-op transclude -->
<div ng-transclude></div>
- <div class="eg-grid-action-row">
- [% INCLUDE 'staff/parts/column_picker.tt2' listname='dataList' %]
+ <div class="eg-grid-row eg-grid-action-row">
+ [% INCLUDE 'staff/parts/column_picker.tt2' listname='list' %]
</div>
+ <!-- ================== -->
+ <!-- column headers row -->
<div class="eg-grid-row eg-grid-header-row">
<div class="eg-grid-cell eg-grid-cell-1">[% l('#') %]</div>
<div class="eg-grid-cell eg-grid-cell-1">
- <input type='checkbox' ng-click="dataList.toggleSelectAll()"/>
+ <input type='checkbox' ng-click="list.toggleSelectAll()"/>
</div>
<div class="eg-grid-cell"
- ng-repeat="column in dataList.allColumns"
+ ng-repeat="column in list.allColumns"
style="flex:{{column.flexWidth}}"
- ng-show="dataList.displayColumns[column.name]">
+ ng-show="list.displayColumns[column.name]">
<a href="javascript:;" ng-click="sortOn(column.name)">{{column.label}}</a>
</div>
</div>
- <div class="eg-grid-row eg-grid-header-row" ng-show="showGridConf">
+ <!-- ====================== -->
+ <!-- grid configuration row -->
+ <div class="eg-grid-row" ng-show="showGridConf">
<div class="eg-grid-cell eg-grid-cell-2">
- <div style="width:100%;text-align:right">[% l('Wider') %]</div>
- <div style="width:100%;text-align:right;border-top:1px solid #ccc">
- [% l('Narrower') %]</div>
- <div style="width:100%;text-align:right;border-top:1px solid #ccc">
- [% l('Sort') %]</div>
+ <div class="eg-grid-conf-cell-entry">[% l('Wider') %]</div>
+ <div class="eg-grid-conf-cell-entry">[% l('Narrower') %]</div>
+ <div class="eg-grid-conf-cell-entry">[% l('Sort') %]</div>
</div>
<div class="eg-grid-cell"
- ng-repeat="column in dataList.allColumns"
+ ng-repeat="column in list.allColumns"
style="flex:{{column.flexWidth}}"
- ng-show="dataList.displayColumns[column.name]">
- <div style="width:100%;text-align:center">
+ ng-show="list.displayColumns[column.name]">
+ <div class="eg-grid-conf-cell-entry">
<a href="" title="[% l('Make column wider') %]"
ng-click="column.flexWidth = column.flexWidth + 1">
<span class="glyphicon glyphicon-fast-forward"></span>
</a>
</div>
- <div style="width:100%;text-align:center;border-top:1px solid #ccc">
+ <div class="eg-grid-conf-cell-entry">
<a href="" title="[% l('Make column narrower') %]"
ng-click="column.flexWidth = column.flexWidth - 1">
<span class="glyphicon glyphicon-fast-backward"></span>
</a>
</div>
- <div style="width:100%;text-align:center;border-top:1px solid #ccc">
+ <div class="eg-grid-conf-cell-entry">
<input type='number' ng-model="column.sortPriority"
title="[% l('Sort Priority') %]" style='width:2.3em'/>
</div>
</div>
</div>
+ <!-- ============== -->
+ <!-- grid data rows -->
<div class="eg-grid-row"
- ng-repeat="item in dataList.items"
+ ng-repeat="item in list.items"
ng-class="{'eg-grid-row-selected' : itemIsSelected(item)}">
<div class="eg-grid-cell eg-grid-cell-1"
ng-click="handleRowClick($event, item)">
- {{$index + 1 + dataList.pageOffset}}
+ {{$index + 1 + list.pageOffset}}
</div>
<div class="eg-grid-cell eg-grid-cell-1">
<!-- ng-click=handleRowClick here has unintended
consequences and is unnecessary, avoid it -->
<input type='checkbox'
- ng-model="dataList.selected[dataList.indexValue(item)]"/>
+ ng-model="list.selected[list.indexValue(item)]"/>
</div>
<div class="eg-grid-cell"
ng-click="handleRowClick($event, item)"
- ng-repeat="column in dataList.allColumns"
+ ng-repeat="column in list.allColumns"
style="flex:{{column.flexWidth}}"
- ng-show="dataList.displayColumns[column.name]">
- {{dataList.fieldValue(item, column.name) | egGridvalueFilter:column}}
+ ng-show="list.displayColumns[column.name]">
+ {{list.fieldValue(item, column.name) | egGridvalueFilter:column}}
</div>
</div>
</div>
// fields on the base idlClass
autoFields : '=',
- // optional, custom data retrieval function
- dataFetcher : '=',
-
// grid preferences will be stored / retrieved with this key
persistKey : '@',
// field whose value is unique and may be used for item
// reference / lookup. This will usually be someting like
- // "id". This is not needed when using autoFields, since
- // we can determine the primary key directly from the IDL.
- idField : '@'
+ // "id". This is not needed when using autoFields, since we
+ // can determine the primary key directly from the IDL.
+ idField : '@',
+
+ // egList is provided for us.
+ dataSource : '=',
+
+ egList : '=',
+
+ // if true, hide the sortPriority options in the
+ // grid configuration UI. This is primarily used by
+ // UIs where the data is ephemeral and can only be
+ // single-display-column sorted.
+ disableSortPriority : '='
},
link : function(scope, element, attrs) {
templateUrl : '/eg/staff/parts/t_autogrid', // TODO: avoid abs url
- controller : function($scope, $timeout, $modal, egIDL, egAuth, egNet, egList) { // TODO: reqs list
+ controller : // TODO: reqs list
+ function($scope, $timeout, $modal, egIDL, egAuth, egNet, egList) {
var self = this;
- // If we stick w/ Bootstrap grids for display, we're
- // limited to (currently) 12 visible columns at a time.
- // One of those is occupied by the shared ow count /
- // selector column
- this.maxFieldCount = 24;
-
- // TODO
+ // TODO: dynamic
this.limit = 20;
this.ofset = 0;
- $scope.dataList = egList.create();
+ $scope.list = $scope.egList || egList.create();
// column-header click quick sort
$scope.sortOn = function(col_name) {
// [{name : "asc"}, {code : "desc"}, {type : "asc"}]
this.compileSort = function() {
- var sortList = $scope.dataList.allColumns.filter(
+ var sortList = $scope.list.allColumns.filter(
function(col) { return Number(col.sortPriority) != 0 }
).sort(
function(a, b) {
*/
this.addColumn = function(fieldSpec) {
- if (Object.keys($scope.dataList.displayColumns).length
- >= self.maxFieldCount) {
- fieldSpec.display = false;
- }
-
var field = {
name : fieldSpec.name,
label : fieldSpec.label,
};
if (!field.path) field.path = field.name;
field = self.absorbField(field);
- $scope.dataList.addColumn(field);
+ $scope.list.addColumn(field);
field.flexWidth = 2; // TODO:
}
* from the "selector" field as well.
*/
this.compileAutoFields = function() {
- if ($scope.dataList.allColumns.length) return;
+ if ($scope.list.allColumns.length) return;
$scope.idField = $scope.idField ||
egIDL.classes[$scope.idlClass].pkey;
* For non-stock grids, calls the external data fetcher
*/
$scope.fetchData = function() {
- $scope.dataList.resetPageData();
- if (self.dataFetcher)
- return self.dataFetcher();
+ // when a list is provided, data management is
+ // handled externally.
+ if ($scope.egList) return;
+
+ $scope.list.resetPageData();
if (!$scope.query) {
console.error("egGrid requires a query");
if ($scope.autoFields)
self.compileAutoFields();
- $scope.dataList.indexField = $scope.idField;
+ $scope.list.indexField = $scope.idField;
var queryFields = {}
- angular.forEach($scope.dataList.allColumns, function(field) {
- if ($scope.dataList.displayColumns[field.name])
+ angular.forEach($scope.list.allColumns, function(field) {
+ if ($scope.list.displayColumns[field.name])
queryFields[field.name] = field.path || field.name;
});
offset : self.offset
}
).then(null, null, function(item) {
- $scope.dataList.items.push(item);
+ $scope.list.items.push(item);
});
}
$scope.handleRowClick = function($event, item) {
- var index = $scope.dataList.indexValue(item);
+ var index = $scope.list.indexValue(item);
if ($event.ctrlKey || $event.metaKey /* mac command */) {
- $scope.dataList.toggleOneSelection(index);
+ $scope.list.toggleOneSelection(index);
} else {
- $scope.dataList.selectOne(index);
+ $scope.list.selectOne(index);
}
}
$scope.itemIsSelected = function(item) {
- return $scope.dataList.selected[
- $scope.dataList.indexValue(item)
+ return $scope.list.selected[
+ $scope.list.indexValue(item)
];
}
}