mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-07-28 11:49:13 -04:00
Merge pull request #2702 from alphagov/fix-bugs-with-sticky-overflow-code
Fix bugs with sticky overflow code
This commit is contained in:
@@ -140,7 +140,16 @@
|
||||
// Object collecting together methods for treating sticky elements as if they
|
||||
// were wrapped by a dialog component
|
||||
var dialog = {
|
||||
_hasResized: false,
|
||||
hasResized: false,
|
||||
// we add padding of 20px around each sticky to isolate it from the rest of the page
|
||||
// it shouldn't apply between stickys when stacked
|
||||
_getPaddingBetweenEls: function (els) {
|
||||
var spaceBetween = 40;
|
||||
|
||||
if (els.length < 2) { return 0; }
|
||||
|
||||
return (els.length - 1) * spaceBetween;
|
||||
},
|
||||
_getTotalHeight: function (els) {
|
||||
var reducer = function (accumulator, currentValue) {
|
||||
return accumulator + currentValue;
|
||||
@@ -152,6 +161,7 @@
|
||||
},
|
||||
getOffsetFromEdge: function (el, sticky) {
|
||||
var els = this._elsThatCanBeStuck(sticky._els).slice();
|
||||
var elsBetween;
|
||||
var elIdx;
|
||||
|
||||
// els must be arranged furtherest from window edge is stuck to first
|
||||
@@ -165,10 +175,12 @@
|
||||
// if next to window edge the dialog is stuck to, no offset
|
||||
if (elIdx === (els.length - 1)) { return 0; }
|
||||
|
||||
// make els all those from this one to the window edge
|
||||
els = els.slice(elIdx);
|
||||
// get all els between this one and the window edge
|
||||
els = els.slice(elIdx + 1);
|
||||
elsBetween = els.slice(1);
|
||||
|
||||
return this._getTotalHeight(els);
|
||||
return this._getTotalHeight(elsBetween) - this._getPaddingBetweenEls(els);
|
||||
},
|
||||
getOffsetFromEnd: function (el, sticky) {
|
||||
var els = this._elsThatCanBeStuck(sticky._els).slice();
|
||||
@@ -218,10 +230,8 @@
|
||||
sticky.reset(currentEl);
|
||||
currentEl.canBeStuck(false);
|
||||
|
||||
if (!sticky._hasResized) { sticky._hasResized = true; }
|
||||
if (!self.hasResized) { self.hasResized = true; }
|
||||
}
|
||||
|
||||
return this._getTotalHeight(els);
|
||||
},
|
||||
getElementAtStickyEdge: function (sticky) {
|
||||
var els = this._elsThatCanBeStuck(sticky._els);
|
||||
@@ -251,7 +261,7 @@
|
||||
$(window).scrollTop(this.getInPageEdgePosition(sticky) - windowHeight);
|
||||
}
|
||||
|
||||
sticky._hasResized = false;
|
||||
self.hasResized = false;
|
||||
},
|
||||
releaseEl: function (el, sticky) {
|
||||
el.$fixedEl.css(sticky.edge, '');
|
||||
@@ -263,7 +273,7 @@
|
||||
var Sticky = function (selector) {
|
||||
this._hasScrolled = false;
|
||||
this._scrollTimeout = false;
|
||||
this._hasResized = false;
|
||||
this._windowHasResized = false;
|
||||
this._resizeTimeout = false;
|
||||
this._elsLoaded = false;
|
||||
this._initialPositionsSet = false;
|
||||
@@ -272,6 +282,9 @@
|
||||
this.CSS_SELECTOR = selector;
|
||||
this.STOP_PADDING = 10;
|
||||
};
|
||||
Sticky.prototype.setMode = function (mode) {
|
||||
_mode = mode;
|
||||
};
|
||||
Sticky.prototype.getWindowDimensions = function () {
|
||||
return {
|
||||
height: $(global).height(),
|
||||
@@ -360,19 +373,19 @@
|
||||
}
|
||||
};
|
||||
// Recalculate stored dimensions for all sticky elements
|
||||
Sticky.prototype.recalculate = function (opts) {
|
||||
Sticky.prototype.recalculate = function () {
|
||||
var self = this;
|
||||
var onSyncComplete = function () {
|
||||
self.setEvents();
|
||||
if (_mode === 'dialog') {
|
||||
dialog.fitToHeight(self);
|
||||
dialog.adjustForResize(self);
|
||||
if (dialog.hasResized) {
|
||||
dialog.adjustForResize(self);
|
||||
}
|
||||
}
|
||||
self.setElementPositions();
|
||||
};
|
||||
|
||||
if ((opts !== undefined) && ('mode' in opts)) { _mode = opts.mode; }
|
||||
|
||||
this.syncWithDOM(onSyncComplete);
|
||||
};
|
||||
Sticky.prototype.setElWidth = function (el) {
|
||||
@@ -413,30 +426,38 @@
|
||||
Sticky.prototype.allElementsLoaded = function (totalEls) {
|
||||
return this._els.length === totalEls;
|
||||
};
|
||||
Sticky.prototype.hasEl = function (node) {
|
||||
return !!$.grep(this._els, function (el) { return el.$fixedEl.is(node); }).length;
|
||||
Sticky.prototype.getElForNode = function (node) {
|
||||
var matches = $.grep(this._els, function (el) { return el.$fixedEl.is(node); });
|
||||
|
||||
return !!matches.length ? matches[0] : false;
|
||||
};
|
||||
Sticky.prototype.add = function (el, setPositions, cb) {
|
||||
var self = this;
|
||||
var $el = $(el);
|
||||
var onDimensionsSet;
|
||||
var elObj;
|
||||
|
||||
// guard against adding elements already stored
|
||||
if (this.hasEl(el)) { return; }
|
||||
var elObj = this.getElForNode(el);
|
||||
var exists = !!elObj;
|
||||
|
||||
onDimensionsSet = function () {
|
||||
elObj.hasLoaded(true);
|
||||
self._els.push(elObj);
|
||||
|
||||
// guard against adding elements already stored
|
||||
if (!exists) {
|
||||
self._els.push(elObj);
|
||||
}
|
||||
|
||||
if (setPositions) {
|
||||
self.setElementPositions();
|
||||
}
|
||||
|
||||
if (cb !== undefined) {
|
||||
cb();
|
||||
}
|
||||
};
|
||||
|
||||
elObj = new StickyElement($el, self);
|
||||
if (!exists) {
|
||||
elObj = new StickyElement($el, self);
|
||||
}
|
||||
|
||||
self.setElementDimensions(elObj, onDimensionsSet);
|
||||
};
|
||||
@@ -485,8 +506,8 @@
|
||||
});
|
||||
}
|
||||
};
|
||||
Sticky.prototype.init = function (opts) {
|
||||
this.recalculate(opts);
|
||||
Sticky.prototype.init = function () {
|
||||
this.recalculate();
|
||||
};
|
||||
Sticky.prototype.setEvents = function () {
|
||||
var self = this;
|
||||
@@ -511,7 +532,7 @@
|
||||
this._hasScrolled = true;
|
||||
};
|
||||
Sticky.prototype.onResize = function () {
|
||||
this._hasResized = true;
|
||||
this._windowHasResized = true;
|
||||
};
|
||||
Sticky.prototype.checkScroll = function () {
|
||||
var self = this;
|
||||
@@ -525,8 +546,8 @@
|
||||
var self = this,
|
||||
windowWidth = self.getWindowDimensions().width;
|
||||
|
||||
if (self._hasResized === true) {
|
||||
self._hasResized = false;
|
||||
if (self._windowHasResized === true) {
|
||||
self._windowHasResized = false;
|
||||
|
||||
$.each(self._els, function (i, el) {
|
||||
if (!self.viewportIsWideEnough(windowWidth)) {
|
||||
@@ -539,7 +560,9 @@
|
||||
if (self.viewportIsWideEnough(windowWidth)) {
|
||||
if (_mode === 'dialog') {
|
||||
dialog.fitToHeight(self);
|
||||
dialog.adjustForResize(self);
|
||||
if (dialog.hasResized) {
|
||||
dialog.adjustForResize(self);
|
||||
}
|
||||
}
|
||||
self.setElementPositions();
|
||||
}
|
||||
|
||||
@@ -139,14 +139,20 @@
|
||||
};
|
||||
|
||||
this.render = function() {
|
||||
var mode = 'default';
|
||||
|
||||
// detach everything, unless they are the currentState
|
||||
this.states.forEach(
|
||||
state => (state.key === this.currentState ? this.$stickyBottom.append(state.$el) : state.$el.detach())
|
||||
);
|
||||
|
||||
// make sticky JS recalculate its cache of the element's position
|
||||
// use dialog mode for states which contain more than one form control
|
||||
GOVUK.stickAtBottomWhenScrolling.recalculate({ 'mode': 'dialog' });
|
||||
if (['move-to-existing-folder', 'add-new-template'].includes(this.currentState)) {
|
||||
mode = 'dialog';
|
||||
}
|
||||
GOVUK.stickAtBottomWhenScrolling.setMode(mode);
|
||||
// make sticky JS recalculate its cache of the element's position
|
||||
GOVUK.stickAtBottomWhenScrolling.recalculate();
|
||||
};
|
||||
|
||||
this.nothingSelectedButtons = $(`
|
||||
|
||||
@@ -46,6 +46,10 @@
|
||||
padding: $vertical-padding 0 $vertical-padding $gutter-half;
|
||||
margin-top: -$vertical-padding;
|
||||
|
||||
& + .js-stick-at-bottom-when-scrolling {
|
||||
margin-top: ($vertical-padding * 2) * -1;
|
||||
}
|
||||
|
||||
.page-footer {
|
||||
margin-bottom: 0;
|
||||
min-height: 50px;
|
||||
|
||||
Reference in New Issue
Block a user