angular-table-resize
Advanced tools
Comparing version 1.0.8 to 1.0.9
@@ -25,4 +25,4 @@ { | ||
"angular": "^1.5.7", | ||
"jquery": "^3.0.0" | ||
"jquery": "^2.0.0" | ||
} | ||
} |
var devapp = angular.module("DemoApp", ["ngTableResize"]); | ||
devapp.controller('main-controller', ['$scope', '$timeout', function($scope, $timeout) { | ||
$scope.hello = "Hello world"; | ||
$scope.profile = "profile1" | ||
$scope.tableMode = "FixedResizer"; | ||
$scope.tableMode = "BasicResizer"; | ||
var i = 1; | ||
@@ -15,4 +14,2 @@ | ||
$scope.columns = ['Name', 'Status', 'Notes', 'More', 'Even More'] | ||
$scope.items = ["One", "Tow", "Three", "Four"]; | ||
@@ -25,27 +22,2 @@ | ||
function getRandomInt(min, max) { | ||
min = Math.ceil(min); | ||
max = Math.floor(max); | ||
return Math.floor(Math.random() * (max - min)) + min; | ||
} | ||
$scope.shuffleColumns = function() { | ||
console.log('Shuffle'); | ||
$scope.columns = $scope.columns.sort(function() { | ||
var r = getRandomInt(-1,1) | ||
console.log(r); | ||
return r | ||
}) | ||
} | ||
var j = 1; | ||
$scope.addColumn = function() { | ||
$scope.columns.unshift('Col'+(j++)) | ||
} | ||
$scope.removeColumn = function() { | ||
$scope.columns.pop() | ||
} | ||
$scope.removeItem = function() { | ||
@@ -52,0 +24,0 @@ $scope.items.pop(); |
angular.module("ngTableResize", []); | ||
angular.module("ngTableResize").directive('resizable', ['resizeStorage', '$injector', function(resizeStorage, $injector) { | ||
angular.module("ngTableResize").directive('resizeable', ['resizeStorage', '$injector', function(resizeStorage, $injector) { | ||
function controller() { | ||
this.columns = [] | ||
this.isFirstDrag = true | ||
this.resizer = getResizer(this) | ||
var cache = resizeStorage.loadTableSizes(this.id, this.mode, this.profile) | ||
var mode; | ||
this.addColumn = function(column) { | ||
if (Number.isInteger(column.$index)){ | ||
this.columns.splice(column.$index, 0, column); | ||
} else { | ||
this.columns.push(column) | ||
} | ||
} | ||
var columns = null; | ||
var ctrlColumns = null; | ||
var handleColumns = null; | ||
var table = null; | ||
var container = null; | ||
var resizer = null; | ||
var isFirstDrag = true; | ||
this.loadSavedColumns = function() { | ||
cache = resizeStorage.loadTableSizes(this.id, this.mode, this.profile) | ||
} | ||
var cache = null; | ||
this.injectResizer = function() { | ||
if (this.resizer) { | ||
this.resizer.tearDown(); | ||
} | ||
var resizer = getResizer(this) | ||
if (resizer !== null) { | ||
this.resizer = resizer | ||
} | ||
this.loadSavedColumns() | ||
} | ||
function link(scope, element, attr) { | ||
// Set global reference to table | ||
table = element; | ||
this.getStoredWidth = function(column) { | ||
return cache[column.resize]; | ||
} | ||
// Set global reference to container | ||
container = scope.container ? $(scope.container) : $(table).parent(); | ||
this.initialiseColumns = function() { | ||
if (this.canRestoreColumns()) { | ||
this.initSavedColumns() | ||
} else { | ||
this.initDefaultColumns() | ||
} | ||
} | ||
// Add css styling/properties to table | ||
$(table).addClass('resize'); | ||
this.canRestoreColumns = function() { | ||
var self = this | ||
var strict = true | ||
if (this.resizer.strictSaving === true) { | ||
strict = Object.keys(cache).length === self.columns.length | ||
} | ||
var restore = this.columns.every(function(column) { | ||
return self.getStoredWidth(column) || self.resizer.newColumnWidth(column); | ||
}) | ||
return strict && restore | ||
} | ||
// Initialise handlers, bindings and modes | ||
initialiseAll(table, attr, scope); | ||
this.render = function() { | ||
if (!this.columns || this.columns.length === 0) return | ||
this.resetAll(); | ||
this.initialiseAll(); | ||
this.resizer.setup() | ||
this.initialiseColumns() | ||
} | ||
// Bind utility functions to scope object | ||
bindUtilityFunctions(table, attr, scope) | ||
this.initSavedColumns = function() { | ||
var self = this | ||
this.columns.forEach(function(column) { | ||
column.setWidth(self.getStoredWidth(column) || self.resizer.newColumnWidth(column)) | ||
}) | ||
this.resizer.onTableReady() | ||
this.virgin = false | ||
} | ||
// Watch for mode changes and update all | ||
watchModeChange(table, attr, scope); | ||
} | ||
this.initDefaultColumns = function() { | ||
var self = this | ||
cache = {} | ||
this.columns.forEach(function(column) { | ||
column.setWidth(self.resizer.defaultWidth(column)) | ||
}) | ||
this.virgin = true | ||
} | ||
this.getColumns = function() { | ||
return this.columns.map(function(column) { | ||
return column.element | ||
}) | ||
} | ||
this.removeColumn = function(column) { | ||
var index = this.columns.indexOf(column) | ||
if (index > -1) { | ||
this.columns.splice(index, 1); | ||
function bindUtilityFunctions(table, attr, scope) { | ||
if (scope.bind === undefined) return; | ||
scope.bind = { | ||
update: function() { | ||
cleanUpAll(table); | ||
initialiseAll(table, attr, scope); | ||
} | ||
this.resetAll(); | ||
this.initialiseAll(); | ||
this.initialiseColumns(); | ||
} | ||
this.deleteHandles = function() { | ||
this.columns.forEach(function(column) { | ||
column.deleteHandle() | ||
}) | ||
} | ||
this.resetAll = function() { | ||
this.isFirstDrag = true | ||
this.virgin = true | ||
this.deleteHandles() | ||
} | ||
this.initialiseAll = function() { | ||
this.columns.forEach(function(column) { | ||
column.initialise() | ||
}) | ||
} | ||
this.saveColumnSizes = function() { | ||
var self = this | ||
if (!cache) cache = {}; | ||
this.columns.forEach(function(column) { | ||
cache[column.resize] = self.resizer.saveAttr(column); | ||
}) | ||
resizeStorage.saveTableSizes(this.id, this.mode, this.profile, cache); | ||
} | ||
this.nextColumn = function(column) { | ||
var index = this.columns.indexOf(column) | ||
if (index === -1 || index >= this.columns.length) { | ||
return undefined | ||
} else { | ||
return this.columns[index + 1] | ||
} | ||
} | ||
} | ||
function compile(element, attr) { | ||
element.addClass('resize') | ||
return link | ||
} | ||
function link(scope, element, attr, ctrl) { | ||
// Set global reference to table | ||
ctrl.table = $(element) | ||
// Set global reference to container | ||
ctrl.container = attr.container ? $(attr.container) : element.parent(); | ||
// Watch for changes | ||
watchModeChange(scope, element, ctrl); | ||
} | ||
function watchModeChange(scope, element, ctrl) { | ||
function watchModeChange(table, attr, scope) { | ||
scope.$watch(function() { | ||
return ctrl.mode; | ||
}, function(newMode) { | ||
if (newMode) { | ||
ctrl.injectResizer(); | ||
ctrl.render(); | ||
} | ||
return scope.mode; | ||
}, function(/*newMode*/) { | ||
cleanUpAll(table); | ||
initialiseAll(table, attr, scope); | ||
}); | ||
} | ||
scope.$watch(function() { | ||
return ctrl.profile; | ||
}, function(newProfile) { | ||
if (newProfile) { | ||
ctrl.loadSavedColumns() | ||
ctrl.initialiseColumns() | ||
} | ||
}) | ||
function analyzeColumns() { | ||
var columns = [] | ||
$(element).find('th').each(function(index, header) { | ||
columns.push(angular.element(header).scope()) | ||
}) | ||
return columns | ||
} | ||
scope.$watch(function(){ | ||
return ctrl.columnsCollection | ||
}, function(){ | ||
ctrl.columns = analyzeColumns() | ||
ctrl.render() | ||
}, true) | ||
function cleanUpAll(table) { | ||
isFirstDrag = true; | ||
deleteHandles(table); | ||
} | ||
@@ -195,126 +66,88 @@ | ||
function getResizer(scope) { | ||
try { | ||
var mode = scope.mode ? scope.mode : 'BasicResizer'; | ||
var Resizer = $injector.get(mode) | ||
if (!Resizer) return; | ||
return new Resizer(scope); | ||
} catch (e) { | ||
console.error("The resizer "+ scope.mode +" was not found"); | ||
return null; | ||
} | ||
function deleteHandles(table) { | ||
$(table).find('th').find('.handle').remove(); | ||
} | ||
// Return this directive as an object literal | ||
return { | ||
restrict: 'A', | ||
priority: 0, | ||
compile: compile, | ||
controller: controller, | ||
controllerAs: 'rzctrl', | ||
bindToController: true, | ||
scope: { | ||
id: '@', | ||
mode: '=?', | ||
profile: '=?', | ||
columnsCollection: '=?columns', | ||
bind: '=?' | ||
} | ||
}; | ||
function initialiseAll(table, attr, scope) { | ||
// Get all column headers | ||
columns = $(table).find('th'); | ||
}]); | ||
mode = scope.mode; | ||
angular.module("ngTableResize").directive('resize', [function() { | ||
// Get the resizer object for the current mode | ||
var ResizeModel = getResizer(scope, attr); | ||
if (!ResizeModel) return; | ||
resizer = new ResizeModel(table, columns, container); | ||
// Load column sized from saved storage | ||
cache = resizeStorage.loadTableSizes(table, scope.mode) | ||
// Return this directive as a object literal | ||
return { | ||
restrict: 'A', | ||
compile: compile, | ||
require: '^^resizable', | ||
scope: false | ||
}; | ||
// Decide which columns should have a handler attached | ||
handleColumns = resizer.handles(columns); | ||
function compile() { | ||
return { | ||
pre: prelink, | ||
post: postlink | ||
} | ||
} | ||
// Decide which columns are controlled and resized | ||
ctrlColumns = resizer.ctrlColumns; | ||
function prelink(scope, element, attr, ctrl) { | ||
scope.resize = scope.$eval(attr.resize) | ||
scope.element = element | ||
// Execute setup function for the given resizer mode | ||
resizer.setup(); | ||
scope.deleteHandle = function() { | ||
if (scope.handle) { | ||
scope.handle.remove() | ||
} | ||
} | ||
// Set column sizes from cache | ||
setColumnSizes(cache); | ||
scope.addHandle = function() { | ||
initHandle(scope, ctrl, element) | ||
} | ||
// Initialise all handlers for every column | ||
handleColumns.each(function(index, column) { | ||
initHandle(table, column); | ||
}) | ||
scope.initialise = function() { | ||
if (ctrl.resizer.handles(scope)) { | ||
initHandle(scope, ctrl, element) | ||
} | ||
} | ||
//scope.setWidth(ctrl.getStoredWidth()) | ||
function setColumnSizes(cache) { | ||
if (!cache) { | ||
resetTable(table); | ||
return; | ||
} | ||
scope.setWidth = function(width) { | ||
element.css({ width: width }) | ||
} | ||
$(table).width('auto'); | ||
scope.next = function() { | ||
return ctrl.nextColumn(scope) | ||
} | ||
ctrlColumns.each(function(index, column){ | ||
var id = $(column).attr('id'); | ||
var cacheWidth = cache[id]; | ||
$(column).css({ width: cacheWidth }); | ||
}) | ||
scope.getWidth = function() { | ||
return scope.element.outerWidth() | ||
} | ||
scope.$on('$destroy', function() { | ||
ctrl.removeColumn(scope) | ||
}); | ||
//ctrl.addColumn(scope) | ||
resizer.onTableReady(); | ||
} | ||
function postlink(scope, element, attr, ctrl) { | ||
return | ||
} | ||
function initHandle(scope, ctrl, column) { | ||
function initHandle(table, column) { | ||
// Prepend a new handle div to the column | ||
scope.handle = $('<div>', { | ||
var handle = $('<div>', { | ||
class: 'handle' | ||
}); | ||
column.prepend(scope.handle); | ||
$(column).prepend(handle); | ||
// Make handle as tall as the table | ||
//$(handle).height($(table).height()) | ||
// Use the middleware to decide which columns this handle controls | ||
scope.controlledColumn = ctrl.resizer.handleMiddleware(scope, ctrl.collumns) | ||
var controlledColumn = resizer.handleMiddleware(handle, column) | ||
// Bind mousedown, mousemove & mouseup events | ||
bindEventToHandle(scope, ctrl); | ||
bindEventToHandle(table, handle, controlledColumn); | ||
} | ||
function bindEventToHandle(scope, ctrl) { | ||
function bindEventToHandle(table, handle, column) { | ||
// This event starts the dragging | ||
$(scope.handle).mousedown(function(event) { | ||
if (ctrl.isFirstDrag) { | ||
ctrl.resizer.onFirstDrag(); | ||
ctrl.resizer.onTableReady() | ||
ctrl.isFirstDrag = false; | ||
ctrl.virgin = false | ||
$(handle).mousedown(function(event) { | ||
if (isFirstDrag) { | ||
resizer.onFirstDrag(column, handle); | ||
resizer.onTableReady(); | ||
isFirstDrag = false; | ||
} | ||
var optional = {} | ||
if (ctrl.resizer.intervene) { | ||
optional = ctrl.resizer.intervene.selector(scope.controlledColumn); | ||
if (resizer.intervene) { | ||
optional = resizer.intervene.selector(column); | ||
optional.column = optional; | ||
optional.orgWidth = optional.element.outerWidth(); | ||
optional.orgWidth = $(optional).width(); | ||
} | ||
@@ -326,3 +159,3 @@ | ||
// Change css styles for the handle | ||
$(scope.handle).addClass('active'); | ||
$(handle).addClass('active'); | ||
@@ -334,9 +167,9 @@ // Show the resize cursor globally | ||
var orgX = event.clientX; | ||
var orgWidth = scope.getWidth(); | ||
var orgWidth = $(column).width(); | ||
// On every mouse move, calculate the new width | ||
$(window).mousemove(calculateWidthEvent(scope, ctrl, orgX, orgWidth, optional)) | ||
$(window).mousemove(calculateWidthEvent(column, orgX, orgWidth, optional)) | ||
// Stop dragging as soon as the mouse is released | ||
$(window).one('mouseup', unbindEvent(scope, ctrl, scope.handle)) | ||
$(window).one('mouseup', unbindEvent(handle)) | ||
@@ -346,3 +179,3 @@ }) | ||
function calculateWidthEvent(scope, ctrl, orgX, orgWidth, optional) { | ||
function calculateWidthEvent(column, orgX, orgWidth, optional) { | ||
return function(event) { | ||
@@ -354,19 +187,32 @@ // Get current mouse position | ||
var diffX = newX - orgX; | ||
var newWidth = ctrl.resizer.calculate(orgWidth, diffX); | ||
var newWidth = resizer.calculate(orgWidth, diffX); | ||
// Use restric function to abort potential restriction | ||
if (ctrl.resizer.restrict(newWidth)) return; | ||
if (resizer.restrict(newWidth)) return; | ||
// Extra optional column | ||
if (ctrl.resizer.intervene){ | ||
var optWidth = ctrl.resizer.intervene.calculator(optional.orgWidth, diffX); | ||
if (ctrl.resizer.intervene.restrict(optWidth)) return; | ||
optional.setWidth(optWidth) | ||
if (resizer.intervene){ | ||
var optWidth = resizer.intervene.calculator(optional.orgWidth, diffX); | ||
if (resizer.intervene.restrict(optWidth)) return; | ||
$(optional).width(optWidth) | ||
} | ||
// Set size | ||
scope.controlledColumn.setWidth(newWidth); | ||
$(column).width(newWidth); | ||
} | ||
} | ||
function unbindEvent(scope, ctrl, handle) { | ||
function getResizer(scope, attr) { | ||
try { | ||
var mode = attr.mode ? scope.mode : 'BasicResizer'; | ||
var Resizer = $injector.get(mode) | ||
return Resizer; | ||
} catch (e) { | ||
console.error("The resizer "+ scope.mode +" was not found"); | ||
return null; | ||
} | ||
} | ||
function unbindEvent(handle) { | ||
// Event called at end of drag | ||
@@ -378,7 +224,30 @@ return function( /*event*/ ) { | ||
ctrl.resizer.onEndDrag(); | ||
ctrl.saveColumnSizes(); | ||
resizer.onEndDrag(); | ||
saveColumnSizes(); | ||
} | ||
} | ||
function saveColumnSizes() { | ||
if (!cache) cache = {}; | ||
$(columns).each(function(index, column) { | ||
var id = $(column).attr('id'); | ||
if (!id) return; | ||
cache[id] = resizer.saveAttr(column); | ||
}) | ||
resizeStorage.saveTableSizes(table, mode, cache); | ||
} | ||
// Return this directive as a object literal | ||
return { | ||
restrict: 'A', | ||
link: link, | ||
scope: { | ||
mode: '=', | ||
bind: '=', | ||
container: '@' | ||
} | ||
}; | ||
}]); | ||
@@ -390,10 +259,10 @@ | ||
this.loadTableSizes = function(table, model, profile) { | ||
var key = getStorageKey(table, model, profile); | ||
this.loadTableSizes = function(table, model) { | ||
var key = getStorageKey(table, model); | ||
var object = $window.localStorage.getItem(key); | ||
return JSON.parse(object) || {}; | ||
return JSON.parse(object); | ||
} | ||
this.saveTableSizes = function(table, model, profile, sizes) { | ||
var key = getStorageKey(table, model, profile); | ||
this.saveTableSizes = function(table, model, sizes) { | ||
var key = getStorageKey(table, model); | ||
if (!key) return; | ||
@@ -404,13 +273,9 @@ var string = JSON.stringify(sizes); | ||
function getStorageKey(table, mode, profile) { | ||
var key = [] | ||
if (!table) { | ||
function getStorageKey(table, mode) { | ||
var id = table.attr('id'); | ||
if (!id) { | ||
console.error("Table has no id", table); | ||
return undefined; | ||
} | ||
key.push(prefix) | ||
key.push(table) | ||
key.push(mode) | ||
if (profile) key.push(profile) | ||
return key.join('.') | ||
return prefix + '.' + table.attr('id') + '.' + mode; | ||
} | ||
@@ -422,6 +287,11 @@ | ||
function ResizerModel(rzctrl){ | ||
this.strictSaving = true | ||
this.minWidth = 50; | ||
this.ctrl = rzctrl | ||
function ResizerModel(table, columns, container){ | ||
this.minWidth = 25; | ||
this.table = table; | ||
this.columns = columns; | ||
this.container = container; | ||
this.handleColumns = this.handles(); | ||
this.ctrlColumns = this.ctrlColumns(); | ||
} | ||
@@ -431,3 +301,3 @@ | ||
// Hide overflow by default | ||
$(this.ctrl.container).css({ | ||
$(this.container).css({ | ||
overflowX: 'hidden' | ||
@@ -437,17 +307,5 @@ }) | ||
ResizerModel.prototype.tearDown = function() { | ||
return | ||
} | ||
ResizerModel.prototype.defaultWidth = function(column) { | ||
return 'auto' | ||
} | ||
ResizerModel.prototype.newColumnWidth = function(column) { | ||
return false | ||
} | ||
ResizerModel.prototype.onTableReady = function () { | ||
// Table is by default 100% width | ||
$(this.ctrl.table).outerWidth('100%'); | ||
$(this.table).outerWidth('100%'); | ||
}; | ||
@@ -457,3 +315,3 @@ | ||
// By default all columns should be assigned a handle | ||
return true | ||
return this.columns; | ||
}; | ||
@@ -463,3 +321,3 @@ | ||
// By default all columns assigned a handle are resized | ||
return true | ||
return this.handleColumns; | ||
}; | ||
@@ -469,8 +327,8 @@ | ||
// By default, set all columns to absolute widths | ||
this.ctrl.columns.forEach(function(column) { | ||
column.setWidth(column.getWidth()); | ||
$(this.ctrlColumns).each(function(index, column) { | ||
$(column).width($(column).width()); | ||
}) | ||
}; | ||
ResizerModel.prototype.handleMiddleware = function (column, columns) { | ||
ResizerModel.prototype.handleMiddleware = function (handle, column) { | ||
// By default, every handle controls the column it is placed in | ||
@@ -496,3 +354,3 @@ return column; | ||
ResizerModel.prototype.saveAttr = function (column) { | ||
return column.getWidth() | ||
return $(column).outerWidth(); | ||
}; | ||
@@ -523,3 +381,3 @@ | ||
function interveneSelector(column) { | ||
return column.next() | ||
return $(column).next() | ||
} | ||
@@ -532,8 +390,8 @@ | ||
function interveneRestrict(newWidth){ | ||
return newWidth < 50; | ||
return newWidth < 25; | ||
} | ||
BasicResizer.prototype.setup = function(container, columns) { | ||
BasicResizer.prototype.setup = function() { | ||
// Hide overflow in mode fixed | ||
this.ctrl.container.css({ | ||
$(this.container).css({ | ||
overflowX: 'hidden' | ||
@@ -543,11 +401,10 @@ }) | ||
// First column is auto to compensate for 100% table width | ||
this.ctrl.columns[0].setWidth('auto') | ||
// $(columns).first().css({ | ||
// width: 'auto' | ||
// }); | ||
$(this.columns).first().css({ | ||
width: 'auto' | ||
}); | ||
}; | ||
BasicResizer.prototype.handles = function(column) { | ||
BasicResizer.prototype.handles = function() { | ||
// Mode fixed does not require handler on last column | ||
return column.$last !== true | ||
return $(this.columns).not(':last') | ||
}; | ||
@@ -557,4 +414,4 @@ | ||
// Replace all column's width with absolute measurements | ||
this.ctrl.columns.forEach(function(column) { | ||
column.setWidth(column.getWidth()); | ||
$(this.columns).each(function(index, column) { | ||
$(column).width($(column).width()); | ||
}) | ||
@@ -565,10 +422,11 @@ }; | ||
// Calculates the percent width of each column | ||
var totWidth = $(this.ctrl.table).outerWidth(); | ||
var totWidth = $(this.table).outerWidth(); | ||
var totPercent = 0; | ||
this.ctrl.columns.forEach(function(column) { | ||
var colWidth = column.getWidth(); | ||
$(this.columns).each(function(index, column) { | ||
var colWidth = $(column).outerWidth(); | ||
var percentWidth = colWidth / totWidth * 100 + '%'; | ||
totPercent += (colWidth / totWidth * 100); | ||
column.setWidth(percentWidth) | ||
$(column).css({ width: percentWidth }); | ||
}) | ||
@@ -579,3 +437,3 @@ | ||
BasicResizer.prototype.saveAttr = function (column) { | ||
return $(column.element)[0].style.width; | ||
return $(column)[0].style.width; | ||
}; | ||
@@ -668,3 +526,2 @@ | ||
ResizerModel.call(this, table, columns, container) | ||
this.strictSaving = false | ||
} | ||
@@ -675,9 +532,6 @@ | ||
OverflowResizer.prototype.newColumnWidth = function(column) { | ||
return 150 | ||
} | ||
OverflowResizer.prototype.setup = function() { | ||
// Allow overflow in this mode | ||
$(this.ctrl.container).css({ | ||
$(this.container).css({ | ||
overflow: 'auto' | ||
@@ -687,9 +541,5 @@ }); | ||
OverflowResizer.prototype.tearDown = function() { | ||
$(this.ctrl.table).width(''); | ||
} | ||
OverflowResizer.prototype.onTableReady = function() { | ||
// For mode overflow, make table as small as possible | ||
$(this.ctrl.table).width(1); | ||
$(this.table).width(1); | ||
}; | ||
@@ -696,0 +546,0 @@ |
@@ -1,1 +0,1 @@ | ||
angular.module("ngTableResize",[]),angular.module("ngTableResize").directive("resizable",["resizeStorage","$injector",function(t,e){function n(){this.columns=[],this.isFirstDrag=!0,this.resizer=s(this);var e=t.loadTableSizes(this.id,this.mode,this.profile);this.addColumn=function(t){Number.isInteger(t.$index)?this.columns.splice(t.$index,0,t):this.columns.push(t)},this.loadSavedColumns=function(){e=t.loadTableSizes(this.id,this.mode,this.profile)},this.injectResizer=function(){this.resizer&&this.resizer.tearDown();var t=s(this);null!==t&&(this.resizer=t),this.loadSavedColumns()},this.getStoredWidth=function(t){return e[t.resize]},this.initialiseColumns=function(){this.canRestoreColumns()?this.initSavedColumns():this.initDefaultColumns()},this.canRestoreColumns=function(){var t=this,n=!0;this.resizer.strictSaving===!0&&(n=Object.keys(e).length===t.columns.length);var i=this.columns.every(function(e){return t.getStoredWidth(e)||t.resizer.newColumnWidth(e)});return n&&i},this.render=function(){this.columns&&0!==this.columns.length&&(this.resetAll(),this.initialiseAll(),this.resizer.setup(),this.initialiseColumns())},this.initSavedColumns=function(){var t=this;this.columns.forEach(function(e){e.setWidth(t.getStoredWidth(e)||t.resizer.newColumnWidth(e))}),this.resizer.onTableReady(),this.virgin=!1},this.initDefaultColumns=function(){var t=this;e={},this.columns.forEach(function(e){e.setWidth(t.resizer.defaultWidth(e))}),this.virgin=!0},this.getColumns=function(){return this.columns.map(function(t){return t.element})},this.removeColumn=function(t){var e=this.columns.indexOf(t);e>-1&&this.columns.splice(e,1),this.resetAll(),this.initialiseAll(),this.initialiseColumns()},this.deleteHandles=function(){this.columns.forEach(function(t){t.deleteHandle()})},this.resetAll=function(){this.isFirstDrag=!0,this.virgin=!0,this.deleteHandles()},this.initialiseAll=function(){this.columns.forEach(function(t){t.initialise()})},this.saveColumnSizes=function(){var n=this;e||(e={}),this.columns.forEach(function(t){e[t.resize]=n.resizer.saveAttr(t)}),t.saveTableSizes(this.id,this.mode,this.profile,e)},this.nextColumn=function(t){var e=this.columns.indexOf(t);return e===-1||e>=this.columns.length?void 0:this.columns[e+1]}}function i(t,e){return t.addClass("resize"),o}function o(t,e,n,i){i.table=$(e),i.container=n.container?$(n.container):e.parent(),r(t,e,i)}function r(t,e,n){function i(){var t=[];return $(e).find("th").each(function(e,n){t.push(angular.element(n).scope())}),t}t.$watch(function(){return n.mode},function(t){t&&(n.injectResizer(),n.render())}),t.$watch(function(){return n.profile},function(t){t&&(n.loadSavedColumns(),n.initialiseColumns())}),t.$watch(function(){return n.columnsCollection},function(){n.columns=i(),n.render()},!0)}function s(t){try{var n=t.mode?t.mode:"BasicResizer",i=e.get(n);if(!i)return;return new i(t)}catch(o){return console.error("The resizer "+t.mode+" was not found"),null}}return{restrict:"A",priority:0,compile:i,controller:n,controllerAs:"rzctrl",bindToController:!0,scope:{id:"@",mode:"=?",profile:"=?",columnsCollection:"=?columns",bind:"=?"}}}]),angular.module("ngTableResize").directive("resize",[function(){function t(){return{pre:e,post:n}}function e(t,e,n,o){t.resize=t.$eval(n.resize),t.element=e,t.deleteHandle=function(){t.handle&&t.handle.remove()},t.addHandle=function(){i(t,o,e)},t.initialise=function(){o.resizer.handles(t)&&i(t,o,e)},t.setWidth=function(t){e.css({width:t})},t.next=function(){return o.nextColumn(t)},t.getWidth=function(){return t.element.outerWidth()},t.$on("$destroy",function(){o.removeColumn(t)})}function n(t,e,n,i){}function i(t,e,n){t.handle=$("<div>",{"class":"handle"}),n.prepend(t.handle),t.controlledColumn=e.resizer.handleMiddleware(t,e.collumns),o(t,e)}function o(t,e){$(t.handle).mousedown(function(n){e.isFirstDrag&&(e.resizer.onFirstDrag(),e.resizer.onTableReady(),e.isFirstDrag=!1,e.virgin=!1);var i={};e.resizer.intervene&&(i=e.resizer.intervene.selector(t.controlledColumn),i.column=i,i.orgWidth=i.element.outerWidth()),n.preventDefault(),$(t.handle).addClass("active"),$("body").addClass("table-resize");var o=n.clientX,u=t.getWidth();$(window).mousemove(r(t,e,o,u,i)),$(window).one("mouseup",s(t,e,t.handle))})}function r(t,e,n,i,o){return function(r){var s=r.clientX,u=s-n,l=e.resizer.calculate(i,u);if(!e.resizer.restrict(l)){if(e.resizer.intervene){var c=e.resizer.intervene.calculator(o.orgWidth,u);if(e.resizer.intervene.restrict(c))return;o.setWidth(c)}t.controlledColumn.setWidth(l)}}}function s(t,e,n){return function(){$(n).removeClass("active"),$(window).unbind("mousemove"),$("body").removeClass("table-resize"),e.resizer.onEndDrag(),e.saveColumnSizes()}}return{restrict:"A",compile:t,require:"^^resizable",scope:!1}}]),angular.module("ngTableResize").service("resizeStorage",["$window",function(t){function e(t,e,i){var o=[];return t?(o.push(n),o.push(t),o.push(e),i&&o.push(i),o.join(".")):void console.error("Table has no id",t)}var n="ngColumnResize";this.loadTableSizes=function(n,i,o){var r=e(n,i,o),s=t.localStorage.getItem(r);return JSON.parse(s)||{}},this.saveTableSizes=function(n,i,o,r){var s=e(n,i,o);if(s){var u=JSON.stringify(r);t.localStorage.setItem(s,u)}}}]),angular.module("ngTableResize").factory("ResizerModel",[function(){function t(t){this.strictSaving=!0,this.minWidth=50,this.ctrl=t}return t.prototype.setup=function(){$(this.ctrl.container).css({overflowX:"hidden"})},t.prototype.tearDown=function(){},t.prototype.defaultWidth=function(t){return"auto"},t.prototype.newColumnWidth=function(t){return!1},t.prototype.onTableReady=function(){$(this.ctrl.table).outerWidth("100%")},t.prototype.handles=function(){return!0},t.prototype.ctrlColumns=function(){return!0},t.prototype.onFirstDrag=function(){this.ctrl.columns.forEach(function(t){t.setWidth(t.getWidth())})},t.prototype.handleMiddleware=function(t,e){return t},t.prototype.restrict=function(t){return t<this.minWidth},t.prototype.calculate=function(t,e){return t+e},t.prototype.onEndDrag=function(){},t.prototype.saveAttr=function(t){return t.getWidth()},t}]),angular.module("ngTableResize").factory("BasicResizer",["ResizerModel",function(t){function e(e,r,s){t.call(this,e,r,s),this.ctrlColumns=this.columns,this.intervene={selector:n,calculator:i,restrict:o}}function n(t){return t.next()}function i(t,e){return t-e}function o(t){return t<50}return e.prototype=Object.create(t.prototype),e.prototype.setup=function(t,e){this.ctrl.container.css({overflowX:"hidden"}),this.ctrl.columns[0].setWidth("auto")},e.prototype.handles=function(t){return t.$last!==!0},e.prototype.onFirstDrag=function(){this.ctrl.columns.forEach(function(t){t.setWidth(t.getWidth())})},e.prototype.onEndDrag=function(){var t=$(this.ctrl.table).outerWidth(),e=0;this.ctrl.columns.forEach(function(n){var i=n.getWidth(),o=i/t*100+"%";e+=i/t*100,n.setWidth(o)})},e.prototype.saveAttr=function(t){return $(t.element)[0].style.width},e}]),angular.module("ngTableResize").factory("FixedResizer",["ResizerModel",function(t){function e(e,n,i){t.call(this,e,n,i),this.fixedColumn=$(e).find("th").first(),this.bound=!1}return e.prototype=Object.create(t.prototype),e.prototype.setup=function(){$(this.container).css({overflowX:"hidden"}),$(this.columns).first().css({width:"auto"})},e.prototype.handles=function(){return $(this.columns).not(":last")},e.prototype.ctrlColumns=function(){return $(this.columns).not(":first")},e.prototype.onFirstDrag=function(){$(this.ctrlColumns).each(function(t,e){$(e).width($(e).width())})},e.prototype.handleMiddleware=function(t,e){return $(e).next()},e.prototype.restrict=function(t){return this.bound?!(t<this.bound)||($(this.fixedColumn).width("auto"),this.bound=!1,!1):t<this.minWidth||($(this.fixedColumn).width()<=this.minWidth?(this.bound=t,$(this.fixedColumn).width(this.minWidth),!0):void 0)},e.prototype.calculate=function(t,e){return t-e},e}]),angular.module("ngTableResize").factory("OverflowResizer",["ResizerModel",function(t){function e(e,n,i){t.call(this,e,n,i),this.strictSaving=!1}return e.prototype=Object.create(t.prototype),e.prototype.newColumnWidth=function(t){return 150},e.prototype.setup=function(){$(this.ctrl.container).css({overflow:"auto"})},e.prototype.tearDown=function(){$(this.ctrl.table).width("")},e.prototype.onTableReady=function(){$(this.ctrl.table).width(1)},e}]); | ||
angular.module("ngTableResize",[]),angular.module("ngTableResize").directive("resizeable",["resizeStorage","$injector",function(t,n){function e(t,n,e){g=n,z=t.container?$(t.container):$(g).parent(),$(g).addClass("resize"),a(g,e,t),o(g,e,t),i(g,e,t)}function o(t,n,e){void 0!==e.bind&&(e.bind={update:function(){r(t),a(t,n,e)}})}function i(t,n,e){e.$watch(function(){return e.mode},function(){r(t),a(t,n,e)})}function r(t){R=!0,s(t)}function u(t){$(t).outerWidth("100%"),$(t).find("th").width("auto")}function s(t){$(t).find("th").find(".handle").remove()}function a(n,e,o){y=$(n).find("th"),v=o.mode;var i=f(o,e);i&&(C=new i(n,y,z),T=t.loadTableSizes(n,o.mode),b=C.handles(y),w=C.ctrlColumns,C.setup(),c(T),b.each(function(t,e){l(n,e)}))}function c(t){return t?($(g).width("auto"),w.each(function(n,e){var o=$(e).attr("id"),i=t[o];$(e).css({width:i})}),void C.onTableReady()):void u(g)}function l(t,n){var e=$("<div>",{"class":"handle"});$(n).prepend(e);var o=C.handleMiddleware(e,n);d(t,e,o)}function d(t,n,e){$(n).mousedown(function(t){R&&(C.onFirstDrag(e,n),C.onTableReady(),R=!1);var o={};C.intervene&&(o=C.intervene.selector(e),o.column=o,o.orgWidth=$(o).width()),t.preventDefault(),$(n).addClass("active"),$("body").addClass("table-resize");var i=t.clientX,r=$(e).width();$(window).mousemove(h(e,i,r,o)),$(window).one("mouseup",p(n))})}function h(t,n,e,o){return function(i){var r=i.clientX,u=r-n,s=C.calculate(e,u);if(!C.restrict(s)){if(C.intervene){var a=C.intervene.calculator(o.orgWidth,u);if(C.intervene.restrict(a))return;$(o).width(a)}$(t).width(s)}}}function f(t,e){try{var o=e.mode?t.mode:"BasicResizer",i=n.get(o);return i}catch(r){return console.error("The resizer "+t.mode+" was not found"),null}}function p(t){return function(){$(t).removeClass("active"),$(window).unbind("mousemove"),$("body").removeClass("table-resize"),C.onEndDrag(),m()}}function m(){T||(T={}),$(y).each(function(t,n){var e=$(n).attr("id");e&&(T[e]=C.saveAttr(n))}),t.saveTableSizes(g,v,T)}var v,y=null,w=null,b=null,g=null,z=null,C=null,R=!0,T=null;return{restrict:"A",link:e,scope:{mode:"=",bind:"=",container:"@"}}}]),angular.module("ngTableResize").service("resizeStorage",["$window",function(t){function n(t,n){var o=t.attr("id");return o?e+"."+t.attr("id")+"."+n:void console.error("Table has no id",t)}var e="ngColumnResize";this.loadTableSizes=function(e,o){var i=n(e,o),r=t.localStorage.getItem(i);return JSON.parse(r)},this.saveTableSizes=function(e,o,i){var r=n(e,o);if(r){var u=JSON.stringify(i);t.localStorage.setItem(r,u)}}}]),angular.module("ngTableResize").factory("ResizerModel",[function(){function t(t,n,e){this.minWidth=25,this.table=t,this.columns=n,this.container=e,this.handleColumns=this.handles(),this.ctrlColumns=this.ctrlColumns()}return t.prototype.setup=function(){$(this.container).css({overflowX:"hidden"})},t.prototype.onTableReady=function(){$(this.table).outerWidth("100%")},t.prototype.handles=function(){return this.columns},t.prototype.ctrlColumns=function(){return this.handleColumns},t.prototype.onFirstDrag=function(){$(this.ctrlColumns).each(function(t,n){$(n).width($(n).width())})},t.prototype.handleMiddleware=function(t,n){return n},t.prototype.restrict=function(t){return t<this.minWidth},t.prototype.calculate=function(t,n){return t+n},t.prototype.onEndDrag=function(){},t.prototype.saveAttr=function(t){return $(t).outerWidth()},t}]),angular.module("ngTableResize").factory("BasicResizer",["ResizerModel",function(t){function n(n,r,u){t.call(this,n,r,u),this.ctrlColumns=this.columns,this.intervene={selector:e,calculator:o,restrict:i}}function e(t){return $(t).next()}function o(t,n){return t-n}function i(t){return t<25}return n.prototype=Object.create(t.prototype),n.prototype.setup=function(){$(this.container).css({overflowX:"hidden"}),$(this.columns).first().css({width:"auto"})},n.prototype.handles=function(){return $(this.columns).not(":last")},n.prototype.onFirstDrag=function(){$(this.columns).each(function(t,n){$(n).width($(n).width())})},n.prototype.onEndDrag=function(){var t=$(this.table).outerWidth(),n=0;$(this.columns).each(function(e,o){var i=$(o).outerWidth(),r=i/t*100+"%";n+=i/t*100,$(o).css({width:r})})},n.prototype.saveAttr=function(t){return $(t)[0].style.width},n}]),angular.module("ngTableResize").factory("FixedResizer",["ResizerModel",function(t){function n(n,e,o){t.call(this,n,e,o),this.fixedColumn=$(n).find("th").first(),this.bound=!1}return n.prototype=Object.create(t.prototype),n.prototype.setup=function(){$(this.container).css({overflowX:"hidden"}),$(this.columns).first().css({width:"auto"})},n.prototype.handles=function(){return $(this.columns).not(":last")},n.prototype.ctrlColumns=function(){return $(this.columns).not(":first")},n.prototype.onFirstDrag=function(){$(this.ctrlColumns).each(function(t,n){$(n).width($(n).width())})},n.prototype.handleMiddleware=function(t,n){return $(n).next()},n.prototype.restrict=function(t){return this.bound?!(t<this.bound)||($(this.fixedColumn).width("auto"),this.bound=!1,!1):t<this.minWidth||($(this.fixedColumn).width()<=this.minWidth?(this.bound=t,$(this.fixedColumn).width(this.minWidth),!0):void 0)},n.prototype.calculate=function(t,n){return t-n},n}]),angular.module("ngTableResize").factory("OverflowResizer",["ResizerModel",function(t){function n(n,e,o){t.call(this,n,e,o)}return n.prototype=Object.create(t.prototype),n.prototype.setup=function(){$(this.container).css({overflow:"auto"})},n.prototype.onTableReady=function(){$(this.table).width(1)},n}]); |
@@ -12,4 +12,3 @@ /*jshint esversion: 6 */ | ||
"scripts/angular-table-resize.js", | ||
"scripts/directives/resizable-directive.js", | ||
"scripts/directives/resize-directive.js", | ||
"scripts/directives/resizeable-directive.js", | ||
"scripts/services/resize-storage-service.js", | ||
@@ -42,7 +41,7 @@ "scripts/services/resizer-factory.js", | ||
gulp.task('watch', function() { | ||
gulp.watch(['index.html', 'css/**', 'scripts/**', 'views/**', 'demo/**'], ['build']); | ||
gulp.watch(['index.html', 'css/**', 'scripts/**', 'views/**', 'demo/**'], browsersync.reload); | ||
}); | ||
gulp.task('dev', function() { | ||
runSequence('build', 'serve', 'watch'); | ||
runSequence('serve', 'watch'); | ||
}); | ||
@@ -57,3 +56,2 @@ | ||
.pipe(gulp.dest(DIST)) | ||
.pipe(browsersync.reload({ stream:true })) | ||
}) | ||
@@ -67,3 +65,2 @@ | ||
.pipe(gulp.dest(DIST)) | ||
.pipe(browsersync.reload({ stream:true })) | ||
}) | ||
@@ -70,0 +67,0 @@ |
{ | ||
"name": "angular-table-resize", | ||
"version": "1.0.8", | ||
"version": "1.0.9", | ||
"description": "An AngularJS module for resizing table columns!", | ||
@@ -5,0 +5,0 @@ "main": "./dist/angular-table-resize.js", |
@@ -21,3 +21,3 @@ angular.module("ngTableResize").factory("BasicResizer", ["ResizerModel", function(ResizerModel) { | ||
function interveneSelector(column) { | ||
return column.next() | ||
return $(column).next() | ||
} | ||
@@ -30,8 +30,8 @@ | ||
function interveneRestrict(newWidth){ | ||
return newWidth < 50; | ||
return newWidth < 25; | ||
} | ||
BasicResizer.prototype.setup = function(container, columns) { | ||
BasicResizer.prototype.setup = function() { | ||
// Hide overflow in mode fixed | ||
this.ctrl.container.css({ | ||
$(this.container).css({ | ||
overflowX: 'hidden' | ||
@@ -41,11 +41,10 @@ }) | ||
// First column is auto to compensate for 100% table width | ||
this.ctrl.columns[0].setWidth('auto') | ||
// $(columns).first().css({ | ||
// width: 'auto' | ||
// }); | ||
$(this.columns).first().css({ | ||
width: 'auto' | ||
}); | ||
}; | ||
BasicResizer.prototype.handles = function(column) { | ||
BasicResizer.prototype.handles = function() { | ||
// Mode fixed does not require handler on last column | ||
return column.$last !== true | ||
return $(this.columns).not(':last') | ||
}; | ||
@@ -55,4 +54,4 @@ | ||
// Replace all column's width with absolute measurements | ||
this.ctrl.columns.forEach(function(column) { | ||
column.setWidth(column.getWidth()); | ||
$(this.columns).each(function(index, column) { | ||
$(column).width($(column).width()); | ||
}) | ||
@@ -63,10 +62,11 @@ }; | ||
// Calculates the percent width of each column | ||
var totWidth = $(this.ctrl.table).outerWidth(); | ||
var totWidth = $(this.table).outerWidth(); | ||
var totPercent = 0; | ||
this.ctrl.columns.forEach(function(column) { | ||
var colWidth = column.getWidth(); | ||
$(this.columns).each(function(index, column) { | ||
var colWidth = $(column).outerWidth(); | ||
var percentWidth = colWidth / totWidth * 100 + '%'; | ||
totPercent += (colWidth / totWidth * 100); | ||
column.setWidth(percentWidth) | ||
$(column).css({ width: percentWidth }); | ||
}) | ||
@@ -77,3 +77,3 @@ | ||
BasicResizer.prototype.saveAttr = function (column) { | ||
return $(column.element)[0].style.width; | ||
return $(column)[0].style.width; | ||
}; | ||
@@ -80,0 +80,0 @@ |
@@ -6,3 +6,2 @@ angular.module("ngTableResize").factory("OverflowResizer", ["ResizerModel", function(ResizerModel) { | ||
ResizerModel.call(this, table, columns, container) | ||
this.strictSaving = false | ||
} | ||
@@ -13,9 +12,6 @@ | ||
OverflowResizer.prototype.newColumnWidth = function(column) { | ||
return 150 | ||
} | ||
OverflowResizer.prototype.setup = function() { | ||
// Allow overflow in this mode | ||
$(this.ctrl.container).css({ | ||
$(this.container).css({ | ||
overflow: 'auto' | ||
@@ -25,9 +21,5 @@ }); | ||
OverflowResizer.prototype.tearDown = function() { | ||
$(this.ctrl.table).width(''); | ||
} | ||
OverflowResizer.prototype.onTableReady = function() { | ||
// For mode overflow, make table as small as possible | ||
$(this.ctrl.table).width(1); | ||
$(this.table).width(1); | ||
}; | ||
@@ -34,0 +26,0 @@ |
@@ -5,10 +5,10 @@ angular.module("ngTableResize").service('resizeStorage', ['$window', function($window) { | ||
this.loadTableSizes = function(table, model, profile) { | ||
var key = getStorageKey(table, model, profile); | ||
this.loadTableSizes = function(table, model) { | ||
var key = getStorageKey(table, model); | ||
var object = $window.localStorage.getItem(key); | ||
return JSON.parse(object) || {}; | ||
return JSON.parse(object); | ||
} | ||
this.saveTableSizes = function(table, model, profile, sizes) { | ||
var key = getStorageKey(table, model, profile); | ||
this.saveTableSizes = function(table, model, sizes) { | ||
var key = getStorageKey(table, model); | ||
if (!key) return; | ||
@@ -19,15 +19,11 @@ var string = JSON.stringify(sizes); | ||
function getStorageKey(table, mode, profile) { | ||
var key = [] | ||
if (!table) { | ||
function getStorageKey(table, mode) { | ||
var id = table.attr('id'); | ||
if (!id) { | ||
console.error("Table has no id", table); | ||
return undefined; | ||
} | ||
key.push(prefix) | ||
key.push(table) | ||
key.push(mode) | ||
if (profile) key.push(profile) | ||
return key.join('.') | ||
return prefix + '.' + table.attr('id') + '.' + mode; | ||
} | ||
}]); |
angular.module("ngTableResize").factory("ResizerModel", [function() { | ||
function ResizerModel(rzctrl){ | ||
this.strictSaving = true | ||
this.minWidth = 50; | ||
this.ctrl = rzctrl | ||
function ResizerModel(table, columns, container){ | ||
this.minWidth = 25; | ||
this.table = table; | ||
this.columns = columns; | ||
this.container = container; | ||
this.handleColumns = this.handles(); | ||
this.ctrlColumns = this.ctrlColumns(); | ||
} | ||
@@ -11,3 +16,3 @@ | ||
// Hide overflow by default | ||
$(this.ctrl.container).css({ | ||
$(this.container).css({ | ||
overflowX: 'hidden' | ||
@@ -17,17 +22,5 @@ }) | ||
ResizerModel.prototype.tearDown = function() { | ||
return | ||
} | ||
ResizerModel.prototype.defaultWidth = function(column) { | ||
return 'auto' | ||
} | ||
ResizerModel.prototype.newColumnWidth = function(column) { | ||
return false | ||
} | ||
ResizerModel.prototype.onTableReady = function () { | ||
// Table is by default 100% width | ||
$(this.ctrl.table).outerWidth('100%'); | ||
$(this.table).outerWidth('100%'); | ||
}; | ||
@@ -37,3 +30,3 @@ | ||
// By default all columns should be assigned a handle | ||
return true | ||
return this.columns; | ||
}; | ||
@@ -43,3 +36,3 @@ | ||
// By default all columns assigned a handle are resized | ||
return true | ||
return this.handleColumns; | ||
}; | ||
@@ -49,8 +42,8 @@ | ||
// By default, set all columns to absolute widths | ||
this.ctrl.columns.forEach(function(column) { | ||
column.setWidth(column.getWidth()); | ||
$(this.ctrlColumns).each(function(index, column) { | ||
$(column).width($(column).width()); | ||
}) | ||
}; | ||
ResizerModel.prototype.handleMiddleware = function (column, columns) { | ||
ResizerModel.prototype.handleMiddleware = function (handle, column) { | ||
// By default, every handle controls the column it is placed in | ||
@@ -76,3 +69,3 @@ return column; | ||
ResizerModel.prototype.saveAttr = function (column) { | ||
return column.getWidth() | ||
return $(column).outerWidth(); | ||
}; | ||
@@ -79,0 +72,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
67148
26
1323