Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit 7da3589

Browse files
committed
preparing tabbed for PR
1 parent 2345e3a commit 7da3589

File tree

4 files changed

+268
-68
lines changed

4 files changed

+268
-68
lines changed

runestone/tabbedStuff/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<h2>Tabbed Stuff</h2>
2+
3+
```html
4+
<div data-component="tabbedStuff" id="tabbedstuff1">
5+
<div data-component="tab" data-tabname="Tab 1">
6+
Stuff in tab 1.
7+
</div>
8+
<div data-component="tab" data-tabname="Tab 2">
9+
Stuff in tab 2.
10+
</div>
11+
<div data-component="tab" data-inactive data-tabname="Tab 3">
12+
Stuff in tab 3.
13+
</div>
14+
</div>
15+
```
16+
17+
Here the <code>div</code> tag represents the entire Tabbed Stuff component to be rendered.
18+
Each Tabbed Stuff component contains a series of Tab components, which are also <code>div</code> elements.
19+
Each Tab component can contain anything from text to other working components such as Multiple Choice, Activecode, etc.
20+
By default, the first tab is opened on page load, but this can be changed by the presence of <code>data-inactive</code> in the Tabbed Stuff tag or <code>data-active</code> in one of the tabs.
21+
22+
Option spec:
23+
24+
<ul>
25+
<li><code>data-component="tabbedStuff"</code> Identifies this as a Tabbed Stuff component</li>
26+
<li><code>id</code> Must be unique in the document</li>
27+
<li><code>data-inactive</code> Ensures that no tabs are open by default on page load--this overrides any data-active attribute in a tab tag.</li>
28+
</ul>
29+
30+
Option spec for each tab:
31+
32+
<ul>
33+
<li><code>data-component="tab"</code> Identifies this as a Tab component</li>
34+
<li><code>data-tabname</code> This is the text that appears on the top of the tab that users can click to open the tab.</li>
35+
<li><code>data-active</code> Specifies this tab to be opened on page load--only one per Tabbed Stuff component, and is overridden by the presence of <code>data-inactive</code> in the Tabbed Stuff tag. The default tab to be opened on page load is the first tab.</li>
36+
</ul>

