diff --git a/app/assets/javascripts/stick-to-window-when-scrolling.js b/app/assets/javascripts/stick-to-window-when-scrolling.js index c7296d12d..63914fce0 100644 --- a/app/assets/javascripts/stick-to-window-when-scrolling.js +++ b/app/assets/javascripts/stick-to-window-when-scrolling.js @@ -3,6 +3,42 @@ var $ = global.jQuery; var GOVUK = global.GOVUK || {}; + var _mode = 'default'; + + // Object collecting together methods for dealing with marking the edge of a sticky, or group of + // sticky elements (as seen in dialog mode) + var oppositeEdge = { + _classes: { + 'top': 'content-fixed__top', + 'bottom': 'content-fixed__bottom' + }, + _getClassForEdge: function (edge) { + return this._classes[edge]; + }, + mark: function (sticky) { + var edgeClass = this._getClassForEdge(sticky.edge); + var els; + + if (_mode === 'dialog') { + els = [dialog.getElementAtOppositeEnd(sticky)]; + } else { + els = sticky._els; + } + + els = $.grep(els, function (el) { return el.isStuck(); }); + + $.each(els, function (i, el) { + el.$fixedEl.addClass(edgeClass); + }); + }, + unmark: function (sticky) { + var edgeClass = this._getClassForEdge(sticky.edge); + + $.each(sticky._els, function (i, el) { + el.$fixedEl.removeClass(edgeClass); + }); + } + }; // Constructor for objects holding data for each element to have sticky behaviour var StickyElement = function ($el, sticky) { @@ -13,6 +49,20 @@ this._appliedClass = null; this._$shim = null; this._stopped = false; + this._hasLoaded = false; + this._canBeStuck = true; + this.verticalMargins = { + 'top': parseInt(this.$fixedEl.css('margin-top'), 10), + 'bottom': parseInt(this.$fixedEl.css('margin-bottom'), 10), + }; + }; + StickyElement.prototype._getShimCSS = function () { + return { + 'width': this.horizontalSpace + 'px', + 'height': this.height + 'px', + 'margin-top': this.verticalMargins.top + 'px', + 'margin-bottom': this.verticalMargins.bottom + 'px' + }; }; StickyElement.prototype.stickyClass = function () { return (this._sticky._initialPositionsSet) ? this._fixedClass : this._initialFixedClass; @@ -20,44 +70,192 @@ StickyElement.prototype.appliedClass = function () { return this._appliedClass; }; + StickyElement.prototype.removeStickyClasses = function (sticky) { + this.$fixedEl.removeClass([ + this._initialFixedClass, + this._fixedClass + ].join(' ')); + }; StickyElement.prototype.isStuck = function () { return this._appliedClass !== null; }; - StickyElement.prototype.stick = function () { + StickyElement.prototype.stick = function (sticky) { this._appliedClass = this.stickyClass(); + this.$fixedEl.addClass(this._appliedClass); this._hasBeenCalled = true; }; - StickyElement.prototype.release = function () { + StickyElement.prototype.release = function (sticky) { this._appliedClass = null; + this.removeStickyClasses(sticky); this._hasBeenCalled = true; }; // When a sticky element is moved into the 'stuck' state, a shim is inserted into the // page to preserve the space the element occupies in the flow. StickyElement.prototype.addShim = function (position) { - this._$shim = $('
 
'); + this._$shim = $('
 
