Open joshlongerbeam opened 8 years ago
It sounds like you want to save the current grid and be able to load that later? I think @j--w is working on that.
Yup! That's exactly what I'm doing. I almost have it working too: I decided to modify the size attributes instead of css widths, and apparently scope.$watch('ui.layout.resize'
and scope.$on('ui.layout.resize'
trigger at different times.
@SomeKittens , I wasn't working on persisting the sizes, just caching them during the session as per #100 which @petrsimon ended up resolving with his PR I believe. I think a localstorage layer could be built on top of his work if we wanted to persist the cached sizes.
Here's the directive I've made. (can't link to file, in a private repo). Notes: It's only meant to handle widths between vertical splitters, and the localStorageService basically just interacts with local storage.
At the very least, I hope this helps show how much work-around is needed to manually employ such an enhancement.
angular.module('core').directive('saveSplit', ['localStorageService', '$timeout',
function(localStorageService, $timeout) {
return {
link: function(scope, element, attrs) {
var widths = []; // widths from localStorage (possibly in percent from old splitters)
var minWidths = []; // minimum widths (in px) of each panel
var containers = []; // jquery references to panes between splitters
var inited = false;
function updateWidths() {
if(inited) {
widths = [];
containers.forEach(function(container) {
widths.push(parseInt(container.css('width'), 10));
});
localStorageService.set(attrs.saveSplit, widths);
}
setWidths(); //apply changes to html size attributes
}
function setWidths() {
if (!containers.length)
findPanes();
if(!minWidths.length) {
var temp;
element.children('div[ui-layout-container]').each(function(){
temp = $(this).attr('min-size');
temp = temp ? temp : 0; //incase no min-size given, .attr() returns undefined
minWidths.push(parseInt(temp, 10));
});
}
if(!widths.length)
widths = localStorageService.get(attrs.saveSplit);
widths.forEach(function(width, index){
if(width && width >= minWidths[index])
containers[index].attr('size', width+'px');
});
inited = true;
}
function findPanes() {
element.children('div[ui-layout-container]').each(function(){
containers.push($(this));
});
}
scope.$watch('ui.layout.resize', function(){
setWidths();
});
scope.$on('ui.layout.resize', function(){
updateWidths();
});
}
};
}
]);
Corresponding HTML:
<div ui-layout="{flow : 'column', disableToggle:true}" save-split="driveSplitter">
<div ui-layout-container[s]></div>
</div>
@j--w ah, understood. Wouldn't be too hard to add in a persistent dealio.
@joshterainsights We'd love a PR! Would you mind adding to core? If not, that's ok, it'll just be up to the maintainer's schedules.
Can I ask why do you want to store splitbar positions and not container size instead? Conceptually, I think, the container is what we care about, splitbar position is secondary.
In my view, what we need is to serialize container sizes and their collapsed state.
The collapsed state is easy, see the updated README in master branch.
Serializing container sizes should be relatively easy to add. Each layout stores it's child containers in the container
property. And each container stores uncollapsedSize
property (which should be undefined
for auto
sized containers).
So mapping over all layouts and containers will give you all their sizes, which you can store and later reuse. The size of auto-sized containers should not be stored.
There's also the size
property of containers, which is the actual size and all containers should have it defined and it should be 0
for collapsed containers. When split bar is dragged, the uncollapsedSize
is set (i.e. container is no longer an auto-sized container, except for "central" containers, see README).
The ui.layout.loaded
event should fire after all sizes have been calculated and containers collapsed. So if you are seeing left:0px
you either have collapsed container to the left of the splitbar or you are using flow: 'row'
or there is something wrong.
@petrsimon It's not so much that I care about splitbar positions, it's that that was the solution I saw that solved it. But you're right: the container-widths are the more important aspect. Currently, I actually set them to percentage widths.
Current project doesn't care about collapsed state since it's always disabled.
The directive I copy-pasted roughly uses the properties you described, and it's just to get the particular job done.
I have no idea what was happening with left:0px
, as collapse is never enabled anywhere in the project.
@SomeKittens I'm currently bogged down with graduating from college and impending laser eye surgery, but I'd love to do a pull request in a month or so! I'll try to make it generic enough to handle heights/widths and collapsed states.
I'm attaching my own directive to the
ui-layout
element that writes the current position of theui-splitbar
elements to local storage (specifically theirstyle="left:..."
property). But I'm having problems getting this directive to overwrite the splitbars' css values at the proper time when loading the page (it always starts-with/is-overwritten-by whatever I've specified inui-layout-container size="..."
).ui.layout.loaded
fires, the splitbars all haveleft:0px;
ui.layout.resize
only fires when the user resizes, not when ui-layout moves them from their starting0px;
.loaded(fn)
and.on('loaded', fn)
methods refuse to work/triggerui.layout.loaded
doesIf I'm clearly using something not as intended (e.g., I should be pointing the directive at the sizes attr instead of css values or jquery should be working but I'm new to it), tell me and close the issue.
If this is a feature that would be useful for this or other reasons, tag it as enhancement.