mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 11:08:45 +02:00
N°3560 Allow to scroll vertically through tabs content. User can activate this feature in preference page
This commit is contained in:
2
js/ScrollMagic.min.js
vendored
Normal file
2
js/ScrollMagic.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
178
js/layouts/tab-container/scrollable-tabs.js
Normal file
178
js/layouts/tab-container/scrollable-tabs.js
Normal file
@@ -0,0 +1,178 @@
|
||||
$.widget( "itop.scrollabletabs", $.ui.tabs, {
|
||||
js_selectors:
|
||||
{
|
||||
tab_toggler: '[data-role="ibo-tab-container--tab-toggler"]',
|
||||
tab_container_list: '[data-role="ibo-tab-container--tab-container-list"]'
|
||||
},
|
||||
controller: null,
|
||||
_create: function() {
|
||||
var me = this;
|
||||
|
||||
// Initialize a single controller for this tab container
|
||||
this.controller = new ScrollMagic.Controller({'container': '#' + this.element.find(this.js_selectors.tab_container_list).attr('id'), 'refreshInterval' : 200});
|
||||
|
||||
// Add remote tabs to controller after they are loaded
|
||||
var afterloadajax = function (a, b)
|
||||
{
|
||||
me._newScene(b.tab, b.panel).addTo(me.controller);
|
||||
};
|
||||
this.element.on('scrollabletabsload', afterloadajax);
|
||||
|
||||
this._super();
|
||||
|
||||
// Load remote tabs as soon as possible
|
||||
$(this.js_selectors.tab_toggler).each(function() {
|
||||
var that = this;
|
||||
if($(that).attr('href').charAt(0) !== '#') {
|
||||
var index = $(this).parent('li').prevAll().length
|
||||
me.load(index);
|
||||
}
|
||||
});
|
||||
|
||||
// Add every other tab to the controller
|
||||
$(this.js_selectors.tab_toggler).each(function(){
|
||||
var that = this;
|
||||
|
||||
if($(that).attr('href').charAt(0) === '#') {
|
||||
me._newScene($(that).parent('li'), $($(that).attr('href'))).addTo(me.controller);
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
// Create a new scene to be added to the controller
|
||||
_newScene: function(tab, panel)
|
||||
{
|
||||
var me = this;
|
||||
var iPanelId = panel.attr('id');
|
||||
return new ScrollMagic.Scene({
|
||||
triggerElement: '#' + iPanelId,
|
||||
triggerHook: 0.03, // show, when scrolled 10% into view
|
||||
duration: function () {
|
||||
return $('#' + iPanelId).outerHeight();
|
||||
}
|
||||
})
|
||||
.on("enter", function (event) {
|
||||
$(tab).addClass("ui-tabs-active ui-state-active");
|
||||
$(tab).siblings('li').removeClass("ui-tabs-active ui-state-active");
|
||||
me.setTab($(tab));
|
||||
me.element.trigger('tabscrolled', [{'newTab': $(tab)}]);
|
||||
})
|
||||
.on("leave", function (event){
|
||||
$(tab).removeClass("ui-tabs-active ui-state-active");
|
||||
})
|
||||
},
|
||||
// jQuery UI overload
|
||||
_refresh: function() {
|
||||
this._setOptionDisabled( this.options.disabled );
|
||||
this._setupEvents( this.options.event );
|
||||
this._setupHeightStyle( this.options.heightStyle );
|
||||
|
||||
this.tabs.not( this.active ).attr( {
|
||||
"aria-selected": "false",
|
||||
"aria-expanded": "false",
|
||||
tabIndex: -1
|
||||
} );
|
||||
this.panels.not( this._getPanelForTab( this.active ) )
|
||||
// jQuery UI overload : Do NOT hide panels
|
||||
//.hide()
|
||||
.attr( {
|
||||
"aria-hidden": "true"
|
||||
} );
|
||||
|
||||
// Make sure one tab is in the tab order
|
||||
if ( !this.active.length ) {
|
||||
this.tabs.eq( 0 ).attr( "tabIndex", 0 );
|
||||
} else {
|
||||
this.active
|
||||
.attr( {
|
||||
"aria-selected": "true",
|
||||
"aria-expanded": "true",
|
||||
tabIndex: 0
|
||||
} );
|
||||
this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
|
||||
this._getPanelForTab( this.active )
|
||||
.show()
|
||||
.attr( {
|
||||
"aria-hidden": "false"
|
||||
} );
|
||||
}
|
||||
},
|
||||
// jQuery UI overload
|
||||
// Handles show/hide for selecting tabs
|
||||
_toggle: function( event, eventData ) {
|
||||
var that = this,
|
||||
toShow = eventData.newPanel,
|
||||
toHide = eventData.oldPanel;
|
||||
this.running = true;
|
||||
|
||||
function complete() {
|
||||
that.running = false;
|
||||
// We don't want to trigger activate event in this mode
|
||||
//that._trigger( "activate", event, eventData );
|
||||
}
|
||||
|
||||
function show() {
|
||||
// jQuery UI overload
|
||||
//Showing a tab here equals to scrolling to its content.
|
||||
//Enter/leave events on scenes handle the active/inactive classes on tabs
|
||||
//that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
|
||||
if ( toShow.length && that.options.show ) {
|
||||
//that._show( toShow, that.options.show, complete );
|
||||
that.controller.scrollTo('#' + $(toShow).attr('id'));
|
||||
} else {
|
||||
that.controller.scrollTo('#' + $(toShow).attr('id'));
|
||||
// toShow.show();
|
||||
complete();
|
||||
}
|
||||
}
|
||||
|
||||
// jQuery UI overload
|
||||
// We just want to scroll to the new tab with our "show" function, nothing more
|
||||
|
||||
// Start out by hiding, then showing, then completing
|
||||
// if ( toHide.length && this.options.hide ) {
|
||||
// this._hide( toHide, this.options.hide, function() {
|
||||
// that._removeClass( eventData.oldTab.closest( "li" ),
|
||||
// "ui-tabs-active", "ui-state-active" );
|
||||
// show();
|
||||
// } );
|
||||
// } else {
|
||||
// this._removeClass( eventData.oldTab.closest( "li" ),
|
||||
// "ui-tabs-active", "ui-state-active" );
|
||||
// toHide.hide();
|
||||
// show();
|
||||
// }
|
||||
//this._removeClass( eventData.oldTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
|
||||
show();
|
||||
|
||||
toHide.attr( "aria-hidden", "true" );
|
||||
eventData.oldTab.attr( {
|
||||
"aria-selected": "false",
|
||||
"aria-expanded": "false"
|
||||
} );
|
||||
|
||||
// If we're switching tabs, remove the old tab from the tab order.
|
||||
// If we're opening from collapsed state, remove the previous tab from the tab order.
|
||||
// If we're collapsing, then keep the collapsing tab in the tab order.
|
||||
if ( toShow.length && toHide.length ) {
|
||||
eventData.oldTab.attr( "tabIndex", -1 );
|
||||
} else if ( toShow.length ) {
|
||||
this.tabs.filter( function() {
|
||||
return $( this ).attr( "tabIndex" ) === 0;
|
||||
} )
|
||||
.attr( "tabIndex", -1 );
|
||||
}
|
||||
|
||||
toShow.attr( "aria-hidden", "false" );
|
||||
eventData.newTab.attr( {
|
||||
"aria-selected": "true",
|
||||
"aria-expanded": "true",
|
||||
tabIndex: 0
|
||||
} );
|
||||
},
|
||||
|
||||
// Set the current tab information
|
||||
setTab : function(tab){
|
||||
this.active = tab;
|
||||
},
|
||||
});
|
||||
@@ -27,6 +27,7 @@ $(function()
|
||||
css_classes:
|
||||
{
|
||||
is_hidden: 'ibo-is-hidden',
|
||||
is_scrollable: 'ibo-is-scrollable'
|
||||
},
|
||||
js_selectors:
|
||||
{
|
||||
@@ -42,7 +43,8 @@ $(function()
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
this.element.addClass('ibo-tab-container');
|
||||
var me = this;
|
||||
this.element.addClass('ibo-tab-container');
|
||||
|
||||
// Ugly patch for a change in the behavior of jQuery UI:
|
||||
// Before jQuery UI 1.9, tabs were always considered as "local" (opposed to Ajax)
|
||||
@@ -65,13 +67,22 @@ $(function()
|
||||
// that the tabs aren't changed on click, and any custom event name can be
|
||||
// specified. Note that if you define a callback for the 'select' event, it
|
||||
// will be executed for the selected tab whenever the hash changes.
|
||||
this.element.tabs({event: 'change'});
|
||||
this._addTabsWidget({event: 'change'});
|
||||
} else {
|
||||
this.element.tabs();
|
||||
this._addTabsWidget();
|
||||
}
|
||||
|
||||
|
||||
this._bindEvents();
|
||||
},
|
||||
_addTabsWidget: function(aParams)
|
||||
{
|
||||
if(this.element.hasClass('ibo-is-scrollable')){
|
||||
this.element.scrollabletabs(aParams);
|
||||
} else {
|
||||
this.element.tabs(aParams);
|
||||
}
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
@@ -86,6 +97,9 @@ $(function()
|
||||
this.element.on('tabsactivate', function(oEvent, oUI){
|
||||
me._onTabActivated(oUI);
|
||||
});
|
||||
this.element.on('tabscrolled', function(oEvent, oUI){
|
||||
me._onTabActivated(oUI);
|
||||
});
|
||||
// Bind an event to window.onhashchange that, when the history state changes,
|
||||
// iterates over all tab widgets, changing the current tab as necessary.
|
||||
$(window).on('hashchange', function(){
|
||||
Reference in New Issue
Block a user