Skip to content

Commit

Permalink
Show a floating horizontal scrollbar for tables
Browse files Browse the repository at this point in the history
Show a floating horizontal scrollbar for tables whose horizontal
overflow is hidden under the container, and the native horizontal
scrollbar is out of view when the length of the table exceeds the
browser view area.

Using JS code:
https://github.com/Amphiluke/floating-scroll

Fixes: #22132
  • Loading branch information
cproensa committed Aug 27, 2017
1 parent 6499371 commit 9db1555
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 13 deletions.
3 changes: 3 additions & 0 deletions core/constant_inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,9 @@
define( 'DROPZONE_VERSION', '4.3.0' );
define( 'DROPZONE_HASH', 'sha256-p2l8VeL3iL1J0NxcXbEVtoyYSC+VbEbre5KHbzq1fq8=' );

# Floating Scroll JS
define( 'FLOATING_SCROLL_VERSION', '2.3.0' );

# Byte Order Markers
define( 'UTF8_BOM', "\xEF\xBB\xBF" );

Expand Down
6 changes: 6 additions & 0 deletions core/layout_api.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ function layout_head_css() {
html_css_link( 'bootstrap-datetimepicker-' . DATETIME_PICKER_VERSION . '.min.css' );
}

# floating scroll (no cdn available)
html_css_link( 'jquery.floatingscroll-' . FLOATING_SCROLL_VERSION . '.css' );

# page specific plugin styles

# theme styles
Expand Down Expand Up @@ -341,6 +344,9 @@ function layout_body_javascript() {
html_javascript_link( 'list-' . LISTJS_VERSION . '.min.js' );
}

# floating scroll (no cdn available)
html_javascript_link( 'jquery.floatingscroll-' . FLOATING_SCROLL_VERSION . '.min.js' );

# ace theme scripts
html_javascript_link( 'ace.min.js' );
}
Expand Down
34 changes: 34 additions & 0 deletions css/jquery.floatingscroll-2.3.0.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.fl-scrolls, .fl-scrolls div {
font-size:0;
line-height:0;
margin:0;
padding:0;
}
.fl-scrolls {
bottom:0;
height:35px;
overflow:auto;
position:fixed;
}
.fl-scrolls div {
height:1px;
overflow:hidden;
}
.fl-scrolls div:before {
content:""; /* fixes #6 */
}
.fl-scrolls-hidden {
bottom:9999px;
}

.fl-scrolls-viewport {
/* It can be any type of positioning except static. Redefine in your CSS as needed */
position:relative;
}
.fl-scrolls-body {
overflow:auto;
}
.fl-scrolls-viewport .fl-scrolls {
left:0;
position:absolute;
}
2 changes: 2 additions & 0 deletions js/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ $(document).ready( function() {
$('tr[id=bugnote-attach-files]').show();
}
});

$('.table-responsive').floatingScroll();
});

