Skip to content

Commit 761cfc3

Browse files
authored
Merge pull request #48 from mikejacobson/use-tooltips
Add tabsLiContent and tabsPostProcessors features
2 parents cad7d98 + 233d15a commit 761cfc3

13 files changed

+217
-40
lines changed

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ There are also optional features available:
3030
* [Tab Click Handler](#tabClickHandler)
3131
* [Custom Scroll Arrow classes](#cssClassArrows)
3232
* [Custom Scroll Arrow content](#customArrowsContent)
33+
* [Custom Tab LI content](#customTabLiContent)
34+
* [Tab LI and Anchor Post-Processors](#postProcessors)
3335
* [Enable Horizontal Swiping for Touch Screens](#enableSwiping)
3436
* [Enable Right-to-Left Language Support](#enableRtlSupport)
3537

@@ -444,6 +446,52 @@ You would then need to add some CSS to make them work correctly if you don't giv
444446
http://plnkr.co/edit/2MdZCAnLyeU40shxaol3?p=preview
445447

446448

449+
#### <a id="customTabLiContent"></a>Custom Tab LI content
450+
451+
To specify custom HTML for the tabs' LI elements, you can pass in option `tabsLiContent`.
452+
453+
It must be a string array, each entry being an HTML string that defines the tab LI element for the corresponding tab (i.e., same index) in the `tabs` array.
454+
455+
These entries will override the default `<li role="presentation" class=""></li>`.
456+
457+
So, for example, if you had 3 tabs and you needed a custom `tooltip` attribute on each one, your `tabsLiContent` array might look like this (although you would probably build the array dynamically using the `myTabs` data):
458+
459+
```javascript
460+
$('#tabs-inside-here').scrollingTabs({
461+
tabs: myTabs,
462+
tabsLiContent: [
463+
'<li role="presentation" tooltip="Custom TT 1" class="custom-li"></li>',
464+
'<li role="presentation" tooltip="Custom TT 2" class="custom-li"></li>',
465+
'<li role="presentation" tooltip="Custom TT 3" class="custom-li"></li>'
466+
]
467+
});
468+
```
469+
470+
This plunk demonstrates its usage (in conjunction with `tabsPostProcessors`):
471+
http://plnkr.co/edit/ugJLMk7lmDCuZQziQ0k0
472+
473+
474+
#### <a id="postProcessors"></a>Tab LI and Anchor Post-Processors
475+
476+
To perform additional processing on the tab LI and/or Anchor elements after they've been created, you can pass in option `tabsPostProcessors`.
477+
478+
This is an array of functions, each one associated with an entry in the tabs array. When a tab element has been created, its associated post-processor function will be called with two arguments: the newly created $li and $a jQuery elements for that tab.
479+
480+
This allows you to, for example, attach a custom click handler to each anchor tag.
481+
482+
```javascript
483+
$('#tabs-inside-here').scrollingTabs({
484+
tabs: myTabs,
485+
tabsPostProcessors: [
486+
function ($li, $a) { console.log("Tab 1 clicked. $a.href: ", $a.attr('href')); },
487+
function ($li, $a) { console.log("Tab 2 clicked. $a.href: ", $a.attr('href')); },
488+
function ($li, $a) { console.log("Tab 3 clicked. $a.href: ", $a.attr('href')); }
489+
]
490+
});
491+
```
492+
This plunk demonstrates its usage (in conjunction with `tabsLiContent`):
493+
http://plnkr.co/edit/ugJLMk7lmDCuZQziQ0k0
494+
447495

448496

449497
#### <a id="enableSwiping"></a>Enable Horizontal Swiping for Touch Screens

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jquery-bootstrap-scrolling-tabs",
3-
"version": "2.2.1",
3+
"version": "2.3.1",
44
"main": [
55
"./dist/jquery.scrolling-tabs.js",
66
"./dist/jquery.scrolling-tabs.css"

dist/jquery.scrolling-tabs.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* jquery-bootstrap-scrolling-tabs
3-
* @version v2.2.1
3+
* @version v2.3.1
44
* @link https://github.com/mikejacobson/jquery-bootstrap-scrolling-tabs
55
* @author Mike Jacobson <[email protected]>
66
* @license MIT License, http://www.opensource.org/licenses/MIT

dist/jquery.scrolling-tabs.js

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* jquery-bootstrap-scrolling-tabs
3-
* @version v2.2.1
3+
* @version v2.3.1
44
* @link https://github.com/mikejacobson/jquery-bootstrap-scrolling-tabs
55
* @author Mike Jacobson <[email protected]>
66
* @license MIT License, http://www.opensource.org/licenses/MIT
@@ -71,6 +71,35 @@
7171
* corresponds to that required tab property if
7272
* your property name is different than the
7373
* standard name (paneId, title, etc.)
74+
* tabsLiContent:
75+
* optional string array used to define custom HTML
76+
* for each tab's <li> element. Each entry is an HTML
77+
* string defining the tab <li> element for the
78+
* corresponding tab in the tabs array.
79+
* The default for a tab is:
80+
* '<li role="presentation" class=""></li>'
81+
* So, for example, if you had 3 tabs and you needed
82+
* a custom 'tooltip' attribute on each one, your
83+
* tabsLiContent array might look like this:
84+
* [
85+
* '<li role="presentation" tooltip="Custom TT 1" class="custom-li"></li>',
86+
* '<li role="presentation" tooltip="Custom TT 2" class="custom-li"></li>',
87+
* '<li role="presentation" tooltip="Custom TT 3" class="custom-li"></li>'
88+
* ]
89+
* This plunk demonstrates its usage (in conjunction
90+
* with tabsPostProcessors):
91+
* http://plnkr.co/edit/ugJLMk7lmDCuZQziQ0k0
92+
* tabsPostProcessors:
93+
* optional array of functions, each one associated
94+
* with an entry in the tabs array. When a tab element
95+
* has been created, its associated post-processor
96+
* function will be called with two arguments: the
97+
* newly created $li and $a jQuery elements for that tab.
98+
* This allows you to, for example, attach a custom
99+
* event listener to each anchor tag.
100+
* This plunk demonstrates its usage (in conjunction
101+
* with tabsLiContent):
102+
* http://plnkr.co/edit/ugJLMk7lmDCuZQziQ0k0
74103
* ignoreTabPanes: relevant for data-driven tabs only--set to true if
75104
* you want the plugin to only touch the tabs
76105
* and to not generate the tab pane elements
@@ -1128,26 +1157,31 @@
11281157
return $('<div class="tab-content"></div>');
11291158
}
11301159

1131-
function getNewElTabLi(tab, propNames, forceActiveTab) {
1132-
var $li = $('<li role="presentation" class=""></li>'),
1160+
function getNewElTabLi(tab, propNames, options) {
1161+
var liContent = options.tabLiContent || '<li role="presentation" class=""></li>',
1162+
$li = $(liContent),
11331163
$a = getNewElTabAnchor(tab, propNames).appendTo($li);
11341164

11351165
if (tab[propNames.disabled]) {
11361166
$li.addClass('disabled');
11371167
$a.attr('data-toggle', '');
1138-
} else if (forceActiveTab && tab[propNames.active]) {
1168+
} else if (options.forceActiveTab && tab[propNames.active]) {
11391169
$li.addClass('active');
11401170
}
11411171

1172+
if (options.tabPostProcessor) {
1173+
options.tabPostProcessor($li, $a);
1174+
}
1175+
11421176
return $li;
11431177
}
11441178

1145-
function getNewElTabPane(tab, propNames, forceActiveTab) {
1179+
function getNewElTabPane(tab, propNames, options) {
11461180
var $pane = $('<div role="tabpanel" class="tab-pane"></div>')
11471181
.attr('id', tab[propNames.paneId])
11481182
.html(tab[propNames.content]);
11491183

1150-
if (forceActiveTab && tab[propNames.active]) {
1184+
if (options.forceActiveTab && tab[propNames.active]) {
11511185
$pane.addClass('active');
11521186
}
11531187

@@ -1250,16 +1284,22 @@
12501284
return;
12511285
}
12521286

1253-
tabs.forEach(function(tab) {
1287+
tabs.forEach(function(tab, index) {
1288+
var options = {
1289+
forceActiveTab: true,
1290+
tabLiContent: settings.tabsLiContent && settings.tabsLiContent[index],
1291+
tabPostProcessor: settings.tabsPostProcessors && settings.tabsPostProcessors[index]
1292+
};
1293+
12541294
tabElements
1255-
.getNewElTabLi(tab, propNames, true) // true -> forceActiveTab
1295+
.getNewElTabLi(tab, propNames, options)
12561296
.appendTo($navTabs);
12571297

12581298
// build the tab panes if we weren't told to ignore them and there's
12591299
// tab content data available
12601300
if (!ignoreTabPanes && hasTabContent) {
12611301
tabElements
1262-
.getNewElTabPane(tab, propNames, true) // true -> forceActiveTab
1302+
.getNewElTabPane(tab, propNames, options)
12631303
.appendTo($tabContent);
12641304
}
12651305
});
@@ -1277,6 +1317,8 @@
12771317
propNames: propNames,
12781318
ignoreTabPanes: ignoreTabPanes,
12791319
hasTabContent: hasTabContent,
1320+
tabsLiContent: settings.tabsLiContent,
1321+
tabsPostProcessors: settings.tabsPostProcessors,
12801322
scroller: $scroller
12811323
}
12821324
});
@@ -1336,6 +1378,8 @@
13361378
scrollToActiveTab */
13371379
function checkForTabAdded(refreshData) {
13381380
var updatedTabsArray = refreshData.updatedTabsArray,
1381+
updatedTabsLiContent = refreshData.updatedTabsLiContent || [],
1382+
updatedTabsPostProcessors = refreshData.updatedTabsPostProcessors || [],
13391383
propNames = refreshData.propNames,
13401384
ignoreTabPanes = refreshData.ignoreTabPanes,
13411385
options = refreshData.options,
@@ -1355,7 +1399,9 @@
13551399
isInitTabsRequired = true;
13561400

13571401
// add the tab, add its pane (if necessary), and refresh the scroller
1358-
$li = tabElements.getNewElTabLi(tab, propNames, options.forceActiveTab);
1402+
options.tabLiContent = updatedTabsLiContent[idx];
1403+
options.tabPostProcessor = updatedTabsPostProcessors[idx];
1404+
$li = tabElements.getNewElTabLi(tab, propNames, options);
13591405
tabUtils.storeDataOnLiEl($li, updatedTabsArray, idx);
13601406

13611407
if (isTabIdxPastCurrTabs) { // append to end of current tabs
@@ -1365,7 +1411,7 @@
13651411
}
13661412

13671413
if (!ignoreTabPanes && tab[propNames.content] !== undefined) {
1368-
$pane = tabElements.getNewElTabPane(tab, propNames, options.forceActiveTab);
1414+
$pane = tabElements.getNewElTabPane(tab, propNames, options);
13691415
if (isTabIdxPastCurrTabs) { // append to end of current tabs
13701416
$pane.appendTo($currTabContentPanesContainer);
13711417
} else { // insert in middle of current tabs
@@ -1638,6 +1684,8 @@
16381684
refreshData = {
16391685
options: options,
16401686
updatedTabsArray: instanceData.tabs,
1687+
updatedTabsLiContent: instanceData.tabsLiContent,
1688+
updatedTabsPostProcessors: instanceData.tabsPostProcessors,
16411689
propNames: instanceData.propNames,
16421690
ignoreTabPanes: instanceData.ignoreTabPanes,
16431691
$navTabs: $navTabs,
@@ -1846,6 +1894,8 @@
18461894
cssClassRightArrow: 'glyphicon glyphicon-chevron-right',
18471895
leftArrowContent: '',
18481896
rightArrowContent: '',
1897+
tabsLiContent: null,
1898+
tabsPostProcessors: null,
18491899
enableSwiping: false,
18501900
enableRtlSupport: false,
18511901
bootstrapVersion: 3

dist/jquery.scrolling-tabs.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/jquery.scrolling-tabs.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jquery-bootstrap-scrolling-tabs",
3-
"version": "2.2.1",
3+
"version": "2.3.1",
44
"description": "jQuery plugin for scrollable Bootstrap Tabs",
55
"homepage": "https://github.com/mikejacobson/jquery-bootstrap-scrolling-tabs",
66
"bugs": "https://github.com/mikejacobson/jquery-bootstrap-scrolling-tabs/issues",

run/data-driven.html

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@
3939
.st-demo-subheader:first-child {
4040
margin-top: 0;
4141
}
42+
43+
.custom-li a {
44+
color: darkblue !important;
45+
}
46+
47+
.custom-li-added a {
48+
color: darkred !important;
49+
}
4250
</style>
4351
</head>
4452

@@ -72,21 +80,33 @@
7280

7381

7482
var tabs = [
75-
{ paneId: 'tab00', title: 'Tab Index 0', content: 'Tab Index 0 Content', active: true, disabled: false },
76-
{ paneId: 'tab01', title: 'Tab Index 1', content: 'Tab Index 1 Content', active: false, disabled: false },
77-
{ paneId: 'tab02', title: 'Tab Index 2', content: 'Tab Index 2 Content', active: false, disabled: false },
78-
{ paneId: 'tab03', title: 'Tab Index 3', content: 'Tab Index 3 Content', active: false, disabled: false },
79-
{ paneId: 'tab04', title: 'Tab Index 4', content: 'Tab Index 4 Content', active: false, disabled: true },
80-
{ paneId: 'tab05', title: 'Tab Index 5', content: 'Tab Index 5 Content', active: false, disabled: false },
81-
{ paneId: 'tab06', title: 'Tab Index 6', content: 'Tab Index 6 Content', active: false, disabled: false },
82-
{ paneId: 'tab07', title: 'Tab Index 7', content: 'Tab Index 7 Content', active: false, disabled: false },
83-
{ paneId: 'tab08', title: 'Tab Index 8', content: 'Tab Index 8 Content', active: false, disabled: false },
84-
{ paneId: 'tab09', title: 'Tab Index 9', content: 'Tab Index 9 Content', active: false, disabled: false },
85-
{ paneId: 'tab10', title: 'Tab Index 10', content: 'Tab Index 10 Content', active: false, disabled: false },
86-
{ paneId: 'tab11', title: 'Tab Index 11', content: 'Tab Index 11 Content', active: false, disabled: false }
83+
{ paneId: 'tab00', tooltip: 'Custom Tooltip Tab 0', title: 'Tab Index 0', content: 'Tab Index 0 Content', active: true, disabled: false },
84+
{ paneId: 'tab01', tooltip: 'Custom Tooltip Tab 1', title: 'Tab Index 1', content: 'Tab Index 1 Content', active: false, disabled: false },
85+
{ paneId: 'tab02', tooltip: 'Custom Tooltip Tab 2', title: 'Tab Index 2', content: 'Tab Index 2 Content', active: false, disabled: false },
86+
{ paneId: 'tab03', tooltip: 'Custom Tooltip Tab 3', title: 'Tab Index 3', content: 'Tab Index 3 Content', active: false, disabled: false },
87+
{ paneId: 'tab04', tooltip: 'Custom Tooltip Tab 4', title: 'Tab Index 4', content: 'Tab Index 4 Content', active: false, disabled: true },
88+
{ paneId: 'tab05', tooltip: 'Custom Tooltip Tab 5', title: 'Tab Index 5', content: 'Tab Index 5 Content', active: false, disabled: false },
89+
{ paneId: 'tab06', tooltip: 'Custom Tooltip Tab 6', title: 'Tab Index 6', content: 'Tab Index 6 Content', active: false, disabled: false },
90+
{ paneId: 'tab07', tooltip: 'Custom Tooltip Tab 7', title: 'Tab Index 7', content: 'Tab Index 7 Content', active: false, disabled: false },
91+
{ paneId: 'tab08', tooltip: 'Custom Tooltip Tab 8', title: 'Tab Index 8', content: 'Tab Index 8 Content', active: false, disabled: false },
92+
{ paneId: 'tab09', tooltip: 'Custom Tooltip Tab 9', title: 'Tab Index 9', content: 'Tab Index 9 Content', active: false, disabled: false },
93+
{ paneId: 'tab10', tooltip: 'Custom Tooltip Tab 10', title: 'Tab Index 10', content: 'Tab Index 10 Content', active: false, disabled: false },
94+
{ paneId: 'tab11', tooltip: 'Custom Tooltip Tab 11', title: 'Tab Index 11', content: 'Tab Index 11 Content', active: false, disabled: false }
8795
],
8896
lastTabId = 11;
8997

98+
var tabsLiContent = tabs.map(function(tab) {
99+
return '<li role="presentation" title="' + tab.tooltip + '" data-trigger="hover" class="custom-li"></li>';
100+
});
101+
102+
var tabsPostProcessors = tabs.map(function(tab) {
103+
return function($li, $a) {
104+
$a.click(function() {
105+
console.log("anchor click! tab.tooltip: ", tab.tooltip);
106+
});
107+
};
108+
});
109+
90110

91111

92112
$(activate);
@@ -104,6 +124,8 @@
104124
scrollToTabEdge: false, // optional - pass in default value for demo purposes
105125
disableScrollArrowsOnFullyScrolled: true,
106126
enableSwiping: true,
127+
tabsLiContent: tabsLiContent,
128+
tabsPostProcessors: tabsPostProcessors,
107129
//widthMultiplier: 0.7,
108130
tabClickHandler: function () {
109131
console.log("click!! ", Date.now());
@@ -143,6 +165,7 @@
143165
function addTab() {
144166
var newTab = {
145167
paneId: 'tab' + (++lastTabId),
168+
tooltip: 'Custom Tooltab Tab ' + lastTabId,
146169
title: 'Tab Index ' + lastTabId,
147170
content: 'Tab Index ' + lastTabId + ' Content',
148171
active: true,
@@ -160,6 +183,12 @@
160183
});
161184

162185
tabs.push(newTab);
186+
tabsLiContent.push('<li role="presentation" title="' + newTab.tooltip + '" data-trigger="hover" class="custom-li-added"></li>');
187+
tabsPostProcessors.push(function($li, $a) {
188+
$a.click(function() {
189+
console.log("anchor click! tab.tooltip: ", newTab.tooltip);
190+
});
191+
});
163192

164193
$('.tabs-inside-here').scrollingTabs('refresh', {
165194
forceActiveTab: true // make our new tab active

src/js/api.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ $.fn.scrollingTabs.defaults = {
152152
cssClassRightArrow: 'glyphicon glyphicon-chevron-right',
153153
leftArrowContent: '',
154154
rightArrowContent: '',
155+
tabsLiContent: null,
156+
tabsPostProcessors: null,
155157
enableSwiping: false,
156158
enableRtlSupport: false,
157159
bootstrapVersion: 3

0 commit comments

Comments
 (0)