Getting Started
Using the TabPanel control is like using any Wijmo control:
-
Include the required scripts, either from local copies of from our CDN.
For details, please see
Referencing Wijmo in Your Applications.
-
Create elements on the page that will host the controls.
-
Initialize the controls passing the id of the host element as a
parameter, followed by an optional initialization object.
The markup used to initialize TabPanel controls consists of one element
per tab. Each child element contains two children: the tab header and
the tab content.
We suggest you use anchor elements (tag a) for the tab headers
because they are semantically more meaningful than plain div
elements.
In this example, we added a "wj-state-active" class to the "America"
pane markup. That defines the tab that is initially selected.
Alternatively, we could have initialized the TabPanel's
selectedIndex property in JavaScript.
HTML
<div id="tabGettingStarted">
<div>
<a>Africa</a>
<div>
<ul>
<li>Algeria</li>
<li>Angola</li>
<li>Benin</li>
<li>Botswana</li>
</ul>
</div>
</div>
<div>
<a class="wj-state-active">
America
</a>
<div>
<ul>
<li>Canada</li>
<li>Chile</li>
<li>Mexico</li>
<li>United States</li>
</ul>
</div>
</div>
<div>
<a>Asia</a>
<div>
<ul>
<li>China</li>
<li>Korea</li>
<li>India</li>
<li>Japan</li>
</ul>
</div>
</div>
<div>
<a>Europe</a>
<div>
<ul>
<li>Austria</li>
<li>England</li>
<li>France</li>
<li>Germany</li>
<li>Netherlands</li>
<li>Switzerland</li>
</ul>
</div>
</div>
<div>
<a>Oceania</a>
<div>
<ul>
<li>Australia</li>
<li>Fiji</li>
<li>New Zealand</li>
<li>Samoa</li>
</ul>
</div>
</div>
</div>
JS
var tabGettingStarted = new wijmo.nav.TabPanel('#tabGettingStarted');
Result (live):
Africa
- Algeria
- Angola
- Benin
- Botswana
America
- Canada
- Chile
- Mexico
- United States
Europe
- Austria
- England
- France
- Germany
- Netherlands
- Switzerland
Oceania
- Australia
- Fiji
- New Zealand
- Samoa
Hosting Wijmo Controls
One of the main benefits of the TabPanel control is that it automatically
updates any Wijmo controls it contains when a new tab is selected.
When using other tab controls, you must add code to refresh any Wijmo
controls contained in the tabs.
HTML
<div id="tabWijmoControls">
<div>
<a>FlexGrid</a>
<div>
<div id="theGrid"></div>
</div>
</div>
<div>
<a>FlexChart</a>
<div>
<div id="theChart"></div>
</div>
</div>
<div>
<a>Gauges</a>
<div style="overflow:hidden">
<div id="theRadialGauge"></div>
<div id="theLinearGauge"></div>
</div>
</div>
</div>
JS
var tabWijmoControls = new wijmo.nav.TabPanel('#tabWijmoControls');
var theGrid = new wijmo.grid.FlexGrid('#theGrid', {
itemsSource: getData()
});
var theChart = new wijmo.chart.FlexChart('#theChart', {
itemsSource: getData(),
bindingX: 'country',
series: [
{ binding: 'sales', name: 'Sales' },
{ binding: 'expenses', name: 'Expenses' },
{ binding: 'downloads', name: 'Downloads' }
]
});
var theRadialGauge = new wijmo.gauge.RadialGauge('#theRadialGauge', {
min: 0,
max: 100,
value: 75,
isReadOnly: false
});
var theLinearGauge = new wijmo.gauge.LinearGauge('#theLinearGauge', {
min: 0,
max: 100,
value: 75,
isReadOnly: false
});
function getData() {
var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','),
data = [];
for (var i = 0; i < countries.length; i++) {
data.push({
country: countries[i],
sales: Math.random() * 10000,
expenses: Math.random() * 5000,
downloads: Math.round(Math.random() * 20000),
});
}
return data;
}
CSS
.wj-tabpanel .wj-flexgrid,
.wj-tabpanel .wj-flexchart,
.wj-tabpanel .wj-radialgauge {
height: 200px;
border: none;
}
Creating TabPanels Programmatically
In some cases, you may want to add tabs to a TabPanel control
programmatically rather than using HTML markup.
You can do this using the tabs property, which provides
access to the collection of tabs in the TabPanel.
In this example, we add several Tab objects to the tabs
collection. Each Tab object is defined by a header and a pane
elements.
You can also use the tabs property to remove, modify, or
reorder the tabs within the TabPanel.
HTML
<div id="tabInCode">
</div>
JS
var tabInCode = new wijmo.nav.TabPanel('#tabInCode'),
url = 'http://services.odata.org/Northwind/Northwind.svc/',
headers = 'Employees,Categories,Products,Customers'.split(',');
tabInCode.tabs.deferUpdate(function () { // update only when done
headers.forEach(function (header) {
// create the tab header element
var elHeader = document.createElement('a');
elHeader.textContent = header;
// create the tab pane element
var elPane = document.createElement('div'),
elGrid = document.createElement('div'),
grid = new wijmo.grid.FlexGrid(elGrid, {
isReadOnly: true,
itemsSource: new wijmo.odata.ODataCollectionView(url, header)
});
elPane.appendChild(elGrid);
// add the new Tab to the TabPanel
tabInCode.tabs.push(new wijmo.nav.Tab(elHeader, elPane));
});
});
Styling and CSS
You can customize the appearance of the TabPanel using CSS.
The TabPanel control has a simple layout, which makes it easy
to style using CSS. For example, tabs appear above the content
by default, but you can use CSS to change their position and
show the below or vertically stacked, to the left or to the right
of the content.
This example changes the appearance of the Tabs and lets you
select the tab alignment and whether or not to use animation
when switching tabs.
HTML
<div id="tabCss" class="custom-tab">
<div>
<a>Africa</a>
<div>
<ul>
<li>Algeria</li>
<li>Angola</li>
<li>Benin</li>
<li>Botswana</li>
</ul>
</div>
</div>
<div>
<a>America</a>
<div>
<ul>
<li>Canada</li>
<li>Chile</li>
<li>Mexico</li>
<li>United States</li>
</ul>
</div>
</div>
<div>
<a>Asia</a>
<div>
<ul>
<li>China</li>
<li>Korea</li>
<li>India</li>
<li>Japan</li>
</ul>
</div>
</div>
<div>
<a>Europe</a>
<div>
<ul>
<li>Austria</li>
<li>England</li>
<li>France</li>
<li>Germany</li>
<li>Netherlands</li>
<li>Switzerland</li>
</ul>
</div>
</div>
<div>
<a>Oceania</a>
<div>
<ul>
<li>Australia</li>
<li>Fiji</li>
<li>New Zealand</li>
<li>Samoa</li>
</ul>
</div>
</div>
</div>
<div>
<label for="tabAlign">
Tab Alignment
</label>
<div id="tabAlign"></div>
</div>
<div>
<label for="isAnimated">
isAnimated
</label>
<input id="isAnimated" type="checkbox" checked="checked">
</div>
<div>
<label for="customHeaders">
Custom Headers
</label>
<input id="customHeaders" type="checkbox">
</div>
<div>
<label for="tabsOnLeft">
Tabs on the Left
</label>
<input id="tabsOnLeft" type="checkbox">
</div>
JS
var tabCss = new wijmo.nav.TabPanel('#tabCss');
// toggle custom classes
document.getElementById('tabsOnLeft').addEventListener('click', function (e) {
wijmo.toggleClass(tabCss.hostElement, 'tabs-on-left', e.target.checked);
});
document.getElementById('customHeaders').addEventListener('click', function (e) {
wijmo.toggleClass(tabCss.hostElement, 'custom-headers', e.target.checked);
});
// change tab alignment
var tabAlign = new wijmo.input.ComboBox('#tabAlign', {
itemsSource: 'Left,Center,Right'.split(','),
selectedIndexChanged: function (s, e) {
tabCss.hostElement.querySelector('.wj-tabheaders').style.textAlign = s.text;
}
});
// toggle animation
document.getElementById('isAnimated').addEventListener('click', function (e) {
tabCss.isAnimated = e.target.checked;
});
CSS
/* custom-headers */
.wj-tabpanel.custom-headers .wj-tabpanes {
border-top: none;
}
.wj-tabpanel.custom-headers .wj-tabheaders {
background: black;
color: white;
}
.wj-tabpanel.custom-headers .wj-tabheaders .wj-tabheader.wj-state-active {
background: white;
color: black;
}
.wj-tabpanel.custom-headers .wj-tabheaders .wj-tabheader:not(.wj-state-active) {
font-weight: normal;
}
.wj-tabpanel.custom-headers .wj-tabheaders .wj-tabheader.wj-state-active:after { /* hide underline */
display: none;
}
/* tabs on the left*/
.wj-tabpanel.tabs-on-left > div{
display: flex;
align-items: center;
}
.wj-tabpanel.tabs-on-left .wj-tabheaders {
display: flex;
flex-direction: column;
min-width: 8em;
border-right: 1px solid #ddd;
}
.wj-tabpanel.tabs-on-left .wj-tabpanes {
display: flex;
flex-grow: 1;
border-top: none;
overflow-x: hidden;
}
Disabled and Invisible Tabs
You can disable or hide individual tabs using the
Tab's isDisabled and isVisible properties.
HTML
<div id="tabDisableHide">
<div>
<a>Africa</a>
<div>
<ul>
<li>Algeria</li>
<li>Angola</li>
<li>Benin</li>
<li>Botswana</li>
</ul>
</div>
</div>
<div>
<a>America</a>
<div>
<ul>
<li>Canada</li>
<li>Chile</li>
<li>Mexico</li>
<li>United States</li>
</ul>
</div>
</div>
<div>
<a>Asia</a>
<div>
<ul>
<li>China</li>
<li>Korea</li>
<li>India</li>
<li>Japan</li>
</ul>
</div>
</div>
<div>
<a id="tab-europe" class="wj-state-disabled">Europe</a>
<div>
<ul>
<li>Austria</li>
<li>England</li>
<li>France</li>
<li>Germany</li>
<li>Netherlands</li>
<li>Switzerland</li>
</ul>
</div>
</div>
<div>
<a id="tab-oceania">Oceania</a>
<div>
<ul>
<li>Australia</li>
<li>Fiji</li>
<li>New Zealand</li>
<li>Samoa</li>
</ul>
</div>
</div>
</div>
<div>
<label for="disableEurope">
Disable Europe
</label>
<input id="disableEurope" type="checkbox" checked>
</div>
<div>
<label for="showOceania">
Show Oceania
</label>
<input id="showOceania" type="checkbox" checked>
</div>
JS
var tabDisableHide = new wijmo.nav.TabPanel('#tabDisableHide');
// toggle Europe's disabled state
document.getElementById('disableEurope').addEventListener('click', function (e) {
tabDisableHide.getTab('tab-europe').isDisabled = e.target.checked;
});
// toggle Oceania's visibility
document.getElementById('showOceania').addEventListener('click', function (e) {
tabDisableHide.getTab('tab-oceania').isVisible = e.target.checked;
});
Detached Panels
The TabPanel has a built-in panel that shows the content of the
selected tab. In some cases, you may want to display the content
in a different element. To do that, simply hide the built-in
content element and use the selectedIndexChanged
event to update the content.
HTML
<div id="tabDetached">
<!-- tab without any content -->
<div>
<a>Africa</a>
<div></div>
</div>
<div>
<a>America</a>
<div></div>
</div>
<div>
<a>Asia</a>
<div></div>
</div>
<div>
<a>Europe</a>
<div></div>
</div>
<div>
<a>Oceania</a>
<div></div>
</div>
</div>
<p></p>
<div class="panel panel-success">
<!-- separate div to show the content -->
<div class="panel-heading">
<h3 id="detachedContent" class="panel-title"></h3>
</div>
</div>
JS
var tabDetached = new wijmo.nav.TabPanel('#tabDetached', {
// show the content for the selected tab in a separate div
selectedIndexChanged: function (s, e) {
var div = document.getElementById('detachedContent');
div.innerHTML = 'Content for tab <b>' +
s.selectedTab.header.textContent +
'</b>...';
}
});
// hide the built-in content area
tabDetached.hostElement.querySelector('.wj-tabpanes').style.display = 'none';
Accessibility
The TabPanel implements WAI-ARIA accessibility guidelines.
All tab elements have the proper role attributes as well as all applicable
ARIA attributes.
The example below assigns unique IDs to the tab headers and panes,
which the TabPanel automatically uses to generate "aria-controls" and
"aria-labelledby" attributes.
The example also adds a "wj-state-active" class to the "America"
pane in markup to define the tab that is initially selected.
Without that, the first tab would have been selected by default.
Finally, the example shows the effect of the autoSwitch property,
which affects how the control handles the tab and cursor keys.
For a detailed discussion of this topic, please see the
W3C ARIA practices
and
SimplyAccessible article.
HTML
<div id="tabAccessibility">
<div>
<a id="hdr-africa">
Africa
</a>
<div id="pane-africa">
<ul>
<li>Algeria</li>
<li>Angola</li>
<li>Benin</li>
<li>Botswana</li>
</ul>
</div>
</div>
<div>
<a id="hdr-america" class="wj-state-active">
America
</a>
<div id="pane-america">
<ul>
<li>Canada</li>
<li>Chile</li>
<li>Mexico</li>
<li>United States</li>
</ul>
</div>
</div>
<div>
<a id="hdr-asia">
Asia
</a>
<div id="pane-asia">
<ul>
<li>China</li>
<li>Korea</li>
<li>India</li>
<li>Japan</li>
</ul>
</div>
</div>
<div>
<a id="hdr-europe">
Europe
</a>
<div id="pane-europe">
<ul>
<li>Austria</li>
<li>England</li>
<li>France</li>
<li>Germany</li>
<li>Netherlands</li>
<li>Switzerland</li>
</ul>
</div>
</div>
<div>
<a id="hdr-oceania">
Oceania
</a>
<div id="pane-oceania">
<ul>
<li>Australia</li>
<li>Fiji</li>
<li>New Zealand</li>
<li>Samoa</li>
</ul>
</div>
</div>
</div>
<div>
<label for="autoSwitch">
autoSwitch
</label>
<input id="autoSwitch" type="checkbox" checked="checked">
</div>
JS
var tabAccessibility = new wijmo.nav.TabPanel('#tabAccessible');
// toggle autoSwitch property
document.getElementById('autoSwitch').addEventListener('click', function (e) {
tabAccessibility.autoSwitch = e.target.checked;
})
Right to Left (RTL)
Some languages render content from the right to the left of the page
(Arabic and Hebrew are typical examples) . HTML accommodates this with
the 'dir' attribute. Setting 'dir' to 'rtl' on any element causes the
element's content to flow from right to left.
The TabPanel supports this automatically. If the element hosting the
control has the 'dir' attribute set to 'rtl', the panel will render
with tabs aligned from right to left. You don't have to set any
properties on the control.
Note that the 'dir' attribute value is inherited, so if you set it on
the body tag for example, the entire page will be rendered from right
to left, including the TabPanel.
Note also that CSS has a 'direction' attribute that performs the same
function as the 'dir' element attribute. The 'dir' attribute is
generally considered more appropriate for several reasons, including
the fact that it can be used in CSS rules.
HTML
<div id="tabRtl" dir="rtl">
<div>
<a>Africa</a>
<div>
<ul>
<li>Algeria</li>
<li>Angola</li>
<li>Benin</li>
<li>Botswana</li>
</ul>
</div>
</div>
<div>
<a>America</a>
<div>
<ul>
<li>Canada</li>
<li>Chile</li>
<li>Mexico</li>
<li>United States</li>
</ul>
</div>
</div>
<div>
<a>Asia</a>
<div>
<ul>
<li>China</li>
<li>Korea</li>
<li>India</li>
<li>Japan</li>
</ul>
</div>
</div>
<div>
<a>Europe</a>
<div>
<ul>
<li>Austria</li>
<li>England</li>
<li>France</li>
<li>Germany</li>
<li>Netherlands</li>
<li>Switzerland</li>
</ul>
</div>
</div>
<div>
<a>Oceania</a>
<div>
<ul>
<li>Australia</li>
<li>Fiji</li>
<li>New Zealand</li>
<li>Samoa</li>
</ul>
</div>
</div>
</div>
JS
var tabRtl = new wijmo.nav.TabPanel('#tabRtl');
Result (live):
Africa
- Algeria
- Angola
- Benin
- Botswana
America
- Canada
- Chile
- Mexico
- United States
Europe
- Austria
- England
- France
- Germany
- Netherlands
- Switzerland
Oceania
- Australia
- Fiji
- New Zealand
- Samoa