|
|
@@ -1,48 +1,100 @@
|
|
|
// JavaScript source code
|
|
|
(function () {
|
|
|
angular.module('bsTable', []).directive('bsTableControl', function () {
|
|
|
- var SEARCH_SELECTOR = '.search input';
|
|
|
var CONTAINER_SELECTOR = '.bootstrap-table';
|
|
|
+ var SCROLLABLE_SELECTOR = '.fixed-table-body';
|
|
|
+ var SEARCH_SELECTOR = '.search input';
|
|
|
+ var bsTables = {};
|
|
|
+ function getBsTable (el) {
|
|
|
+ var result;
|
|
|
+ $.each(bsTables, function (id, bsTable) {
|
|
|
+ if (!bsTable.$el.closest(CONTAINER_SELECTOR).has(el).length) return;
|
|
|
+ result = bsTable;
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ $(window).resize(function () {
|
|
|
+ $.each(bsTables, function (id, bsTable) {
|
|
|
+ bsTable.$el.bootstrapTable('resetView');
|
|
|
+ });
|
|
|
+ });
|
|
|
+ function onScroll () {
|
|
|
+ var bsTable = this;
|
|
|
+ var state = bsTable.$s.bsTableControl.state;
|
|
|
+ bsTable.$s.$applyAsync(function () {
|
|
|
+ state.scroll = bsTable.$el.bootstrapTable('getScrollPosition');
|
|
|
+ });
|
|
|
+ }
|
|
|
+ $(document)
|
|
|
+ .on('post-header.bs.table', CONTAINER_SELECTOR+' table', function (evt) { // bootstrap-table calls .off('scroll') in initHeader so reattach here
|
|
|
+ var bsTable = getBsTable(evt.target);
|
|
|
+ if (!bsTable) return;
|
|
|
+ bsTable.$el
|
|
|
+ .closest(CONTAINER_SELECTOR)
|
|
|
+ .find(SCROLLABLE_SELECTOR)
|
|
|
+ .on('scroll', onScroll.bind(bsTable));
|
|
|
+ })
|
|
|
+ .on('sort.bs.table', CONTAINER_SELECTOR+' table', function (evt, sortName, sortOrder) {
|
|
|
+ var bsTable = getBsTable(evt.target);
|
|
|
+ if (!bsTable) return;
|
|
|
+ var state = bsTable.$s.bsTableControl.state;
|
|
|
+ bsTable.$s.$applyAsync(function () {
|
|
|
+ state.sortName = sortName;
|
|
|
+ state.sortOrder = sortOrder;
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .on('page-change.bs.table', CONTAINER_SELECTOR+' table', function (evt, pageNumber, pageSize) {
|
|
|
+ var bsTable = getBsTable(evt.target);
|
|
|
+ if (!bsTable) return;
|
|
|
+ var state = bsTable.$s.bsTableControl.state;
|
|
|
+ bsTable.$s.$applyAsync(function () {
|
|
|
+ state.pageNumber = pageNumber;
|
|
|
+ state.pageSize = pageSize;
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .on('search.bs.table', CONTAINER_SELECTOR+' table', function (evt, searchText) {
|
|
|
+ var bsTable = getBsTable(evt.target);
|
|
|
+ if (!bsTable) return;
|
|
|
+ var state = bsTable.$s.bsTableControl.state;
|
|
|
+ bsTable.$s.$applyAsync(function () {
|
|
|
+ state.searchText = searchText;
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .on('focus blur', CONTAINER_SELECTOR+' '+SEARCH_SELECTOR, function (evt) {
|
|
|
+ var bsTable = getBsTable(evt.target);
|
|
|
+ if (!bsTable) return;
|
|
|
+ var state = bsTable.$s.bsTableControl.state;
|
|
|
+ bsTable.$s.$applyAsync(function () {
|
|
|
+ state.searchHasFocus = $(evt.target).is(':focus');
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
return {
|
|
|
restrict: 'EA',
|
|
|
- scope: {options: '='},
|
|
|
+ scope: {bsTableControl: '='},
|
|
|
link: function ($s, $el) {
|
|
|
- var scroll;
|
|
|
- var options;
|
|
|
- $el
|
|
|
- .on('sort.bs.table', function (evt, sortName, sortOrder) {
|
|
|
- if (!options) return;
|
|
|
- options.sortName = sortName;
|
|
|
- options.sortOrder = sortOrder;
|
|
|
- })
|
|
|
- .on('page-change.bs.table', function (evt, pageNumber, pageSize) {
|
|
|
- if (!options) return;
|
|
|
- options.pageNumber = pageNumber;
|
|
|
- options.pageSize = pageSize;
|
|
|
- })
|
|
|
- .on('search.bs.table', function (evt, searchText) {
|
|
|
- if (!options) return;
|
|
|
- options.searchText = searchText;
|
|
|
- });
|
|
|
- $s.$watch('options', function (newOptions) {
|
|
|
- if (!newOptions) return;
|
|
|
+ var bsTable = bsTables[$s.$id] = {$s: $s, $el: $el};
|
|
|
+ $s.instantiated = false;
|
|
|
+ $s.$watch('bsTableControl.options', function (options) {
|
|
|
+ if (!options) options = $s.bsTableControl.options = {};
|
|
|
+ var state = $s.bsTableControl.state || {};
|
|
|
|
|
|
- var searchHasFocus = $el.closest(CONTAINER_SELECTOR).find(SEARCH_SELECTOR).is(':focus');
|
|
|
- if (options) {
|
|
|
- scroll = $el.bootstrapTable('getScrollPosition');
|
|
|
- $el.bootstrapTable('destroy');
|
|
|
- }
|
|
|
- newOptions = angular.copy(newOptions);
|
|
|
- if (options) angular.forEach(['sortName', 'sortOrder', 'pageNumber', 'pageSize', 'searchText'], function (key) {
|
|
|
- if (key in options) newOptions[key] = options[key];
|
|
|
- });
|
|
|
- options = newOptions;
|
|
|
- $el.bootstrapTable(options);
|
|
|
- if (scroll) $el.bootstrapTable('scrollTo', scroll);
|
|
|
- if (searchHasFocus) $el.closest(CONTAINER_SELECTOR).find(SEARCH_SELECTOR).focus(); // $el gets detached so have to recompute whole chain
|
|
|
+ if ($s.instantiated) $el.bootstrapTable('destroy');
|
|
|
+ $el.bootstrapTable(angular.extend(angular.copy(options), state));
|
|
|
+ $s.instantiated = true;
|
|
|
+
|
|
|
+ // Update the UI for state that isn't settable via options
|
|
|
+ if ('scroll' in state) $el.bootstrapTable('scrollTo', state.scroll);
|
|
|
+ if ('searchHasFocus' in state) $el.closest(CONTAINER_SELECTOR).find(SEARCH_SELECTOR).focus(); // $el gets detached so have to recompute whole chain
|
|
|
+ }, true);
|
|
|
+ $s.$watch('bsTableControl.state', function (state) {
|
|
|
+ if (!state) state = $s.bsTableControl.state = {};
|
|
|
+ $el.trigger('directive-updated.bs.table', [state]);
|
|
|
}, true);
|
|
|
- $(window).resize(function () {
|
|
|
- if (options) $el.bootstrapTable('resetView');
|
|
|
+ $s.$on('$destroy', function () {
|
|
|
+ delete bsTables[$s.$id];
|
|
|
});
|
|
|
}
|
|
|
};
|