META-INF.resources.primefaces.tabview.tabview.js Maven / Gradle / Ivy
/**
* __PrimeFaces TabView Widget__
*
* TabView is a container component to group content in tabs.
*
* @typedef PrimeFaces.widget.TabView.OnTabChangeCallback Client side callback to execute when a tab is clicked. If the
* callback returns `false`, the tab is not selected. See also {@link TabViewCfg.onTabChange}.
* @this {PrimeFaces.widget.TabView} PrimeFaces.widget.TabView.OnTabChangeCallback
* @param {number} PrimeFaces.widget.TabView.OnTabChangeCallback.index 0-based index of the tab that is about to be
* selected.
* @return {boolean} PrimeFaces.widget.TabView.OnTabChangeCallback `true` to switch to the tab, `false` to stay at the
* current tab.
*
* @typedef PrimeFaces.widget.TabView.OnTabCloseCallback Client side callback to execute on tab close. When the callback
* returns `false`, the tab is not closed. See also {@link TabViewCfg.onTabClose}.
* @this {PrimeFaces.widget.TabView} PrimeFaces.widget.TabView.OnTabCloseCallback
* @param {number} PrimeFaces.widget.TabView.OnTabCloseCallback.index 0-based index of the tab that is about to be
* closed.
* @return {boolean} PrimeFaces.widget.TabView.OnTabCloseCallback `true` to close the tab, `false` to keep the tab
* open.
*
* @typedef PrimeFaces.widget.TabView.OnTabShowCallback Client side callback to execute when a tab is shown. See also
* {@link TabViewCfg.onTabShow}.
* @this {PrimeFaces.widget.TabView} PrimeFaces.widget.TabView.OnTabShowCallback
* @param {number} PrimeFaces.widget.TabView.OnTabShowCallback.index 0-based index of the tab that was
* shown.
*
* @prop {JQuery} [firstTab] The DOM element for the first tab.
* @prop {null} focusedTabHeader Always `null`.
* @prop {JQuery} headerContainer The DOM element for the container element with the tab header.
* @prop {JQuery} lastTab The DOM element for the last tab.
* @prop {JQuery} navscroller The DOM element for the tab navigation bar.
* @prop {JQuery} navcrollerLeft The DOM element for the button that scrolls the tab navigation bar to the left.
* @prop {JQuery} navcrollerRight The DOM element for the button that scrolls the tab navigation bar to the right.
* @prop {JQuery} navContainer The DOM element for the container element with the tab navigation bar.
* @prop {JQuery} panelContainer The DOM element for the panel with the tab's contents.
* @prop {JQuery} scrollStateHolder The DOM element for the hidden input field storing the current scroll position.
* @prop {JQuery} stateHolder The DOM element for the hidden input field storing which is tab is active and visible.
* @prop {number} tabindex Position of the element in the tabbing order.
*
* @interface {PrimeFaces.widget.TabViewCfg} cfg The configuration for the {@link TabView| TabView widget}.
* You can access this configuration via {@link PrimeFaces.widget.BaseWidget.cfg|BaseWidget.cfg}. Please note that this
* configuration is usually meant to be read-only and should not be modified.
* @extends {PrimeFaces.widget.DeferredWidgetCfg} cfg
*
* @prop {boolean} cfg.cache When tab contents are lazy loaded via AJAX toggle mode, caching only retrieves the tab
* contents once and subsequent toggles of a cached tab does not communicate with server. If caching is turned off, tab
* contents are reloaded from server each time tab is clicked.
* @prop {boolean} cfg.dynamic Enables lazy loading of inactive tabs.
* @prop {string} cfg.effect Name of the transition effect.
* @prop {number} cfg.effectDuration Duration of the transition effect.
* @prop {PrimeFaces.widget.TabView.OnTabChangeCallback} cfg.onTabChange Client side callback to execute when a tab is
* clicked. If the callback returns `false`, the tab is not selected.
* @prop {PrimeFaces.widget.TabView.OnTabCloseCallback} cfg.onTabClose Client side callback to execute on tab close.
* When the callback returns `false`, the tab is not closed.
* @prop {PrimeFaces.widget.TabView.OnTabShowCallback} cfg.onTabShow Client side callback to execute when a tab is
* shown.
* @prop {boolean} cfg.scrollable When enabled, tab headers can be scrolled horizontally instead of wrapping.
* @prop {number} cfg.selected The currently selected tab.
* @prop {number} cfg.tabindex Position of the element in the tabbing order.
* @prop {boolean} cfg.multiViewState Whether to keep TabView state across views.
* @prop {boolean} cfg.focusOnError Whether to focus the first tab that has an error associated to it.
* @prop {boolean} cfg.focusOnLastActiveTab Whether to focus on the last active tab that a user selected.
*/
PrimeFaces.widget.TabView = PrimeFaces.widget.DeferredWidget.extend({
/**
* @override
* @inheritdoc
* @param {PrimeFaces.PartialWidgetCfg} cfg
*/
init: function(cfg) {
this._super(cfg);
this.panelContainer = this.jq.children('.ui-tabs-panels');
this.stateHolder = $(this.jqId + '_activeIndex');
this.cfg.selected = parseInt(this.stateHolder.val());
this.focusedTabHeader = null;
this.tabindex = this.cfg.tabindex||0;
this.cfg.focusOnError = this.cfg.focusOnError || false;
this.cfg.focusOnLastActiveTab = this.cfg.focusOnLastActiveTab || false;
if(this.cfg.scrollable) {
this.navscroller = this.jq.children('.ui-tabs-navscroller');
this.navcrollerLeft = this.navscroller.children('.ui-tabs-navscroller-btn-left');
this.navcrollerRight = this.navscroller.children('.ui-tabs-navscroller-btn-right');
this.navContainer = this.navscroller.children('.ui-tabs-nav');
this.firstTab = this.navContainer.children('li.ui-tabs-header:first-child');
this.lastTab = this.navContainer.children('li.ui-tabs-header:last-child');
this.scrollStateHolder = $(this.jqId + '_scrollState');
}
else {
this.navContainer = this.jq.children('.ui-tabs-nav');
}
this.headerContainer = this.navContainer.children('li.ui-tabs-header');
this.bindEvents();
//Cache initial active tab
if(this.cfg.dynamic && this.cfg.cache) {
this.markAsLoaded(this.panelContainer.children().eq(this.cfg.selected));
}
this.renderDeferred();
},
/**
* @override
* @inheritdoc
*/
renderDeferred: function() {
if(this.jq.is(':visible')) {
this._render();
}
else if (this.jq.parent()[0]) {
var container = this.jq.parent()[0].closest('.ui-hidden-container');
if (container) {
var $container = $(container);
if ($container.length) {
var $this = this;
this.addDeferredRender(this.id, $container, function() {
return $this.render();
});
}
}
}
},
/**
* @include
* @override
* @protected
* @inheritdoc
*/
_render: function() {
if(this.cfg.scrollable) {
this.initScrolling();
var $this = this;
PrimeFaces.utils.registerResizeHandler(this, 'resize.' + this.id + '_align', null, function() {
$this.initScrolling();
});
}
},
/**
* Sets up all event listeners that are required by this widget.
* @private
*/
bindEvents: function() {
var $this = this;
//Tab header events
this.headerContainer
.on('mouseover.tabview', function(e) {
var element = $(this);
if(!element.hasClass('ui-state-disabled')) {
element.addClass('ui-state-hover');
}
})
.on('mouseout.tabview', function(e) {
var element = $(this);
if(!element.hasClass('ui-state-disabled')) {
element.removeClass('ui-state-hover');
}
})
.on('click.tabview', function(e) {
var element = $(this);
if($(e.target).is(':not(.ui-icon-close)')) {
var index = $this.headerContainer.index(element);
if(!element.hasClass('ui-state-disabled') && index !== $this.cfg.selected) {
$this.select(index);
element.trigger('focus.tabview');
}
}
e.preventDefault();
});
//Closable tabs
this.navContainer.find('li .ui-icon-close')
.on('click.tabview', function(e) {
var index = $(this).parent().index();
if($this.cfg.onTabClose) {
var retVal = $this.cfg.onTabClose.call($this, index);
if(retVal !== false) {
$this.remove(index);
}
}
else {
$this.remove(index);
}
e.preventDefault();
});
//Scrolling
if(this.cfg.scrollable) {
this.navscroller.children('.ui-tabs-navscroller-btn')
.on('mouseover.tabview', function() {
var el = $(this);
if(!el.hasClass('ui-state-disabled'))
$(this).addClass('ui-state-hover');
})
.on('mouseout.tabview', function() {
var el = $(this);
if(!el.hasClass('ui-state-disabled'))
$(this).removeClass('ui-state-hover ui-state-active');
})
.on('mousedown.tabview', function() {
var el = $(this);
if(!el.hasClass('ui-state-disabled'))
$(this).removeClass('ui-state-hover').addClass('ui-state-active');
})
.on('mouseup.tabview', function() {
var el = $(this);
if(!el.hasClass('ui-state-disabled'))
$(this).addClass('ui-state-hover').removeClass('ui-state-active');
})
.on('focus.tabview', function() {
$(this).addClass('ui-state-focus');
})
.on('blur.tabview', function() {
$(this).removeClass('ui-state-focus');
});
this.navcrollerLeft.on('click.tabview', function(e) {
$this.scroll(100);
e.preventDefault();
});
this.navcrollerRight.on('click.tabview', function(e) {
$this.scroll(-100);
e.preventDefault();
});
}
this.bindSwipeEvents();
this.bindKeyEvents();
this.bindRefreshListener();
},
/**
* Binds swipe events to this tabview.
* @private
*/
bindSwipeEvents: function() {
if (!PrimeFaces.env.isTouchable(this.cfg)) {
return;
}
var $this = this;
this.jq.swipe({
swipeLeft:function(event) {
var activeIndex = $this.getActiveIndex();
if (activeIndex < $this.getLength() - 1) {
$this.select(activeIndex + 1);
}
},
swipeRight: function(event) {
var activeIndex = $this.getActiveIndex();
if (activeIndex > 0) {
$this.select(activeIndex - 1);
}
},
excludedElements: PrimeFaces.utils.excludedSwipeElements()
});
},
/**
* Sets up all keyboard related event listeners that are required by this widget.
* @private
*/
bindKeyEvents: function() {
var $this = this,
tabs = this.headerContainer;
/* For Screen Reader and Keyboard accessibility */
tabs.not('.ui-state-disabled').attr('tabindex', this.tabindex);
tabs.on('focus.tabview', function(e) {
var focusedTab = $(this);
if(!focusedTab.hasClass('ui-state-disabled')) {
focusedTab.addClass('ui-tabs-outline');
if($this.cfg.scrollable) {
if($this.navcrollerRight.is(':visible') && (focusedTab.position().left + focusedTab.width() > $this.navcrollerRight.position().left)) {
$this.navcrollerRight.trigger('click.tabview');
}
else if($this.navcrollerLeft.is(':visible') && (focusedTab.position().left < $this.navcrollerLeft.position().left)) {
$this.navcrollerLeft.trigger('click.tabview');
}
}
}
})
.on('blur.tabview', function(){
$(this).removeClass('ui-tabs-outline');
})
.on('keydown.tabview', function(e) {
var element = $(this);
if(PrimeFaces.utils.isActionKey(e) && !element.hasClass('ui-state-disabled')) {
$this.select(element.index());
e.preventDefault();
}
});
//Scrolling
if(this.cfg.scrollable) {
this.navcrollerLeft.on('keydown.tabview', function(e) {
if (PrimeFaces.utils.isActionKey(e)) {
$this.scroll(100);
e.preventDefault();
}
});
this.navcrollerRight.on('keydown.tabview', function(e) {
if (PrimeFaces.utils.isActionKey(e)) {
$this.scroll(-100);
e.preventDefault();
}
});
}
},
/**
* Binds refresh listener to update error highlighting or restore the last active tab on component udpate.
* @private
*/
bindRefreshListener: function() {
var $this = this;
var focusIndex = -1;
this.addRefreshListener(function() {
// update error highlighting and set focusIndex
$(this.jqId + '>ul>li.ui-tabs-header').each(function() {
var tabId = $('a', this).attr('href').slice(1);
tabId = PrimeFaces.escapeClientId(tabId);
if ($(tabId + ' .ui-state-error').length > 0 || $(tabId + ' .ui-message-error-detail').length > 0) {
$(this).addClass('ui-state-error');
if (focusIndex < 0) {
focusIndex = $(this).data('index');
}
} else {
$(this).removeClass('ui-state-error');
}
});
// set focusIndex to restore the last active tab
// "focusOnError" always takes precedence over "focusOnLastActiveTab"
if (focusIndex < 0 || !$this.cfg.focusOnError) {
focusIndex = $this.cfg.selected;
}
if (($this.cfg.focusOnError || $this.cfg.focusOnLastActiveTab) && focusIndex >= 0) {
setTimeout(function () {$this.select(focusIndex, true)}, 10);
}
});
},
/**
* Sets up the classes and attributes required for scrolling the tab navigation bar.
* @private
*/
initScrolling: function() {
if(this.headerContainer.length) {
var overflown = ((this.lastTab.position().left + this.lastTab.width()) - this.firstTab.position().left) > this.navscroller.innerWidth();
if (overflown) {
this.navscroller.removeClass('ui-tabs-navscroller-btn-hidden');
this.navcrollerLeft.attr('tabindex', this.tabindex);
this.navcrollerRight.attr('tabindex', this.tabindex);
this.restoreScrollState();
}
else {
this.navscroller.addClass('ui-tabs-navscroller-btn-hidden');
this.navcrollerLeft.attr('tabindex', this.tabindex);
this.navcrollerRight.attr('tabindex', this.tabindex);
}
}
},
/**
* Scrolls the tab navigation bar by the given amount.
* @param {number} step Amount to scroll the navigation bar, positive to scroll to the right, negative to scroll to
* the left.
*/
scroll: function(step) {
if(this.navContainer.is(':animated')) {
return;
}
var oldMarginLeft = parseInt(this.navContainer.css('margin-left')),
newMarginLeft = oldMarginLeft + step,
viewportWidth = this.navscroller.innerWidth(),
$this = this;
if(step < 0) {
var lastTabBoundry = this.lastTab.position().left + parseInt(this.lastTab.innerWidth());
if(lastTabBoundry > viewportWidth)
this.navContainer.animate({'margin-left': newMarginLeft + 'px'}, 'fast', 'easeInOutCirc', function() {
$this.saveScrollState(newMarginLeft);
if((lastTabBoundry + step) < viewportWidth)
$this.disableScrollerButton($this.navcrollerRight);
if($this.navcrollerLeft.hasClass('ui-state-disabled'))
$this.enableScrollerButton($this.navcrollerLeft);
});
}
else {
if(newMarginLeft <= 0) {
this.navContainer.animate({'margin-left': newMarginLeft + 'px'}, 'fast', 'easeInOutCirc', function() {
$this.saveScrollState(newMarginLeft);
if(newMarginLeft === 0)
$this.disableScrollerButton($this.navcrollerLeft);
if($this.navcrollerRight.hasClass('ui-state-disabled'))
$this.enableScrollerButton($this.navcrollerRight);
});
}
}
},
/**
* Disables the buttons for scrolling the contents of the navigation bar.
* @param {JQuery} btn The scroll button to enable.
*/
disableScrollerButton: function(btn) {
btn.addClass('ui-state-disabled').removeClass('ui-state-hover ui-state-active ui-state-focus').attr('tabindex', -1);
},
/**
* Enables the buttons for scrolling the contents of the navigation bar.
* @param {JQuery} btn The scroll button to enable.
*/
enableScrollerButton: function(btn) {
btn.removeClass('ui-state-disabled').attr('tabindex', this.tabindex);
},
/**
* Stores the current scroll position in a hidden input field, called before an AJAX request.
* @private
* @param {number} value The scroll position to be saved.
*/
saveScrollState: function(value) {
this.scrollStateHolder.val(value);
},
/**
* Restores the current scroll position in a hidden input field, called after an AJAX request.
* @private
*/
restoreScrollState: function() {
var value = parseInt(this.scrollStateHolder.val());
if(value === 0) {
this.disableScrollerButton(this.navcrollerLeft);
}
this.navContainer.css('margin-left', this.scrollStateHolder.val() + 'px');
},
/**
* Selects the given tab, if it is not selected already.
* @param {number} index 0-based index of the tab to select.
* @param {boolean} [silent] Controls whether events are triggered.
* @return {boolean} Whether the given tab is now selected.
*/
select: function(index, silent) {
//Call user onTabChange callback
if(this.cfg.onTabChange && !silent) {
var result = this.cfg.onTabChange.call(this, index);
if(result === false)
return false;
}
var newPanel = this.panelContainer.children().eq(index),
shouldLoad = this.cfg.dynamic && !this.isLoaded(newPanel);
//update state
this.stateHolder.val(newPanel.data('index'));
this.cfg.selected = index;
if(shouldLoad) {
this.loadDynamicTab(newPanel);
}
else {
this.show(newPanel);
if (!silent) {
if (this.hasBehavior('tabChange')) {
this.fireTabChangeEvent(newPanel);
}
else if (this.cfg.multiViewState) {
var options = {
source: this.id,
partialSubmit: true,
partialSubmitFilter: PrimeFaces.escapeClientId(this.id + '_activeIndex'),
process: this.id,
ignoreAutoUpdate: true,
global: false,
params: [
{name: this.id + '_skipChildren', value: true}
]
};
PrimeFaces.ajax.Request.handle(options);
}
}
}
return true;
},
/**
* After a tab was loaded from the server, prepares the given tab and shows it.
* @private
* @param {JQuery} newPanel New tab to be shown.
*/
show: function(newPanel) {
var oldPanel = this.panelContainer.children('.ui-tabs-panel:visible');
// it is possible the current panel has been removed from the DOM with rendered flag
if (!newPanel || newPanel.length === 0) {
newPanel = oldPanel;
}
var headers = this.headerContainer,
actionsQuery = '.ui-tabs-actions:not(.ui-tabs-actions-global)',
oldHeader = headers.filter('.ui-state-active'),
oldActions = oldHeader.next(actionsQuery),
hasOldActions = oldActions.length,
newHeader = headers.eq(newPanel.index()),
newActions = newHeader.next(actionsQuery),
hasNewActions = newActions.length,
globalActions = this.navContainer.children('.ui-tabs-actions.ui-tabs-actions-global'),
$this = this;
globalActions.hide();
if(!hasNewActions){
newActions = globalActions;
hasNewActions = newActions.length;
}
//aria
oldPanel.attr('aria-hidden', true);
oldPanel.addClass('ui-helper-hidden');
oldHeader.attr('aria-expanded', false);
oldHeader.attr('aria-selected', false);
if(hasOldActions) {
oldActions.attr('aria-hidden', true);
}
newPanel.attr('aria-hidden', false);
newPanel.removeClass('ui-helper-hidden');
newHeader.attr('aria-expanded', true);
newHeader.attr('aria-selected', true);
if(hasNewActions) {
newActions.attr('aria-hidden', false);
}
if(this.cfg.effect && oldPanel.length) {
oldPanel.hide(this.cfg.effect, null, this.cfg.effectDuration, function() {
oldHeader.removeClass('ui-tabs-selected ui-state-active');
if(hasOldActions) {
oldActions.hide($this.cfg.effect, null, $this.cfg.effectDuration);
}
newHeader.addClass('ui-tabs-selected ui-state-active');
newPanel.show($this.cfg.effect, null, $this.cfg.effectDuration, function() {
$this.postTabShow(newPanel);
});
if(hasNewActions) {
newActions.show($this.cfg.effect, null, $this.cfg.effectDuration);
}
});
}
else {
oldHeader.removeClass('ui-tabs-selected ui-state-active');
oldPanel.hide();
if(hasOldActions) {
oldActions.hide();
}
newHeader.addClass('ui-tabs-selected ui-state-active');
newPanel.show();
if(hasNewActions) {
newActions.show();
}
this.postTabShow(newPanel);
}
},
/**
* Dynamically loads contents of a tab from the server via AJAX.
* @private
* @param {JQuery} newPanel The tab whose content needs to be loaded.
*/
loadDynamicTab: function(newPanel) {
var $this = this,
tabIndex = newPanel.data('index'),
options = {
source: this.id,
process: this.id,
update: this.id,
ignoreAutoUpdate: true,
params: [
{name: this.id + '_contentLoad', value: true},
{name: this.id + '_newTab', value: newPanel.attr('id')},
{name: this.id + '_tabindex', value: tabIndex}
],
onsuccess: function(responseXML, status, xhr) {
PrimeFaces.ajax.Response.handle(responseXML, status, xhr, {
widget: $this,
handle: function(content) {
// #8994 get new tab reference in case AJAX update removed the old one from DOM
var updatedTab = $this.panelContainer.children().eq(tabIndex);
if($this.cfg.effect) {
// hide first, otherwise it will be displayed after replacing the content with .html()
updatedTab.hide();
}
updatedTab.html(content);
if($this.cfg.cache) {
$this.markAsLoaded(updatedTab);
}
}
});
return true;
},
oncomplete: function() {
// #8994 get new tab reference in case AJAX update removed the old one from DOM
var updatedTab = $this.panelContainer.children().eq(tabIndex);
$this.show(updatedTab);
}
};
if(this.hasBehavior('tabChange')) {
this.callBehavior('tabChange', options);
}
else {
PrimeFaces.ajax.Request.handle(options);
}
},
/**
* Closes the tab at the given index.
* @param {number} index 0-based index of the tab to close.
*/
remove: function(index) {
// remove old header and content
var header = this.headerContainer.eq(index),
panel = this.panelContainer.children().eq(index);
header.remove();
panel.remove();
// refresh "chached" selectors
this.headerContainer = this.navContainer.children('li.ui-tabs-header');
this.panelContainer = this.jq.children('.ui-tabs-panels');
// select next tab
var length = this.getLength();
if(length > 0) {
if(index < this.cfg.selected) {
this.cfg.selected--;
}
else if(index === this.cfg.selected) {
var newIndex = (this.cfg.selected === (length)) ? (this.cfg.selected - 1): this.cfg.selected,
newPanelHeader = this.headerContainer.eq(newIndex);
if(newPanelHeader.hasClass('ui-state-disabled')) {
var newHeader = this.headerContainer.filter(':not(.ui-state-disabled):first');
if(newHeader.length) {
this.select(newHeader.index(), true);
}
}
else {
this.select(newIndex, true);
}
}
}
else {
this.cfg.selected = -1;
}
this.fireTabCloseEvent(panel.attr('id'), index);
},
/**
* Fins the number of tabs of this tab view.
* @return {number} The number of tabs.
*/
getLength: function() {
return this.headerContainer.length;
},
/**
* Finds and returns the tab that is currently selected.
* @return {number} The 0-based index of the currently selected tab.
*/
getActiveIndex: function() {
return this.cfg.selected;
},
/**
* Calls the appropriate behaviors when a different tab was selected.
* @private
* @param {JQuery} panel The tab that was selected.
*/
fireTabChangeEvent: function(panel) {
var ext = {
params: [
{name: this.id + '_newTab', value: panel.attr('id')},
{name: this.id + '_tabindex', value: panel.data('index')}
]
};
this.callBehavior('tabChange', ext);
},
/**
* Calls the appropriate behaviors when a tab was closed.
* @private
* @param {string} id Client ID of the tab that was closed.
* @param {number} index 0-based index of the tab that was closed.
*/
fireTabCloseEvent: function(id, index) {
if(this.hasBehavior('tabClose')) {
var ext = {
params: [
{name: this.id + '_closeTab', value: id},
{name: this.id + '_tabindex', value: index}
]
};
this.callBehavior('tabClose', ext);
}
},
/**
* Reloads a dynamic tab even if it has already been loaded once. Forces an AJAX refresh of the tab.
* @param {number} index 0-based index of the tab to reload.
*/
reload: function(index) {
var reloadPanel = this.panelContainer.children().eq(index);
this.markAsUnloaded(reloadPanel);
this.select(index);
},
/**
* Marks the content of the given tab as loaded.
* @private
* @param {JQuery} panel A panel with content that was loaded.
*/
markAsLoaded: function(panel) {
panel.data('loaded', true);
},
/**
* Marks the content of the given tab as unloaded.
* @private
* @param {JQuery} panel A panel with content that was unloaded.
*/
markAsUnloaded: function(panel) {
panel.data('loaded', false);
},
/**
* If the content of the tab is loaded dynamically via AJAX, checks if the content was loaded already.
* @private
* @param {JQuery} panel A panel to check.
* @return {boolean} Whether the content of the given panel was loaded from the server.
*/
isLoaded: function(panel) {
return panel.data('loaded') === true;
},
/**
* Disables the tab at the given index. Disabled tabs may not be selected.
* @param {number} index 0-based index of the tab to disable.
*/
disable: function(index) {
this.headerContainer.eq(index).addClass('ui-state-disabled').attr('tabindex', '-1');
},
/**
* Enables the tab at the given index. Enabled tabs may be selected.
* @param {number} index 0-based index of the tab to enable.
*/
enable: function(index) {
this.headerContainer.eq(index).removeClass('ui-state-disabled').attr('tabindex', this.tabindex);
},
/**
* Callback that is invoked after a tab was shown.
* @private
* @param {JQuery} newPanel The panel with the content of the tab.
*/
postTabShow: function(newPanel) {
//execute user defined callback
if(this.cfg.onTabShow) {
this.cfg.onTabShow.call(this, newPanel.index());
}
PrimeFaces.invokeDeferredRenders(this.id);
}
});
© 2015 - 2024 Weber Informatics LLC | Privacy Policy