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

Commit d4aff39

Browse files
committed
Merge pull request #33 from riknos314/tabbedPR
Ported tabbedStuff to be RSE-0001 complient
2 parents c4103c4 + 5ea531e commit d4aff39

File tree

5 files changed

+268
-68
lines changed

5 files changed

+268
-68
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function RunestoneBase () { // Basic parent stuff
2+
3+
}
4+
5+
RunestoneBase.prototype.logBookEvent = function (info) {
6+
console.log("logging event " + this.divid);
7+
};
8+
9+
RunestoneBase.prototype.logRunEvent = function (info) {
10+
console.log("running " + this.divid);
11+
};

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

0 commit comments

Comments
 (0)