// and managed externally.
itemsProvider : '=',
- // 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 : '@',
+ // comma-separated list of supported or disabled grid features
+ // TODO: examples
+ features : '@',
+
+ initialOffset : '=',
// optional primary grid label
- mainLabel : '@'
+ mainLabel : '@',
},
// TODO: avoid hard-coded url
var grid = this;
grid.init = function() {
- grid.offset = 0;
+ grid.offset = $scope.initialOffset || 0;
grid.limit = 25;
grid.items = [];
grid.selected = {}; // idField-based
// default flex values for the index and selector columns
grid.indexFlex = 1;
grid.selectorFlex = 1;
+ grid.features = ($scope.features) ?
+ $scope.features.split(',') : [];
grid.columnsProvider = egGridColumnsProvider.instance({
- idlClass : grid.idlClass
+ idlClass : grid.idlClass,
+ defaultToHidden : (grid.features.indexOf('-display') > -1),
+ defaultToNoSort : (grid.features.indexOf('-sort') > -1)
});
if ($scope.autoFields) {
// provider's revision changes
$scope.$watch(
function() { return grid.dataProvider.revision() },
- function() { grid.collect() }
+ function(newVal, oldVal) {
+ // hmm, why is this check necessary?
+ if (newVal != oldVal) grid.collect();
+ }
);
} else {
}
}
+ // inform the data provider that a selection has been made
+ grid.informSelection = function() {
+ var items = [];
+ angular.forEach(Object.keys(grid.selected),
+ function(index) {
+ items.push(grid.items[grid.indexOf(index)]);
+ }
+ );
+ grid.dataProvider.select(items);
+ }
+
// returns true if item1 appears in the list before item2;
// false otherwise. this is slightly more efficient that
// finding the position of each then comparing them.
} else if ($event.shiftKey) {
// shift-click
+
if (!grid.lastSelectedItemIndex ||
index == grid.lastSelectedItemIndex) {
- // no source row, just do a simple select
grid.selectOneItem(index);
grid.lastSelectedItemIndex = index;
- return;
- }
- var selecting = false;
- var ascending =
- grid.itemComesBefore(grid.lastSelectedItemIndex, item);
- var startPos =
- grid.indexOf(grid.lastSelectedItemIndex);
+ } else {
+
+ var selecting = false;
+ var ascending = grid.itemComesBefore(
+ grid.lastSelectedItemIndex, item);
+ var startPos =
+ grid.indexOf(grid.lastSelectedItemIndex);
- // update to new last-selected
- grid.lastSelectedItemIndex = index;
+ // update to new last-selected
+ grid.lastSelectedItemIndex = index;
- // select each row between the last selected and
- // currently selected items
- while (true) {
- startPos += ascending ? 1 : -1;
- var curItem = grid.items[startPos];
- if (!curItem) break;
- var curIdx = grid.indexValue(curItem);
- grid.selected[curIdx] = true;
- if (curIdx == index) break; // all done
+ // select each row between the last selected and
+ // currently selected items
+ while (true) {
+ startPos += ascending ? 1 : -1;
+ var curItem = grid.items[startPos];
+ if (!curItem) break;
+ var curIdx = grid.indexValue(curItem);
+ grid.selected[curIdx] = true;
+ if (curIdx == index) break; // all done
+ }
}
} else {
grid.selectOneItem(index);
grid.lastSelectedItemIndex = index;
}
+
+ grid.informSelection();
}
// Builds a sort expression from column sort priorities.
// asks the dataProvider for a page of data
grid.collect = function() {
grid.items = [];
- grid.selectedItems = {};
- grid.dataProvider.get(
- grid.offset,
- grid.limit,
- function(item) {
- if (item) grid.items.push(item)
- }
- );
+ grid.selected = {};
+ grid.dataProvider.get(grid.offset, grid.limit)
+ .then(null, null, function(item) {
+ if (item) grid.items.push(item)
+ });
}
grid.init();
name : '@', // required; unique name
path : '@', // optional; flesh path
label : '@', // optional; display label
- flex : '@', // optional; default flex width
- display : '=' // optional; hide column by default
+ flex : '@' // optional; default flex width
},
template : '<div></div>', // NOOP template
link : function(scope, element, attrs, egGridCtrl) {
+
+ // boolean fields are presented as value-less attributes
+ angular.forEach(
+ ['visible', 'hidden', 'sortable', 'nonsortable'],
+ function(field) {
+ if (angular.isDefined(attrs[field]))
+ scope[field] = true;
+ }
+ );
egGridCtrl.columnsProvider.add(scope);
}
};
cols.columns = [];
cols.visible = {};
cols.idlClass = args.idlClass;
+ cols.defaultToHidden = args.defaultToHidden;
+ cols.defaultToNoSort = args.defaultToNoSort;
cols.showAllColumns = function() {
angular.forEach(cols.columns, function(column) {
path : colSpec.path,
flex : Number(colSpec.flex) || 2,
sort : Number(colSpec.sort) || 0,
- datatype : colSpec.datatype,
+ sortable : colSpec.sortable,
+ nonsortable : colSpec.nonsortable,
+ visible : colSpec.visible,
+ hidden : colSpec.hidden,
+ datatype : colSpec.datatype
};
if (!column.name) column.name = column.path;
if (!column.path) column.path = column.name;
- if (colSpec.display !== false)
+ if (column.visible || (!cols.defaultToHidden && !column.hidden))
cols.visible[column.name] = true;
+ if (column.sortable || (!cols.defaultToNoSort && !column.nonsortable))
+ column.sortable = true;
+
cols.columns.push(column);
if (fromIDL) return;
queryFields[col.name] = col.path;
});
- egNet.request(
+ return egNet.request(
'open-ils.fielder',
'open-ils.fielder.flattened_search',
egAuth.token(), gridData.idlClass, queryFields,
limit : count,
offset : index
}
- ).then(
- null, null,
- function(item) { onresponse(item) }
);
}
egGridCtrl.dragColumn = attrs.column;
egGridCtrl.dragType = attrs.dragType || 'move'; // or resize
egGridCtrl.colResizeDir = 0;
- angular.element(e.target).addClass('eg-grid-col-drag');
+ angular.element(e.target).addClass(
+ 'eg-grid-column-move-handle-active');
});
element.bind('dragend', function(e) {
if (egGridCtrl.dragType == 'move')
- angular.element(e.target).removeClass('eg-grid-col-drag');
+ angular.element(e.target).removeClass(
+ 'eg-grid-column-move-handle-active');
});
}
};