runestone/tabbedStuff/css/tabbedstuff.css

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* Styles for the Runestone tabbed exhibit directive */
2-
31
.tab-pane {
42
padding: 20px 15px 10px 15px;
53
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*==========================================
2+
======= Master tabbedstuff.js ========
3+
============================================
4+
=== This file contains the JS for ===
5+
=== the Runestone tabbedStuff component. ===
6+
============================================
7+
=== Created by ===
8+
=== Isaiah Mayerchak ===
9+
=== 06/15/15 ===
10+
==========================================*/
11+
function RunestoneBase () { // Parent function
12+
13+
}
14+
15+
RunestoneBase.prototype.logBookEvent = function (info) {
16+
console.log("logging event " + this.divid);
17+
};
18+
19+
RunestoneBase.prototype.logRunEvent = function (info) {
20+
console.log("running " + this.divid);
21+
};
22+
23+
var TSList = {}; // Dictionary that contains all instances of TabbedStuff objects
24+
25+
TabbedStuff.prototype = new RunestoneBase();
26+
27+
// Define TabbedStuff object
28+
function TabbedStuff (opts) {
29+
if (opts) {
30+
this.init(opts);
31+
}
32+
}
33+
34+
/*===========================================
35+
== Initialize basic TabbedStuff attributes ==
36+
===========================================*/
37+
38+
TabbedStuff.prototype.init = function (opts) {
39+
RunestoneBase.apply(this, arguments);
40+
var orig = opts.orig;
41+
this.origElem = orig; // entire original <div> element that will be replaced by new HTML
42+
this.divid = orig.id;
43+
44+
this.inactive = false;
45+
if ($(this.origElem).is("[data-inactive]")) {
46+
this.inactive = true;
47+
}
48+
49+
this.togglesList = []; // For use in Codemirror/Disqus
50+
this.childTabs = [];
51+
this.populateChildTabs();
52+
53+
this.activeTab = 0; // default value--activeTab is the index of the tab that starts open
54+
this.findActiveTab();
55+
56+
this.createTabContainer();
57+
58+
};
59+
60+
/*===========================================
61+
== Update attributes of instance variables ==
62+
== variables according to specifications ==
63+
===========================================*/
64+
65+
TabbedStuff.prototype.populateChildTabs = function () { // Populate this.childTabs with all child nodes that have the data-component='tab' attribute
66+
for (var i = 0; i < this.origElem.childNodes.length; i++) {
67+
if ($(this.origElem.childNodes[i]).data("component") === "tab") {
68+
this.childTabs.push(this.origElem.childNodes[i]);
69+
}
70+
}
71+
};
72+
73+
TabbedStuff.prototype.findActiveTab = function () { // Checks to see if user has specified a tab to be active on pageload
74+
for (var i = 0; i < this.childTabs.length; i++) {
75+
if ($(this.childTabs[i]).is("[data-active]")) {
76+
this.activeTab = i;
77+
}
78+
}
79+
};
80+
81+
/*==========================================
82+
== Creating/appending final HTML elements ==
83+
==========================================*/
84+
85+
TabbedStuff.prototype.createTabContainer = function () { // First create a container div
86+
this.replacementDiv = document.createElement("div");
87+
this.replacementDiv.id = this.divid;
88+
$(this.replacementDiv).addClass("alert alert-warning");
89+
$(this.replacementDiv).attr({"role": "tabpanel"});
90+
91+
this.tabsUL = document.createElement("ul");
92+
this.tabsUL.id = this.divid + "_tab";
93+
$(this.tabsUL).addClass("nav nav-tabs");
94+
$(this.tabsUL).attr({"role": "tablist"});
95+
96+
this.tabContentDiv = document.createElement("div"); // Create tab content container that holds tab panes w/content
97+
$(this.tabContentDiv).addClass("tab-content");
98+
99+
this.createTabs(); // create and append tabs to the <ul>
100+
101+
this.replacementDiv.appendChild(this.tabsUL);
102+
this.replacementDiv.appendChild(this.tabContentDiv);
103+
104+
this.addCMD(); // Adds fuctionality for Codemirror/Disqus
105+
106+
$(this.origElem).replaceWith(this.replacementDiv);
107+
};
108+
109+
TabbedStuff.prototype.createTabs = function () {
110+
// Create tabs in format <li><a><span></span></a></li> to be appended to the <ul>
111+
for (var i = 0; i < this.childTabs.length; i++) {
112+
// First create tabname and tabfriendly name that has no spaces to be used for the id
113+
var tabListElement = document.createElement("li");
114+
$(tabListElement).attr({
115+
"role": "presentation",
116+
"aria-controls": this.divid + "-" + i
117+
});
118+
// Using bootstrap tabs functionality
119+
var tabElement = document.createElement("a");
120+
$(tabElement).attr({
121+
"data-toggle": "tab",
122+
"href": "#" + this.divid + "-" + i,
123+
"role": "tab"
124+
});
125+
var tabTitle = document.createElement("span"); // Title of tab--what the user will see
126+
tabTitle.textContent = $(this.childTabs[i]).data("tabname");
127+
128+
tabElement.appendChild(tabTitle);
129+
tabListElement.appendChild(tabElement);
130+
this.tabsUL.appendChild(tabListElement);
131+
132+
// tabPane is what holds the contents of the tab
133+
var tabPaneDiv = document.createElement("div");
134+
tabPaneDiv.id = this.divid + "-" + i;
135+
$(tabPaneDiv).addClass("tab-pane");
136+
$(tabPaneDiv).attr({
137+
"role": "tabpanel"
138+
});
139+
//var tabHTML = $(this.childTabs[i]).html();
140+
//$(tabPaneDiv).html(tabHTML);
141+
142+
tabPaneDiv.appendChild(this.childTabs[i]);
143+
144+
if (!this.inactive) {
145+
if (this.activeTab === i) {
146+
$(tabListElement).addClass("active");
147+
$(tabPaneDiv).addClass("active");
148+
}
149+
}
150+
this.togglesList.push(tabElement);
151+
this.tabContentDiv.appendChild(tabPaneDiv);
152+
}
153+
};
154+
155+
/*===================================
156+
== Codemirror/Disqus functionality ==
157+
===================================*/
158+
TabbedStuff.prototype.addCMD = function () {
159+
$(this.togglesList).on("shown.bs.tab", function (e) {
160+
var content_div = $(e.target.attributes.href.value);
161+
content_div.find(".disqus_thread_link").each(function () {
162+
$(this).click();
163+
});
164+
165+
content_div.find(".CodeMirror").each(function (i, el) {
166+
el.CodeMirror.refresh();
167+
});
168+
});
169+
};
170+
171+
/*=================================
172+
== Find the custom HTML tags and ==
173+
== execute our code on them ==
174+
=================================*/
175+
$(document).ready(function () {
176+
$("[data-component=tabbedStuff]").each(function (index) {
177+
TSList[this.id] = new TabbedStuff({"orig": this});
178+
});
179+
});

0 commit comments

Comments
 (0)