mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-09-24 10:27:46 +02:00
JS: Add responsive-tabbar behavior draft
This commit is contained in:
parent
9f9cd71d02
commit
634eebf85b
@ -4,87 +4,144 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
|
||||||
* In case of unsufficient space hide tabitems behind a dropdown
|
|
||||||
*
|
|
||||||
* @param {object} e Event
|
|
||||||
*/
|
|
||||||
function onRendered(e) {
|
function onRendered(e) {
|
||||||
var $tabs = $(this).find(".tabs");
|
var _this = e.data.self;
|
||||||
|
var $this = $(this);
|
||||||
if ($tabs.length) {
|
console.log("on rendered", e.type);
|
||||||
var breakIndex = determineBreakIndex($tabs)
|
if ($this.find(".tabs")) {
|
||||||
|
cacheTabWidths($this, _this);
|
||||||
if (breakIndex) {
|
updateBreakIndex($this, _this);
|
||||||
createDropdown($tabs, breakIndex);
|
|
||||||
} else {
|
|
||||||
console.log("tab items fit", breakIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function onWindowResized (e) {
|
||||||
* Hide tab items behind a dropdown
|
console.log("window resize", e);
|
||||||
*
|
var _this = e.data.self;
|
||||||
* @param {jQuery} $tabs The tab navigation element to modify
|
|
||||||
* @param {int} breakindex The index for the first tab to hide
|
|
||||||
*/
|
|
||||||
function createDropdown($tabs, breakIndex) {
|
|
||||||
var $tabItems = $tabs.children('li');
|
|
||||||
var index = breakIndex - 1;
|
|
||||||
|
|
||||||
if ($tabs.children('.additional-items').length < 1) {
|
$('#col1, #col2').each(function(i) {
|
||||||
|
var $this = $(this);
|
||||||
var $additionalTabsDropdown = $('<li class="dropdown-nav-item additional-items"><a href="#" class="dropdown-toggle"><i class="icon-attention-alt"></i></a><ul class="nav"></ul></li>');
|
if ($this.find(".tabs")) {
|
||||||
|
if (_this.containerData[$this.attr("id")]) {
|
||||||
for (var i = index; i < $tabItems.length; i++) {
|
console.log("update");
|
||||||
var $item = $($tabItems.get(i));
|
updateBreakIndex($this, _this);
|
||||||
if ($item.children('ul.nav').length > 0) {
|
}
|
||||||
|
|
||||||
$item.children('ul.nav').children('li').each(function(j) {
|
|
||||||
|
|
||||||
var $clonedItem = $(this).clone();
|
|
||||||
|
|
||||||
console.log("itemtext", $clonedItem.text());
|
|
||||||
|
|
||||||
$additionalTabsDropdown.children('ul').append($clonedItem);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var $clonedItem = $item.clone();
|
|
||||||
$additionalTabsDropdown.children('ul').append( $clonedItem );
|
|
||||||
$clonedItem.children('a').append($clonedItem.children("a").attr("title"));
|
|
||||||
}
|
|
||||||
$item.hide();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
$tabs.append($additionalTabsDropdown);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function onLayoutChange (e) {
|
||||||
|
|
||||||
|
var _this = e.data.self;
|
||||||
|
|
||||||
|
$('#col1, #col2').each(function(i) {
|
||||||
|
var $this = $(this);
|
||||||
|
if ($this.find(".tabs")) {
|
||||||
|
cacheTabWidths($this, _this);
|
||||||
|
updateBreakIndex($this, _this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the breakIndex according to tabs container width
|
||||||
*
|
*
|
||||||
|
* @param {jQuery} $container Element containing the tabs
|
||||||
*
|
*
|
||||||
* @param {jQuery} $tabContainer The element containing the tabs
|
* @param {object} e Event
|
||||||
*
|
|
||||||
* @returns {Bool} false if there is sufficiently wide, the index of the first tab
|
|
||||||
*/
|
*/
|
||||||
function determineBreakIndex($tabContainer) {
|
function updateBreakIndex($container, e) {
|
||||||
|
|
||||||
var breakIndex = false;
|
var breakIndex = false;
|
||||||
var $tabItems = $tabContainer.children('li');
|
|
||||||
var itemsWidth = 0;
|
|
||||||
|
|
||||||
$tabItems.each(function(i) {
|
var w = 0;
|
||||||
|
var tabsElWidth = $container.find('.tabs').not(".cloned").width() - parseFloat($container.find('.tabs').not(".cloned").css("padding-left"));
|
||||||
|
var tabWidths = e.containerData[$container.attr("id")].tabWidths;
|
||||||
|
|
||||||
itemsWidth += $(this).width() + parseFloat($(this).css('margin-right'));
|
for (var i = 0; i < tabWidths.length; i++) {
|
||||||
|
w += tabWidths[i];
|
||||||
if (itemsWidth > $tabContainer.width()) {
|
if (w > Math.floor(tabsElWidth)) {
|
||||||
breakIndex = i;
|
breakIndex = i;
|
||||||
|
} else {
|
||||||
|
breakIndex = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log("too wide?", itemsWidth, ":", $tabContainer.width());
|
console.log("w : tabsW", w, tabsElWidth, $container, tabWidths);
|
||||||
|
|
||||||
|
setBreakIndex($container, breakIndex, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the breakIndex and if value has changed render Tabs
|
||||||
|
*
|
||||||
|
* @param {jQuery} $container Element containing the tabs
|
||||||
|
*
|
||||||
|
* @param {Int} NewIndex New Value for the breakIndex
|
||||||
|
*/
|
||||||
|
function setBreakIndex($container, newIndex, e) {
|
||||||
|
if (newIndex == e.containerData[$container.attr("id")].breakIndex) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$container.breakIndex = newIndex;
|
||||||
|
renderTabs($container);
|
||||||
|
console.log("break index change", $container, $container.breakIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save horizontal dimensions of the tabs once
|
||||||
|
*
|
||||||
|
* @param {jQuery} $container Element containing the tabs
|
||||||
|
*
|
||||||
|
* @param {object} e Event
|
||||||
|
*/
|
||||||
|
function cacheTabWidths($container, e) {
|
||||||
|
var containerData = {};
|
||||||
|
containerData.tabWidths = [];
|
||||||
|
|
||||||
|
$container.find(".tabs").not(".cloned").children("li").each(function () {
|
||||||
|
containerData.tabWidths.push($(this).width() + parseFloat($(this).css("margin-right")));
|
||||||
});
|
});
|
||||||
|
|
||||||
return breakIndex;
|
e.containerData[$container.attr("id")] = containerData;
|
||||||
|
|
||||||
|
console.log("tab widths cached", $container, containerData, e.containerData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Tabs of a container according to the updated breakIndex
|
||||||
|
*
|
||||||
|
* @param {jQuery} $container Element containing the tabs
|
||||||
|
*/
|
||||||
|
function renderTabs($container) {
|
||||||
|
$container.find('.tabs.cloned').remove();
|
||||||
|
var $tabs = $container.find(".tabs").show();
|
||||||
|
if ($container.breakIndex) {
|
||||||
|
var $additionalTabsDropdown = $('<li class="dropdown-nav-item additional-items"><a href="#" class="dropdown-toggle"><i class="icon-ellipsis"></i></a><ul class="nav"></ul></li>');
|
||||||
|
var $clonedTabs = $tabs.clone().addClass("cloned");
|
||||||
|
var $tabItems = $clonedTabs.children('li');
|
||||||
|
|
||||||
|
for (var i = $container.breakIndex-1; i < $tabItems.length + 1; i++) {
|
||||||
|
var $item = $($tabItems.get(i));
|
||||||
|
|
||||||
|
if ($item.children('ul.nav').length > 0) {
|
||||||
|
$item.children('ul.nav').children('li').each(function(j) {
|
||||||
|
$additionalTabsDropdown.children("ul").append(this);
|
||||||
|
});
|
||||||
|
$item.remove();
|
||||||
|
} else {
|
||||||
|
$additionalTabsDropdown.children("ul").append($item);
|
||||||
|
$item.children("a").append($item.children("a").attr("title"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$clonedTabs.append($additionalTabsDropdown);
|
||||||
|
$container.find(".controls").prepend($clonedTabs);
|
||||||
|
|
||||||
|
$tabs.hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Icinga.Behaviors = Icinga.Behaviors || {};
|
Icinga.Behaviors = Icinga.Behaviors || {};
|
||||||
@ -93,16 +150,19 @@
|
|||||||
* Behavior for managing tab bar width
|
* Behavior for managing tab bar width
|
||||||
*
|
*
|
||||||
* The ResponsiveTabBar will wrap tabs in a dropdown if the containing
|
* The ResponsiveTabBar will wrap tabs in a dropdown if the containing
|
||||||
* tab bar becomes too narrow
|
* tab bar becomes insufficient
|
||||||
*
|
*
|
||||||
* @param {Icinga} icinga
|
* @param {Icinga} icinga
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
var ResponsiveTabBar = function(icinga) {
|
var ResponsiveTabBar = function(icinga) {
|
||||||
|
this.containerData = [];
|
||||||
Icinga.EventListener.call(this, icinga);
|
Icinga.EventListener.call(this, icinga);
|
||||||
this.on('rendered', '#col1, #col2', onRendered, this);
|
this.on('rendered', '#col1, #col2', onRendered, this);
|
||||||
$(document).on("resize", onRendered, this);
|
$(window).resize({self: this}, onWindowResized);
|
||||||
|
this.on('layout-change', '#col1, #col2', onLayoutChange, this);
|
||||||
|
this.on('close-column', '#col1, #col2', onRendered, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
ResponsiveTabBar.prototype = new Icinga.EventListener();
|
ResponsiveTabBar.prototype = new Icinga.EventListener();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user