function setBugLabel() {
Expand Down
166 changes: 166 additions & 0 deletions js/jquery.floatingscroll-2.3.0.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*!
* jQuery floatingScroll Plugin v2.3.0
* supported by jQuery v1.4.3+
*
* https://github.com/Amphiluke/floating-scroll
* http://amphiluke.github.io/floating-scroll/
*
* Copyright (c) 2011-2017 Amphiluke
*/
(function (global, factory) {
"use strict";
if (typeof define === "function" && define.amd) {
define(["jquery"], factory);
} else if (typeof module === "object" && module.exports) {
factory(require("jquery"));
} else {
factory(global.jQuery);
}
}(this, function ($) {
"use strict";

function FScroll(cont) {
var inst = this,
scrollBody = cont.closest(".fl-scrolls-body");
inst.cont = cont[0];
if (scrollBody.length) {
inst.scrollBody = scrollBody;
}
inst.sbar = inst.initScroll();
inst.visible = true;
inst.updateAPI(); // recalculate floating scrolls and hide those of them whose containers are out of sight
inst.syncSbar(inst.cont);
inst.addEventHandlers();
}

$.extend(FScroll.prototype, {
initScroll: function () {
var flscroll = $("<div class='fl-scrolls'></div>");
$("<div></div>").appendTo(flscroll).css({width: this.cont.scrollWidth + "px"});
return flscroll.appendTo(this.cont);
},

addEventHandlers: function () {
var inst = this,
handlers,
i, len;
handlers = inst.eventHandlers = [
{
$el: inst.scrollBody || $(window),
handlers: {
// Don't use `$.proxy()` since it makes impossible event unbinding individually per instance
// (see the warning at http://api.jquery.com/unbind/)
scroll: function () {inst.checkVisibility();},
resize: function () {inst.updateAPI();}
}
},
{
$el: inst.sbar,
handlers: {
scroll: function () {inst.visible && inst.syncCont(this, true);}
}
},
{
$el: $(inst.cont),
handlers: {
scroll: function () {inst.syncSbar(this, true);},
focusin: function () {
setTimeout(function () {
inst.syncSbar(inst.cont);
}, 0);
},
// The `adjustScroll` event type is kept for backward compatibility only.
"update.fscroll adjustScroll": function (e) {
// Check event namespace to ensure that this is not an extraneous event in a bubbling phase
if (e.namespace === "fscroll" || e.type === "adjustScroll") {
inst.updateAPI();
}
},
"destroy.fscroll": function (e) {
if (e.namespace === "fscroll") {
inst.destroyAPI();
}
}
}
}
];
for (i = 0, len = handlers.length; i < len; i++) {
handlers[i].$el.bind(handlers[i].handlers);
}
},

checkVisibility: function () {
var inst = this,
mustHide = (inst.sbar[0].scrollWidth <= inst.sbar[0].offsetWidth),
contRect,
maxVisibleY;
if (!mustHide) {
contRect = inst.cont.getBoundingClientRect();
maxVisibleY = inst.scrollBody
? inst.scrollBody[0].getBoundingClientRect().bottom
: window.innerHeight || document.documentElement.clientHeight;
mustHide = ((contRect.bottom <= maxVisibleY) || (contRect.top > maxVisibleY));
}
if (inst.visible === mustHide) {
inst.visible = !mustHide;
// we cannot simply hide a floating scroll bar since its scrollLeft property will not update in that case
inst.sbar.toggleClass("fl-scrolls-hidden");
}
},

syncCont: function (sender, preventSyncSbar) {
// Prevents next syncSbar function from changing scroll position
if (this.preventSyncCont === true) {
this.preventSyncCont = false;
return;
}
this.preventSyncSbar = !!preventSyncSbar;
this.cont.scrollLeft = sender.scrollLeft;
},

syncSbar: function (sender, preventSyncCont) {
// Prevents next syncCont function from changing scroll position
if (this.preventSyncSbar === true) {
this.preventSyncSbar = false;
return;
}
this.preventSyncCont = !!preventSyncCont;
this.sbar[0].scrollLeft = sender.scrollLeft;
},

// Recalculate scroll width and container boundaries
updateAPI: function () {
var inst = this,
cont = inst.cont,
pos = cont.getBoundingClientRect();
inst.sbar.width($(cont).outerWidth());
if (!inst.scrollBody) {
inst.sbar.css("left", pos.left + "px");
}
$("div", inst.sbar).width(cont.scrollWidth);
inst.checkVisibility(); // fixes issue #2
},

// Remove a scrollbar and all related event handlers
destroyAPI: function () {
var handlers = this.eventHandlers,
i, len;
for (i = 0, len = handlers.length; i < len; i++) {
handlers[i].$el.unbind(handlers[i].handlers);
}
this.sbar.remove();
}
});

// `attachScroll` is the old alias used in v1.X. Temporally kept for backward compatibility.
$.fn.attachScroll = $.fn.floatingScroll = function (method) {
if (!arguments.length || method === "init") {
this.each(function () {
new FScroll($(this));
});
} else if (FScroll.prototype.hasOwnProperty(method + "API")) {
this.trigger(method + ".fscroll");
}
return this;
};
}));
1 change: 1 addition & 0 deletions js/jquery.floatingscroll-2.3.0.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 15 additions & 13 deletions library/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dropzone.js | 4.3.0 | unpatched
chart.js | 2.1.6 | unpatched
typeahead.js | 1.1.1 | unpatched
list.js | 1.4.1 | unpatched
jquery.floatingscroll | 2.3.0 | unpatched


**Notes**
Expand All @@ -39,16 +40,17 @@ list.js | 1.4.1 | unpatched
Upstream projects
-----------------

project | URL
----------------|--------------------------------------------------------------------
rssbuilder | http://code.google.com/p/flaimo-php/
utf8 | http://sourceforge.net/projects/phputf8
jquery | https://jquery.com/
bootstrap | http://getbootstrap.com/
fontawesome | http://fontawesome.io/
moment.js | https://momentjs.com/ - https://github.com/moment/moment/
datetimepicker | https://github.com/Eonasdan/bootstrap-datetimepicker
dropzone.js | http://www.dropzonejs.com/ - https://github.com/enyo/dropzone
chart.js | http://www.chartjs.org/ - https://github.com/chartjs/Chart.js
typeahead.js | https://github.com/twitter/typeahead.js
list.js | http://listjs.com/ - https://github.com/javve/list.js
project | URL
-----------------------|--------------------------------------------------------------------
rssbuilder | http://code.google.com/p/flaimo-php/
utf8 | http://sourceforge.net/projects/phputf8
jquery | https://jquery.com/
bootstrap | http://getbootstrap.com/
fontawesome | http://fontawesome.io/
moment.js | https://momentjs.com/ - https://github.com/moment/moment/
datetimepicker | https://github.com/Eonasdan/bootstrap-datetimepicker
dropzone.js | http://www.dropzonejs.com/ - https://github.com/enyo/dropzone
chart.js | http://www.chartjs.org/ - https://github.com/chartjs/Chart.js
typeahead.js | https://github.com/twitter/typeahead.js
list.js | http://listjs.com/ - https://github.com/javve/list.js
jquery.floatingscroll | https://github.com/Amphiluke/floating-scroll

0 comments on commit 9db1555

Please sign in to comment.