'); + this._$shim.css(this._getShimCSS()); this.$fixedEl[position](this._$shim); }; StickyElement.prototype.removeShim = function () { - this._$shim.remove(); - this._$shim = null; + if (this._$shim !== null) { + this._$shim.remove(); + this._$shim = null; + } }; // Changes to the dimensions of a sticky element with a shim need to be passed on to the shim StickyElement.prototype.updateShim = function () { if (this._$shim) { - this._$shim.css({ - 'height': this.verticalSpace, - 'width': this.horizontalSpace - }); + this._$shim.css(this._getShimCSS()); } }; StickyElement.prototype.stop = function () { - this._isStopped = true; + this._stopped = true; }; StickyElement.prototype.unstop = function () { - this._isStopped = false; + this._stopped = false; }; StickyElement.prototype.isStopped = function () { - return this._isStopped; + return this._stopped; + }; + StickyElement.prototype.isInPage = function () { + var node = this.$fixedEl.get(0); + + return (node === document.body) ? false : document.body.contains(node); + }; + StickyElement.prototype.canBeStuck = function (val) { + if (val !== undefined) { + this._canBeStuck = val; + } else { + return this._canBeStuck; + } + }; + StickyElement.prototype.hasLoaded = function (val) { + if (val !== undefined) { + this._hasLoaded = val; + } else { + return this._hasLoaded; + } + }; + + // Object collecting together methods for treating sticky elements as if they + // were wrapped by a dialog component + var dialog = { + _hasResized: false, + _getTotalHeight: function (els) { + var reducer = function (accumulator, currentValue) { + return accumulator + currentValue; + }; + return $.map(els, function (el) { return el.height; }).reduce(reducer); + }, + _elsThatCanBeStuck: function (els) { + return $.grep(els, function (el) { return el.canBeStuck(); }); + }, + getOffsetFromEdge: function (el, sticky) { + var els = this._elsThatCanBeStuck(sticky._els).slice(); + var elIdx; + + // els must be arranged furtherest from window edge is stuck to first + // default direction is order in document + if (sticky.edge === 'top') { + els.reverse(); + } + + elIdx = els.indexOf(el); + + // if next to window edge the dialog is stuck to, no offset + if (elIdx === (els.length - 1)) { return 0; } + + // get all els between this one and the window edge + els = els.slice(elIdx + 1); + + return this._getTotalHeight(els); + }, + getOffsetFromEnd: function (el, sticky) { + var els = this._elsThatCanBeStuck(sticky._els).slice(); + var elIdx; + + // els must be arranged furtherest from window edge is stuck to first + // default direction is order in document + if (sticky.edge === 'bottom') { + els.reverse(); + } + + elIdx = els.indexOf(el); + + // if next to opposite edge to the one the dialog is stuck to, no offset + if (elIdx === (els.length - 1)) { return 0; } + + // get all els between this one and the opposite edge + els = els.slice(elIdx + 1); + + return this._getTotalHeight(els); + }, + // checks total height of all this._sticky elements against a height + // unsticks each that won't fit and marks them as unstickable + fitToHeight: function (sticky) { + var self = this; + var els = sticky._els.slice(); + var height = sticky.getWindowDimensions().height; + var totalStickyHeight = function () { + return self._getTotalHeight(self._elsThatCanBeStuck(els)); + }; + var dialogFitsHeight = function () { + return totalStickyHeight() <= height; + }; + + // els must be arranged furtherest from window edge is stuck to first + // default direction is order in document + if (sticky.edge === 'top') { + els.reverse(); + } + + // reset elements + $.each(els, function (i, el) { el.canBeStuck(true); }); + + while (self._elsThatCanBeStuck(els).length && !dialogFitsHeight()) { + var currentEl = self._elsThatCanBeStuck(els)[0]; + + sticky.reset(currentEl); + currentEl.canBeStuck(false); + + if (!sticky._hasResized) { sticky._hasResized = true; } + } + + return this._getTotalHeight(els); + }, + getElementAtStickyEdge: function (sticky) { + var els = this._elsThatCanBeStuck(sticky._els); + var idx = (sticky.edge === 'top') ? 0 : els.length - 1; + + return els[idx]; + }, + // get element at the end opposite the sticky edge + getElementAtOppositeEnd: function (sticky) { + var els = this._elsThatCanBeStuck(sticky._els); + var idx = (sticky.edge === 'top') ? els.length - 1 : 0; + + return els[idx]; + }, + getInPageEdgePosition: function (sticky) { + return this.getElementAtStickyEdge(sticky).inPageEdgePosition; + }, + getHeight: function (els) { + return this._getTotalHeight(this._elsThatCanBeStuck(els)); + }, + adjustForResize: function (sticky) { + var windowHeight = sticky.getWindowDimensions().height; + + if (sticky.edge === 'top') { + $(window).scrollTop(this.getInPageEdgePosition(sticky)); + } else { + $(window).scrollTop(this.getInPageEdgePosition(sticky) - windowHeight); + } + + sticky._hasResized = false; + }, + releaseEl: function (el, sticky) { + el.$fixedEl.css(sticky.edge, ''); + } }; // Constructor for objects collecting together all generic behaviour for controlling the state of @@ -72,6 +270,7 @@ this._els = []; this.CSS_SELECTOR = selector; + this.STOP_PADDING = 10; }; Sticky.prototype.getWindowDimensions = function () { return { @@ -86,26 +285,30 @@ }; // Change state of sticky elements based on their position relative to the window Sticky.prototype.setElementPositions = function () { - var self = this; - - $.each(self._els, function (i, el) { - var $el = el.$fixedEl, - windowDimensions = self.getWindowDimensions(); + var self = this, + windowDimensions = self.getWindowDimensions(), + windowTop = self.getWindowPositions().scrollTop, + windowPositions = { + 'top': windowTop, + 'bottom': windowTop + windowDimensions.height + }; + var _setElementPosition = function (el) { if (self.viewportIsWideEnough(windowDimensions.width)) { - if (self.windowNotPastScrolledFrom(el.scrolledFrom)) { - self.release(el); - } else { - if (self.windowNotPastScrolledTo(el, windowDimensions.height)) { + if (self.windowNotPastScrolledFrom(windowPositions, self.getScrolledFrom(el))) { + self.reset(el); + } else { // past the point it sits in the document + if (self.windowNotPastScrollingTo(windowPositions, self.getScrollingTo(el))) { self.stick(el); if (el.isStopped()) { self.unstop(el); } - } else { // window past scrolledTo position - if (!el.isStopped()) { - self.stop(el); + } else { // window past scrollingTo position + if (!el.isStuck()) { + self.stick(el); } + self.stop(el); } } @@ -114,8 +317,20 @@ self.reset(el); } + }; + + // clean up any existing styles marking the edges of sticky elements + oppositeEdge.unmark(self); + + $.each(self._els, function (i, el) { + if (el.canBeStuck()) { + _setElementPosition(el); + } }); + // add styles to mark the edge of sticky elements opposite to that stuck to the window + oppositeEdge.mark(self); + if (self._initialPositionsSet === false) { self._initialPositionsSet = true; } }; // Store all the dimensions for a sticky element to limit DOM queries @@ -123,13 +338,10 @@ var self = this; var $el = el.$fixedEl; var onHeightSet = function () { - el.scrolledTo = self.getScrollingTo(el); // if element is shim'ed, pass changes in dimension on to the shim if (el._$shim) { el.updateShim(); - $el = el._$shim; } - el.scrolledFrom = self.getScrolledFrom($el); if (callback !== undefined) { callback(); } @@ -140,21 +352,28 @@ }; // Reset element to original state in the page Sticky.prototype.reset = function (el) { - if (el.isStuck()) { - this.release(el); - } if (el.isStopped()) { this.unstop(el); } + if (el.isStuck()) { + this.release(el); + } }; // Recalculate stored dimensions for all sticky elements - Sticky.prototype.recalculate = function () { + Sticky.prototype.recalculate = function (opts) { var self = this; + var onSyncComplete = function () { + self.setEvents(); + if (_mode === 'dialog') { + dialog.fitToHeight(self); + dialog.adjustForResize(self); + } + self.setElementPositions(); + }; - $.each(self._els, function (i, el) { - self.setElementDimensions(el); - }); - self.setElementPositions(); + if ((opts !== undefined) && ('mode' in opts)) { _mode = opts.mode; } + + this.syncWithDOM(onSyncComplete); }; Sticky.prototype.setElWidth = function (el) { var $el = el.$fixedEl; @@ -170,56 +389,119 @@ var self = this; var $el = el.$fixedEl; var $img = $el.find('img'); + var onload = function () { + el.height = $el.outerHeight(); + // if element has a shim, the shim's offset represents the element's in-page position + if (el._$shim) { + el.inPageEdgePosition = self.getInPageEdgePosition(el._$shim); + } else { + el.inPageEdgePosition = self.getInPageEdgePosition($el); + } + callback(); + }; - if ((!self._elsLoaded) && ($img.length > 0)) { + if ((!el.hasLoaded()) && ($img.length > 0)) { var image = new global.Image(); image.onload = function () { - el.verticalSpace = $el.outerHeight(true); - el.height = $el.outerHeight(); - callback(); + onload(); }; image.src = $img.attr('src'); } else { - el.verticalSpace = $el.outerHeight(true); - el.height = $el.outerHeight(); - callback(); + onload(); } }; Sticky.prototype.allElementsLoaded = function (totalEls) { return this._els.length === totalEls; }; - Sticky.prototype.init = function () { + Sticky.prototype.hasEl = function (node) { + return !!$.grep(this._els, function (el) { return el.$fixedEl.is(node); }).length; + }; + 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; } + + onDimensionsSet = function () { + elObj.hasLoaded(true); + self._els.push(elObj); + if (setPositions) { + self.setElementPositions(); + } + if (cb !== undefined) { + cb(); + } + }; + + elObj = new StickyElement($el, self); + + self.setElementDimensions(elObj, onDimensionsSet); + }; + Sticky.prototype.remove = function (el) { + if ($.inArray(el, this._els) !== -1) { + + // reset DOM node to original state + this.reset(el); + + // remove sticky element object + this._els = $.grep(this._els, function (_el) { return _el !== el; }); + } + }; + // gets all sticky elements in the DOM and removes any in this._els no longer in attached to it + Sticky.prototype.syncWithDOM = function (callback) { var self = this; var $els = $(self.CSS_SELECTOR); var numOfEls = $els.length; + var onLoaded; - if (numOfEls > 0) { - $els.each(function (i, el) { - var $el = $(el); - var elObj = new StickyElement($el, self); + onLoaded = function () { + if (self._els.length === numOfEls) { + self.endOfScrollArea = self.getEndOfScrollArea(); + if (callback !== undefined) { + callback(); + } + } + }; - self.setElementDimensions(elObj, function () { - self._els.push(elObj); - // set positions based on initial scroll positionu - if (self._els.length === numOfEls) { - self._elsLoaded = true; - self.setElementPositions(); - } - }); + // remove any els no longer in the DOM + if (this._els.length) { + $.each(this._els, function (i, el) { + if (!el.isInPage()) { + self.remove(el); + } }); + } - // flag when scrolling takes place and check (and re-position) sticky elements relative to - // window position - if (self._scrollTimeout === false) { - $(global).scroll(function (e) { self.onScroll(); }); - self._scrollTimeout = global.setInterval(function (e) { self.checkScroll(); }, 50); - } + if (numOfEls) { + // reset flag marking page load + this._initialPositionsSet = false; - // Recalculate all dimensions when the window resizes - if (self._resizeTimeout === false) { - $(global).resize(function (e) { self.onResize(); }); - self._resizeTimeout = global.setInterval(function (e) { self.checkResize(); }, 50); - } + $els.each(function (i, el) { + // delay setting position until all stickys are loaded + self.add(el, false, onLoaded); + }); + } + }; + Sticky.prototype.init = function (opts) { + this.recalculate(opts); + }; + Sticky.prototype.setEvents = function () { + var self = this; + + // flag when scrolling takes place and check (and re-position) sticky elements relative to + // window position + if (self._scrollTimeout === false) { + $(global).scroll(function (e) { self.onScroll(); }); + self._scrollTimeout = global.setInterval(function (e) { self.checkScroll(); }, 50); + } + + // Recalculate all dimensions when the window resizes + if (self._resizeTimeout === false) { + $(global).resize(function (e) { self.onResize(); }); + self._resizeTimeout = global.setInterval(function (e) { self.checkResize(); }, 50); } }; Sticky.prototype.viewportIsWideEnough = function (windowWidth) { @@ -236,7 +518,7 @@ if (self._hasScrolled === true) { self._hasScrolled = false; - self.setElementPositions(true); + self.setElementPositions(); } }; Sticky.prototype.checkResize = function () { @@ -255,6 +537,10 @@ }); if (self.viewportIsWideEnough(windowWidth)) { + if (_mode === 'dialog') { + dialog.fitToHeight(self); + dialog.adjustForResize(self); + } self.setElementPositions(); } } @@ -263,102 +549,182 @@ if (el.isStuck()) { var $el = el.$fixedEl; - $el.removeClass(el.appliedClass()).css('width', ''); + el.removeStickyClasses(this); + $el.css('width', ''); + if (_mode === 'dialog') { + dialog.releaseEl(el, this); + } el.removeShim(); - el.release(); + el.release(this); } }; // Extension of sticky object to add behaviours specific to sticking to top of window var stickAtTop = new Sticky('.js-stick-at-top-when-scrolling'); - // Store top of sticky elements while unstuck - stickAtTop.getScrolledFrom = function ($el) { - return $el.offset().top; - }; - // Store furthest point top of sticky element is allowed - stickAtTop.getScrollingTo = function (el) { + stickAtTop.edge = 'top'; + // Store furthest point sticky elements are allowed + stickAtTop.getEndOfScrollArea = function () { var footer = $('.js-footer:eq(0)'); if (footer.length === 0) { return 0; } - return (footer.offset().top - 10) - el.height; + return footer.offset().top - this.STOP_PADDING; }; - stickAtTop.windowNotPastScrolledFrom = function (scrolledFrom) { - var windowTop = this.getWindowPositions().scrollTop; + // position of the bottom edge when in the page flow + stickAtTop.getInPageEdgePosition = function ($el) { + return $el.offset().top; + }; + stickAtTop.getScrolledFrom = function (el) { + if (_mode === 'dialog') { + return dialog.getInPageEdgePosition(this); + } else { + return el.inPageEdgePosition; + } + }; + stickAtTop.getScrollingTo = function (el) { + var height = el.height; - return scrolledFrom > windowTop; + if (_mode === 'dialog') { + height = dialog.getHeight(this._els); + } + + return this.endOfScrollArea - height; }; - stickAtTop.windowNotPastScrolledTo = function (el, windowHeight) { - var windowTop = this.getWindowPositions().scrollTop; - - return windowTop < el.scrolledTo; + stickAtTop.getStoppingPosition = function (el) { + var offset = 0; + + if (_mode === 'dialog') { + offset = dialog.getOffsetFromEnd(el, this); + } + + return (this.endOfScrollArea - offset) - el.height; + }; + stickAtTop.windowNotPastScrolledFrom = function (windowPositions, scrolledFrom) { + return scrolledFrom > windowPositions.top; + }; + stickAtTop.windowNotPastScrollingTo = function (windowPositions, scrollingTo) { + return windowPositions.top < scrollingTo; }; stickAtTop.stick = function (el) { if (!el.isStuck()) { var $el = el.$fixedEl; + var offset = 0; + + if (_mode === 'dialog') { + offset = dialog.getOffsetFromEdge(el, this); + } el.addShim('before'); - // element will be absolutely positioned so cannot rely on parent element for width - $el.css('width', $el.width() + 'px').addClass(el.stickyClass()); - el.stick(); + $el.css({ + // element will be absolutely positioned so cannot rely on parent element for width + 'width': $el.width() + 'px', + 'top': offset + 'px' + }); + el.stick(this); } }; stickAtTop.stop = function (el) { - el.$fixedEl.css({ 'position': 'absolute', 'top': el.scrolledTo }); - el.stop(); + if (!el.isStopped()) { + el.$fixedEl.css({ + 'position': 'absolute', + 'top': this.getStoppingPosition(el) + }); + el.stop(); + } }; stickAtTop.unstop = function (el) { - el.$fixedEl.css({ 'position': '', 'top': '' }); + el.$fixedEl.css({ + 'position': '', + 'top': '' + }); el.unstop(); }; // Extension of sticky object to add behaviours specific to sticking to bottom of window var stickAtBottom = new Sticky('.js-stick-at-bottom-when-scrolling'); - // Store bottom of sticky elements while unstuck - stickAtBottom.getScrolledFrom = function ($el) { - return $el.offset().top + $el.outerHeight(); - }; - // Store furthest point bottom of sticky element is allowed - stickAtBottom.getScrollingTo = function (el) { + stickAtBottom.edge = 'bottom'; + // Store furthest point sticky elements are allowed + stickAtBottom.getEndOfScrollArea = function () { var header = $('.js-header:eq(0)'); if (header.length === 0) { return 0; } - return (header.offset().top + header.outerHeight() + 10) + el.height; + return (header.offset().top + header.outerHeight()) + this.STOP_PADDING; }; - stickAtBottom.windowNotPastScrolledFrom = function (scrolledFrom) { - var windowBottom = this.getWindowPositions().scrollTop + this.getWindowDimensions().height; - - return scrolledFrom < windowBottom; + // position of the bottom edge when in the page flow + stickAtBottom.getInPageEdgePosition = function ($el) { + return $el.offset().top + $el.outerHeight(); }; - stickAtBottom.windowNotPastScrolledTo = function (el, windowHeight) { - var windowBottom = this.getWindowPositions().scrollTop + this.getWindowDimensions().height; + stickAtBottom.getScrolledFrom = function (el) { + if (_mode === 'dialog') { + return dialog.getInPageEdgePosition(this); + } else { + return el.inPageEdgePosition; + } + }; + stickAtBottom.getScrollingTo = function (el) { + var height = el.height; - return windowBottom > el.scrolledTo; + if (_mode === 'dialog') { + height = dialog.getHeight(this._els); + } + + return this.endOfScrollArea + height; + }; + stickAtBottom.getStoppingPosition = function (el) { + var offset = 0; + + if (_mode === 'dialog') { + offset = dialog.getOffsetFromEnd(el, this); + } + + return this.endOfScrollArea + offset; + }; + stickAtBottom.windowNotPastScrolledFrom = function (windowPositions, scrolledFrom) { + return scrolledFrom < windowPositions.bottom; + }; + stickAtBottom.windowNotPastScrollingTo = function (windowPositions, scrollingTo) { + return windowPositions.bottom > scrollingTo; }; stickAtBottom.stick = function (el) { if (!el.isStuck()) { var $el = el.$fixedEl; + var offset = 0; + + if (_mode === 'dialog') { + offset = dialog.getOffsetFromEdge(el, this); + } el.addShim('after'); - // element will be absolutely positioned so cannot rely on parent element for width - el.$fixedEl.css('width', $el.width() + 'px').addClass(el.stickyClass()); - el.stick(); + $el.css({ + // element will be absolutely positioned so cannot rely on parent element for width + 'width': $el.width() + 'px', + 'bottom': offset + 'px' + }); + el.stick(this); } }; stickAtBottom.stop = function (el) { - el.$fixedEl.css({ - 'position': 'absolute', - 'top': (el.scrolledTo - el.height), - 'bottom': 'auto' - }); - el.stop(); + if (!el.isStopped()) { + el.$fixedEl.css({ + 'position': 'absolute', + 'top': this.getStoppingPosition(el), + 'bottom': 'auto' + }); + el.stop(); + } }; stickAtBottom.unstop = function (el) { + var offset = 0; + + if (_mode === 'dialog') { + offset = dialog.getOffsetFromEdge(el, this); + } + el.$fixedEl.css({ 'position': '', 'top': '', - 'bottom': '' + 'bottom': offset + 'px' }); el.unstop(); }; diff --git a/app/assets/javascripts/templateFolderForm.js b/app/assets/javascripts/templateFolderForm.js index 5f9079fbf..dcd91a5a1 100644 --- a/app/assets/javascripts/templateFolderForm.js +++ b/app/assets/javascripts/templateFolderForm.js @@ -29,6 +29,9 @@ this.states.filter(state => state.cancellable).forEach((x) => this.addCancelButton(x)); this.states.filter(state => state.key === 'items-selected-buttons').forEach(x => this.addClearButton(x)); + // activate stickiness of elements in each state + this.activateStickyElements(); + // first off show the new template / new folder buttons this.currentState = this.$form.data('prev-state') || 'unknown'; if (this.currentState === 'unknown') { @@ -41,6 +44,18 @@ this.$form.on('change', 'input[type=checkbox]', () => this.templateFolderCheckboxChanged()); }; + this.activateStickyElements = function() { + var oldClass = 'js-will-stick-at-bottom-when-scrolling'; + var newClass = 'js-stick-at-bottom-when-scrolling'; + + this.states.forEach(state => { + state.$el + .find('.' + oldClass) + .removeClass(oldClass) + .addClass(newClass); + }); + }; + this.addCancelButton = function(state) { let $cancel = this.makeButton('Cancel', () => { @@ -130,30 +145,33 @@ ); // make sticky JS recalculate its cache of the element's position - if ('stickAtBottomWhenScrolling' in GOVUK) { - GOVUK.stickAtBottomWhenScrolling.recalculate(); - } + // use dialog mode for states which contain more than one form control + GOVUK.stickAtBottomWhenScrolling.recalculate({ 'mode': 'dialog' }); }; - this.nothingSelectedButtons = ` + this.nothingSelectedButtons = $(`
- - -
- Nothing selected +
+ + +
+ Nothing selected +
- `; + `).get(0); - this.itemsSelectedButtons = ` + this.itemsSelectedButtons = $(`
- - -
- 1 selected +
+ + +
+ 1 selected +
- `; + `).get(0); }; })(window.GOVUK.Modules); diff --git a/app/assets/stylesheets/components/stick-at-top-when-scrolling.scss b/app/assets/stylesheets/components/stick-at-top-when-scrolling.scss index 062d900f7..9c5cea1f1 100644 --- a/app/assets/stylesheets/components/stick-at-top-when-scrolling.scss +++ b/app/assets/stylesheets/components/stick-at-top-when-scrolling.scss @@ -72,6 +72,7 @@ background: $white; z-index: 100; padding-right: $gutter-half; + margin-top: 0; .back-to-top-link { opacity: 1; @@ -85,6 +86,11 @@ top: 0; margin-top: 0; + +} + +.js-stick-at-top-when-scrolling.content-fixed__top { + border-bottom: 1px solid $border-colour; box-shadow: 0 2px 0 0 rgba($border-colour, 0.2); @@ -101,6 +107,11 @@ top: auto; // cancel `top: 0;` inherited from govuk-template bottom: 0; + +} + +.js-stick-at-bottom-when-scrolling.content-fixed__bottom { + border-top: 1px solid $border-colour; box-shadow: 0 -2px 0 0 rgba($border-colour, 0.2); diff --git a/app/templates/components/live-search.html b/app/templates/components/live-search.html index bbc31f675..6c7b1fad8 100644 --- a/app/templates/components/live-search.html +++ b/app/templates/components/live-search.html @@ -9,7 +9,7 @@ {%- set search_label = label or form.search.label.text %} {% if show %}
-