Skip to content

Commit

Permalink
feat(saveState): add pinning to save state
Browse files Browse the repository at this point in the history
The idea was to update saveState to include pinning. This turned
out to be more involved than initial anticipated. I ended up
having to update the pinning feature to include a public event
and method so saveState could include pinning as an option.

I updated documentation as I worked through it and even updated the
tutorial to include pinning. This is in reference to an feature
request I made recently #3123.
  • Loading branch information
jonathanchris committed Mar 30, 2015
1 parent 949013c commit b0d943a
Show file tree
Hide file tree
Showing 6 changed files with 318 additions and 32 deletions.
83 changes: 83 additions & 0 deletions misc/demo/grid-save.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html class="no-js" ng-app="test"><!--<![endif]-->
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<title></title>
<meta content="width=device-width" name="viewport">

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" />
<link href="/dist/release/ui-grid.css" rel="stylesheet">

<!--<script src="https://code.jquery.com/jquery-1.11.1.js"></script>-->
<script src="/lib/test/angular/1.2.26/angular.js"></script>
<script src="/dist/release/ui-grid.js"></script>

<style>
body {
padding: 60px;
min-height: 600px;
}
.grid {
width: 500px;
height: 400px;
}
</style>
</head>
<body ng-controller="Main">

<h2>Grid</h2>
<div ui-grid="gridOptions" class="grid" ui-grid-save-state ui-grid-selection ui-grid-cellNav ui-grid-resize-columns ui-grid-move-columns ui-grid-pinning ></div>
<button id="save" type="button" class="btn btn-success" ng-click="saveState()">Save</button>
<button id="restore" type="button" class="btn btn-success" ng-click="restoreState()">Restore</button>

<br>
<br>

<script>
var app = angular.module('test', ['ui.grid', 'ui.grid.pinning', 'ui.grid.resizeColumns', 'ui.grid.saveState']);
app.controller('Main', function($scope, $http) {
$scope.gridOptions = {};
$scope.gridOptions.columnDefs = [
{ name:'id', width:50 },
{ name:'name', width:100, pinnedLeft:true },
{ name:'age', width:100, pinnedRight:true },
{ name:'address.street', width:150 },
{ name:'address.city', width:150 },
{ name:'address.state', width:50 },
{ name:'address.zip', width:50 },
{ name:'company', width:100 },
{ name:'email', width:100 },
{ name:'phone', width:200 },
{ name:'about', width:300 },
{ name:'friends[0].name', displayName:'1st friend', width:150 },
{ name:'friends[1].name', displayName:'2nd friend', width:150 },
{ name:'friends[2].name', displayName:'3rd friend', width:150 }
];
$scope.gridOptions.enableFiltering = true;
$scope.gridOptions.onRegisterApi = function(gridApi) {
$scope.gridApi = gridApi;

gridApi.pinning.on.columnPinned($scope, function(col, action) {
console.log(col, action);
});
};
$scope.state = {};

$scope.saveState = function() {
$scope.state = $scope.gridApi.saveState.save();
};

$scope.restoreState = function() {
$scope.gridApi.saveState.restore( $scope, $scope.state );
};

$http.get('https://rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json')
.success(function(data) {
$scope.gridOptions.data = data;
});
});
</script>
</body>
</html>

8 changes: 5 additions & 3 deletions misc/tutorial/208_save_state.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ default:
- saveVisible
- saveSort
- saveFilter
- savePinning

@example
In this example we provide a button to save the grid state. You can then modify the grid layout
Expand All @@ -38,17 +39,17 @@ to something different, and use the restore button to set the grid back the way

<example module="app">
<file name="app.js">
var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.saveState', 'ui.grid.selection', 'ui.grid.cellNav', 'ui.grid.resizeColumns', 'ui.grid.moveColumns' ]);
var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.saveState', 'ui.grid.selection', 'ui.grid.cellNav', 'ui.grid.resizeColumns', 'ui.grid.moveColumns', 'ui.grid.pinning' ]);

