-
-
Notifications
You must be signed in to change notification settings - Fork 982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework tabset-dropdown to use regular Bootstrap dropdowns #2054
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -1,5 +1,3 @@ | ||||||||||
|
||||||||||
|
||||||||||
/** | ||||||||||
* jQuery Plugin: Sticky Tabs | ||||||||||
* | ||||||||||
|
@@ -75,58 +73,155 @@ window.buildTabsets = function(tocID) { | |||||||||
var tabContent = $('<div class="tab-content"></div>'); | ||||||||||
$(tabs[0]).before(tabContent); | ||||||||||
|
||||||||||
// build the tabset | ||||||||||
var activeTab = 0; | ||||||||||
var activeTabIndex = 0; | ||||||||||
var activeDropdownTabIndex = 0; | ||||||||||
tabs.each(function(i) { | ||||||||||
|
||||||||||
// get the tab div | ||||||||||
var tab = $(tabs[i]); | ||||||||||
|
||||||||||
// get the id then sanitize it for use with bootstrap tabs | ||||||||||
var id = tab.attr('id'); | ||||||||||
|
||||||||||
// see if this is marked as the active tab | ||||||||||
if (tab.hasClass('active')) | ||||||||||
activeTab = i; | ||||||||||
var tabId = tab.attr('id'); | ||||||||||
|
||||||||||
// remove any table of contents entries associated with | ||||||||||
// this ID (since we'll be removing the heading element) | ||||||||||
$("div#" + tocID + " li a[href='#" + id + "']").parent().remove(); | ||||||||||
$("div#" + tocID + " li a[href='#" + tabId + "']").parent().remove(); | ||||||||||
|
||||||||||
// sanitize the id for use with bootstrap tabs | ||||||||||
id = id.replace(/[.\/?&!#<>]/g, '').replace(/\s/g, '_'); | ||||||||||
tab.attr('id', id); | ||||||||||
tabId = tabId.replace(/[.\/?&!#<>]/g, '').replace(/\s/g, '_'); | ||||||||||
tab.attr('id', tabId); | ||||||||||
|
||||||||||
// get the heading element within it, grab it's text, then remove it | ||||||||||
var heading = tab.find('h' + tabLevel + ':first'); | ||||||||||
var headingText = heading.html(); | ||||||||||
heading.remove(); | ||||||||||
var tabHeading = tab.find('h' + tabLevel + ':first'); | ||||||||||
var tabHeadingText = tabHeading.html(); | ||||||||||
tabHeading.remove(); | ||||||||||
|
||||||||||
// build and append the tab list item | ||||||||||
var a = $('<a role="tab" data-toggle="tab">' + headingText + '</a>'); | ||||||||||
a.attr('href', '#' + id); | ||||||||||
a.attr('aria-controls', id); | ||||||||||
var li = $('<li role="presentation"></li>'); | ||||||||||
li.append(a); | ||||||||||
tabList.append(li); | ||||||||||
|
||||||||||
// set it's attributes | ||||||||||
tab.attr('role', 'tabpanel'); | ||||||||||
tab.addClass('tab-pane'); | ||||||||||
tab.addClass('tabbed-pane'); | ||||||||||
if (fade) | ||||||||||
tab.addClass('fade'); | ||||||||||
// see if this is marked as the active tab, or set the first tab by | ||||||||||
// default | ||||||||||
if (tab.hasClass('active')) { | ||||||||||
activeTabIndex = i; | ||||||||||
} | ||||||||||
|
||||||||||
// check if this is a dropdown tab and process it accordingly | ||||||||||
var dropdown = tab.hasClass("tabset-dropdown"); | ||||||||||
if (dropdown) { | ||||||||||
li.addClass('dropdown'); | ||||||||||
|
||||||||||
// build and append the dropdown toggle | ||||||||||
var a = $('<a class="dropdown-toggle" data-toggle="dropdown" href="#">' | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
as in bootstrap doc - I think it is better for accessibility |
||||||||||
+ tabHeadingText | ||||||||||
+ ' <span class="caret"></span></a>'); | ||||||||||
li.append(a); | ||||||||||
|
||||||||||
// build and append the dropdown menu | ||||||||||
var dropdownMenu = $('<ul class="dropdown-menu"></ul>'); | ||||||||||
li.append(dropdownMenu) | ||||||||||
|
||||||||||
// determine the heading level of the dropdown tabs | ||||||||||
var match = tab.attr('class').match(/level(\d) /); | ||||||||||
if (match === null) | ||||||||||
return; | ||||||||||
var dropdownLevel = Number(match[1]); | ||||||||||
var dropdownTabLevel = dropdownLevel + 1; | ||||||||||
|
||||||||||
// find all subheadings immediately below | ||||||||||
var dropdownTabs = tab.find("div.section.level" + dropdownTabLevel); | ||||||||||
if (!dropdownTabs.length) | ||||||||||
return; | ||||||||||
|
||||||||||
dropdownTabs.each(function(j) { | ||||||||||
|
||||||||||
// get the dropdown tab div | ||||||||||
var dropdownTab = $(dropdownTabs[j]); | ||||||||||
|
||||||||||
// get the id then sanitize it for use with bootstrap tabs | ||||||||||
var dropdownId = dropdownTab.attr('id'); | ||||||||||
|
||||||||||
// remove any table of contents entries associated with | ||||||||||
// this ID (since we'll be removing the heading element) | ||||||||||
$("div#" + tocID + " li a[href='#" + dropdownId + "']") | ||||||||||
.parent().remove(); | ||||||||||
|
||||||||||
// sanitize the id for use with bootstrap tabs | ||||||||||
dropdownId = dropdownId | ||||||||||
.replace(/[.\/?&!#<>]/g, '') | ||||||||||
.replace(/\s/g, '_'); | ||||||||||
dropdownTab.attr('id', dropdownId); | ||||||||||
|
||||||||||
// get the heading element within it, grab it's text, then remove it | ||||||||||
var dropdownHeading = dropdownTab | ||||||||||
.find('h' + dropdownTabLevel + ':first'); | ||||||||||
var dropdownHeadingText = dropdownHeading.html(); | ||||||||||
dropdownHeading.remove(); | ||||||||||
|
||||||||||
// build and append the dropdown tab list item | ||||||||||
var dropdownLi = $('<li role="presentation"></li>'); | ||||||||||
dropdownMenu.append(dropdownLi); | ||||||||||
Comment on lines
+142
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we make a JS function as this is the same process as for other tabs above but with different parameter ? Refactoring would help later maintaining |
||||||||||
|
||||||||||
// see if this is marked as the active tab | ||||||||||
if (dropdownTab.hasClass('active')) { | ||||||||||
activeTabIndex = i; | ||||||||||
activeDropdownTabIndex = j; | ||||||||||
} | ||||||||||
|
||||||||||
// move it into the tab content div | ||||||||||
tab.detach().appendTo(tabContent); | ||||||||||
// build and append the dropdown tab link | ||||||||||
var dropdownA = $('<a role="tab" data-toggle="tab">' | ||||||||||
+ dropdownHeadingText | ||||||||||
+ '</a>'); | ||||||||||
dropdownA.attr('href', '#' + dropdownId); | ||||||||||
dropdownA.attr('aria-controls', dropdownId); | ||||||||||
dropdownLi.append(dropdownA); | ||||||||||
|
||||||||||
// set its attributes | ||||||||||
dropdownTab.attr('role', 'tabpanel'); | ||||||||||
dropdownTab.addClass('tab-pane'); | ||||||||||
dropdownTab.addClass('tabbed-pane'); | ||||||||||
if (fade) | ||||||||||
dropdownTab.addClass('fade'); | ||||||||||
|
||||||||||
// move it into the tab content div | ||||||||||
dropdownTab.detach().appendTo(tabContent); | ||||||||||
}); | ||||||||||
} else { | ||||||||||
// build and append the tab link | ||||||||||
var a = $('<a role="tab" data-toggle="tab">' + tabHeadingText + '</a>'); | ||||||||||
Comment on lines
+190
to
+191
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Same as above |
||||||||||
a.attr('href', '#' + tabId); | ||||||||||
a.attr('aria-controls', tabId); | ||||||||||
li.append(a); | ||||||||||
|
||||||||||
// set its attributes | ||||||||||
tab.attr('role', 'tabpanel'); | ||||||||||
tab.addClass('tab-pane'); | ||||||||||
tab.addClass('tabbed-pane'); | ||||||||||
if (fade) | ||||||||||
tab.addClass('fade'); | ||||||||||
|
||||||||||
// move it into the tab content div | ||||||||||
tab.detach().appendTo(tabContent); | ||||||||||
} | ||||||||||
}); | ||||||||||
|
||||||||||
// set active tab | ||||||||||
$(tabList.children('li')[activeTab]).addClass('active'); | ||||||||||
var active = $(tabContent.children('div.section')[activeTab]); | ||||||||||
active.addClass('active'); | ||||||||||
// set active dropdown item | ||||||||||
var activeTab = $(tabList.children('li')[activeTabIndex]) | ||||||||||
activeTab.addClass('active'); | ||||||||||
var contentTabID = activeTab.children('a').attr('aria-controls'); | ||||||||||
|
||||||||||
// set active dropdown tab if necessary | ||||||||||
if (activeTab.hasClass("dropdown")) { | ||||||||||
var activeDropdownTab = $(activeTab.find('li')[activeDropdownTabIndex]); | ||||||||||
activeDropdownTab.addClass('active'); | ||||||||||
|
||||||||||
var contentTabID = activeDropdownTab.children('a').attr('aria-controls'); | ||||||||||
} | ||||||||||
|
||||||||||
// set active content tab | ||||||||||
$('#'+contentTabID).addClass('active'); | ||||||||||
if (fade) | ||||||||||
active.addClass('in'); | ||||||||||
$('#'+contentTabID).addClass('in'); | ||||||||||
|
||||||||||
if (tabset.hasClass("tabset-sticky")) | ||||||||||
tabset.rmarkdownStickyTabs(); | ||||||||||
|
@@ -138,4 +233,3 @@ window.buildTabsets = function(tocID) { | |||||||||
buildTabset($(tabsets[i])); | ||||||||||
}); | ||||||||||
}; | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is comestic maybe but I would put this variable with the others defined above (l. 54) so that all variables are based on class are in the same place in code