app.controller('MainCtrl', ['$scope', '$http', '$interval', function ($scope, $http, $interval) {
$scope.gridOptions = {
saveFocus: false,
saveScroll: true,
enableFiltering: true,
onRegisterApi: function(gridApi){
$scope.gridApi = gridApi;
}
};
$scope.gridOptions.enableFiltering = true;
$scope.state = {};

$scope.saveState = function() {
Expand All @@ -68,7 +69,7 @@ to something different, and use the restore button to set the grid back the way

<file name="index.html">
<div ng-controller="MainCtrl">
<div id="grid1" ui-grid="gridOptions" ui-grid-save-state ui-grid-selection ui-grid-cellNav ui-grid-resize-columns ui-grid-move-columns class="grid"></div>
<div id="grid1" ui-grid="gridOptions" ui-grid-save-state ui-grid-selection ui-grid-cellNav ui-grid-resize-columns ui-grid-move-columns ui-grid-pinning class="grid"></div>
<button id="save" type="button" class="btn btn-success" ng-click="saveState()">Save</button>
<button id="restore" type="button" class="btn btn-success" ng-click="restoreState()">Restore</button>
</div>
Expand All @@ -80,6 +81,7 @@ to something different, and use the restore button to set the grid back the way
height: 400px;
}
</file>

<file name="scenario.js">
var gridTestUtils = require('../../test/e2e/gridTestUtils.spec.js');
describe( '208 save state', function() {
Expand Down
100 changes: 86 additions & 14 deletions src/features/pinning/js/pinning.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,70 @@

var module = angular.module('ui.grid.pinning', ['ui.grid']);

module.service('uiGridPinningService', ['gridUtil', 'GridRenderContainer', 'i18nService', function (gridUtil, GridRenderContainer, i18nService) {
module.constant('uiGridPinningConstants', {
container: {
LEFT: 'left',
RIGHT: 'right',
NONE: ''
}
});

module.service('uiGridPinningService', ['gridUtil', 'GridRenderContainer', 'i18nService', 'uiGridPinningConstants', function (gridUtil, GridRenderContainer, i18nService, uiGridPinningConstants) {
var service = {

initializeGrid: function (grid) {
service.defaultGridOptions(grid.options);

// Register a column builder to add new menu items for pinning left and right
grid.registerColumnBuilder(service.pinningColumnBuilder);

/**
* @ngdoc object
* @name ui.grid.pinning.api:PublicApi
*
* @description Public Api for pinning feature
*/
var publicApi = {
events: {
pinning: {
/**
* @ngdoc event
* @name columnPin
* @eventOf ui.grid.pinning.api:PublicApi
* @description raised when column pin state has changed
* <pre>
* gridApi.pinning.on.columnPinned(scope, function(colDef){})
* </pre>
* @param {object} colDef the column that was changed
* @param {string} container the render container the column is in ('left', 'right', '')
*/
columnPinned: function(colDef, container) {
}
}
},
methods: {
pinning: {
/**
* @ngdoc function
* @name pinColumn
* @methodOf ui.grid.pinning.api:PublicApi
* @description pin column left, right, or none
* <pre>
* gridApi.pinning.pinColumn(col, uiGridPinningConstants.container.LEFT)
* </pre>
* @param {gridColumn} col the column being pinned
* @param {string} container one of the recognised types
* from uiGridPinningConstants
*/
pinColumn: function(col, container) {
service.pinColumn(grid, col, container);
}
}
}
};

grid.api.registerEventsFromObject(publicApi.events);
grid.api.registerMethodsFromObject(publicApi.methods);
},

defaultGridOptions: function (gridOptions) {
Expand Down Expand Up @@ -124,11 +180,7 @@
return typeof(this.context.col.renderContainer) === 'undefined' || !this.context.col.renderContainer || this.context.col.renderContainer !== 'left';
},
action: function () {
this.context.col.renderContainer = 'left';
this.context.col.width = this.context.col.drawnWidth;
this.context.col.grid.createLeftContainer();

col.grid.refresh();
service.pinColumn(this.context.col.grid, this.context.col, uiGridPinningConstants.container.LEFT);
}
};

Expand All @@ -140,11 +192,7 @@
return typeof(this.context.col.renderContainer) === 'undefined' || !this.context.col.renderContainer || this.context.col.renderContainer !== 'right';
},
action: function () {
this.context.col.renderContainer = 'right';
this.context.col.width = this.context.col.drawnWidth;
this.context.col.grid.createRightContainer();

col.grid.refresh();
service.pinColumn(this.context.col.grid, this.context.col, uiGridPinningConstants.container.RIGHT);
}
};

Expand All @@ -156,9 +204,7 @@
return typeof(this.context.col.renderContainer) !== 'undefined' && this.context.col.renderContainer !== null && this.context.col.renderContainer !== 'body';
},
action: function () {
this.context.col.renderContainer = null;

col.grid.refresh();
service.pinColumn(this.context.col.grid, this.context.col, uiGridPinningConstants.container.UNPIN);
}
};

Expand All @@ -171,6 +217,32 @@
if (!gridUtil.arrayContainsObjectWithProperty(col.menuItems, 'name', 'ui.grid.pinning.unpin')) {
col.menuItems.push(removePinAction);
}
},

pinColumn: function(grid, col, container) {
if (container === uiGridPinningConstants.container.NONE) {
col.renderContainer = null;
}
else {
col.renderContainer = container;
col.width = col.drawnWidth;
if (container === uiGridPinningConstants.container.LEFT) {
grid.createLeftContainer();
}
else if (container === uiGridPinningConstants.container.RIGHT) {
grid.createRightContainer();
}
}

// Need to call refresh twice; once to move our column over to the new render container and then
// a second time to update the grid viewport dimensions with our adjustments
grid.refresh()
.then(function () {
grid.refresh()
.then(function() {
grid.api.pinning.raise.columnPinned( col.colDef, container );
});
});
}
};

Expand Down
73 changes: 72 additions & 1 deletion src/features/pinning/test/uiGridPinningService.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
/* global _ */
describe('ui.grid.pinning uiGridPinningService', function () {
var uiGridPinningService;
var uiGridPinningConstants;
var gridClassFactory;
var grid;
var GridRenderContainer;

beforeEach(module('ui.grid.pinning'));

beforeEach(inject(function (_uiGridPinningService_,_gridClassFactory_, $templateCache, _GridRenderContainer_) {
beforeEach(inject(function (_uiGridPinningService_,_gridClassFactory_, $templateCache, _GridRenderContainer_, _uiGridPinningConstants_) {
uiGridPinningService = _uiGridPinningService_;
uiGridPinningConstants = _uiGridPinningConstants_;
gridClassFactory = _gridClassFactory_;
GridRenderContainer = _GridRenderContainer_;

Expand Down Expand Up @@ -131,4 +133,73 @@ describe('ui.grid.pinning uiGridPinningService', function () {

});

describe('pinColumn', function() {

var previousWidth;

beforeEach(function() {
spyOn(grid, 'createLeftContainer').andCallThrough();
spyOn(grid, 'createRightContainer').andCallThrough();
previousWidth = grid.columns[0].drawnWidth;
});

describe('left', function() {

beforeEach(function() {
grid.api.pinning.pinColumn(grid.columns[0], uiGridPinningConstants.container.LEFT);
});

it('should set renderContainer to be left', function(){
expect(grid.columns[0].renderContainer).toEqual('left');
});

it('should call createLeftContainer', function() {
expect(grid.createLeftContainer).toHaveBeenCalled();
});

it('should set width based on previous setting', function() {
expect(grid.width).toEqual(previousWidth);
});

});

describe('right', function() {

beforeEach(function() {
grid.api.pinning.pinColumn(grid.columns[0], uiGridPinningConstants.container.RIGHT);
});

it('should set renderContainer to be right', function(){
expect(grid.columns[0].renderContainer).toEqual('right');
});

it('should call createLeftContainer', function() {
expect(grid.createRightContainer).toHaveBeenCalled();
});

it('should set width based on previous setting', function() {
expect(grid.width).toEqual(previousWidth);
});

});

describe('none', function() {

beforeEach(function() {
grid.api.pinning.pinColumn(grid.columns[0], uiGridPinningConstants.container.NONE);
});

it('should set renderContainer to be null', function(){
expect(grid.columns[0].renderContainer).toBeNull();
});

it('should NOT call either container creation methods', function() {
expect(grid.createLeftContainer).not.toHaveBeenCalled();
expect(grid.createRightContainer).not.toHaveBeenCalled();
});

});

});

});
Loading

0 comments on commit b0d943a

Please sign in to comment.