/hx-js

Collecting some javascript from HarvardX all in one place.

Primary LanguageJavaScript

Table of Contents generated with DocToc

HX-JS: HarvardX Standard Javascript and CSS

This project collects a large number of javascript and css tricks that have been used in various HX courses and puts them all in one place so that they're easier to implement.

Currently Working On...

Nothing! Current release is "stable."

Future Improvements

  • Various functionality additions.
  • Getting this to work globally throughout a course without needing to load it on each page.

How to Implement HXJS in your course

First, download HXJS_Helper.zip unzip it, and upload all of the things therein to your Files & Uploads section. This will let you use...

Also upload the three files from this repo:

  • hx.js, which puts all the javascript in one place
  • hx.css, which is all the css in one file
  • hxGlobalOptions.js, which sets the global options for hx.js

Once you've done that, copy the lines below into a Raw HTML element:

<script src="/static/hx.js"></script>
<link rel="stylesheet" type="text/css" href="/static/hx.css">

Or, if you're using the minified versions from hx-min.zip:

<script src="/static/hx-min.js"></script>
<link rel="stylesheet" type="text/css" href="/static/hx-min.css">

That will enable hx.js for all components on that page. It should be doing exactly nothing so far. You can test whether it's working by entering the Konami Code.

To make other things happen, you'll need to add specific classes to your HTML, and in some cases make little changes to your hxGlobalOptions.js file. Here's the full list of awesome stuff:

Simple Appearance Changes

All of these are classes that you add to various elements.

  • For drop caps that are text rather than an image, do <span class="hx-dropcap">A</span> on the first letter.
  • For small-caps headers, do class="hx-smallcaps". Works with h3 or h4.
  • For a superbold white header with a solid color background, do class="hx-superbold". You can do small caps with this.
  • For an underlined header, do class="hx-underline". You can do small caps with this.
  • For images or divs that hang down on the right-hand side, use class="hx-hangright".
  • For images or divs that hang down on the left-hand side, including image-based drop-caps, use class="hx-hangleft".
  • To get rid of the top navigation "ribbon" and bottom left/right buttons, add hxLocalOptions.collapsedNav = true; to a script tag on your page. Warning: By doing this you are intentionally removing students' ability to get to other units in this subsection. Only do this in subsections that have just a single unit.
  • To add a UTC clock on the right-hand side of the "pages" section, add hxLocalOptions.showClock = true; to a script tag on your page.

Pretty boxes

Blue boxes:

<div class="hx-bluebox">
  <h4>Box Header</h4>
  <p>Other things in box</p>
</div>

Red boxes:

<div class="hx-redbox">
  <h4>Box Header</h4>
  <p>Other things in box</p>
</div>

Grey (or gray) boxes:

<div class="hx-greybox">
  <h4>Box Header</h4>
  <p>Other things in box</p>
</div>

Sidebars (must combine with box style):

<div class="hx-sidebar">
  <h4>Box Header</h4>
  <p>Other things in box</p>
</div>

Quotation/excerpt boxes (should combine with greybox):

<div class="hx-excerpt">
  <h4 class="hx-smallcaps">Quotation Header</h4>
  <p>Actual honest-to-god quotation</p>
  <p class="hx-quote-source">Abraham Lincoln</p>
</div>

Sidebar Tables

Just give your table tag class="hx-hangleft" or class="hx-hangright" and it'll be ready to go. Note that you shouldn't do more than two columns, or three if your headers and data are very compact.

If you need a really compact table, add hx-compact-table to the class.

Automatic external link marker

In hxGlobalOptions, set markExternalLinks: true, in order to add FontAwesome external link markers to all links outside of edX. Note that links to other courses within edX will NOT currently get the markers.

Make You Smile

To make a little face at the bottom of each screen that smiles when you click on it, set makeSmiles: true in the hxGlobalSettings file.

Visibility Toggle

This part makes the button:

<p><button class="hx-togglebutton1">Toggle the sidebar on or off</button></p>

Then you match the number on -togglebutton# to your toggle target:

<div class="hx-toggletarget1 hx-sidebar">
  <p>I am all the stuff you want to toggle on and off.</p>
</div>

Button 1 toggles target 1, button 2 toggles target 2, etc.

Highlighter Toggle

This part makes the button:

<p><button class="hx-highlighter1">Highlight Important Things</button></p>

Match the number on -highlighter# with the class in the following code:

<span class="hx-highlight1">Thing To Highlight</span>

Each button highlights all the things with matching numbers. You don't need a different number for each highlight; you need a different number for each set of highlights.

Pop-ups for clickable images

You will need an image map already prepared. I recommend https://www.image-maps.com/ to create one quickly.

Here's an example:

<p class="hx-centered"><img src="https://placebear.com/500/300" alt="placeholder bear" usemap="#TheBearMap"/></p>

<map id="BearMap1" name="TheBearMap">
  <area id="Area1" class="Bear1 hx-popup-opener" title="Bear 1" shape="rect" coords="150,0,320,120" alt="Bear number one" />
  <area id="Area2" class="Bear2 hx-popup-opener" title="Bear 2" shape="rect" coords="90,120,350,300" alt="Bear number two" />
</map>

Note the classes, Bear1 and Bear2. You can name them anything you want, but they need to be the first class. The hx-popup-opener class is also necessary, but don't put it first. The javscript will then look for divs with matching classes. They need to be divs. Here's an example:

<div class="Bear1 hx-popup-content">
  <p>I am bear #1!</p>
</div>
<div class="Bear2 hx-popup-content">
  <p>I am bear #2!</p>
</div>

You can put them anywhere; they'll hide until you need them. When you click on the areas, the divs pop up.

Underneath, the javascript will automatically create a list with all of the targets, based on their "title" attribute. This list will also pop up the dialogs.

Automated Footnotes

First, make a Raw HTML component at the bottom of your page with this in it:

<h3>Footnotes</h3>

To insert the link to the footnote, use this format:

<span class="hx-footnote1">[1]</span>

Replace the number 1 with the appropriate number. They don't need to be in order, or even to be numbers, strictly speaking. Then, farther down, insert a div like this one:

<div class="hx-footnote-target1">
  <p>1. I am footnote number one.</p>
</div>

Make sure that the -target# at the end matches your -footnote# above.

You can put these divs anywhere; the javascript will move them to the end of the footnote component.

Image Slider

For an image slider, copy the HTML below and alter to fit your purposes. Keep the classes.

<div class="hx-sliderbox">
<div class="hx-slider">
<p><img src="https://placebear.com/300/300" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/250/250" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/180/180" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/150/150" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/240/240" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/240/240" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/240/240" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/240/240" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/100/100" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/200/200" alt="placeholder bear"/>Placeholder Bear</p>
<p><img src="https://placebear.com/200/200" alt="placeholder bear"/>Placeholder Bear</p>
</div>
</div>

For a paired slider, where the top one acts as the navigation for the bottom one, copy the HTML below and alter to fit. Keep the classes.

<div class="hx-sliderbox">
<div class="hx-navslider">
  <p><img src="/static/img1.png" alt="" height="120px" /></p>
  <p><img src="/static/img2.png" alt="" height="120px" /></p>
  <p><img src="/static/img3.png" alt="" height="120px" /></p>
  <p><img src="/static/img4.png" alt="" height="120px" /></p>
  <p><img src="/static/img5.png" alt="" height="120px" /></p>
  <p><img src="/static/img6.png" alt="" height="120px" /></p>
  <p><img src="/static/img7.png" alt="" height="120px" /></p>
  <p><img src="/static/img8.png" alt="" height="120px" /></p>
</div>

<div class="hx-bigslider">
  <p><a href="/static/img1.png" target="_blank"><img src="/static/img1.png" alt="" /></a>Comments on image 1</p>
  <p><a href="/static/img2.png" target="_blank"><img src="/static/img2.png" alt="" /></a>Comments on image 2</p>
  <p><a href="/static/img3.png" target="_blank"><img src="/static/img3.png" alt="" /></a>Comments on image 3</p>
  <p><a href="/static/img4.png" target="_blank"><img src="/static/img4.png" alt="" /></a>Comments on image 4</p>
  <p><a href="/static/img5.png" target="_blank"><img src="/static/img5.png" alt="" /></a>Comments on image 5</p>
  <p><a href="/static/img6.png" target="_blank"><img src="/static/img6.png" alt="" /></a>Comments on image 6</p>
  <p><a href="/static/img7.png" target="_blank"><img src="/static/img7.png" alt="" /></a>Comments on image 7</p>
  <p><a href="/static/img8.png" target="_blank"><img src="/static/img8.png" alt="" /></a>Comments on image 8</p>
</div>
</div>

Video Links

This one is a little complex. Look at the structure below, which you can copy to use as a template. Paste it into a Raw HTML component directly beneath your video.

<div id="hx-vidlinks-static-1" class="hx-vidlinks">

<div data-time="9">
	<a href="http://astronomy.fas.harvard.edu/people/dimitar-sasselov">
	<img src="/static/hx_tiny_white.png" />
	Dimitar Sasselov - Harvard University
	</a>
</div>

<div data-time="17">
	<a href="https://en.wikipedia.org/wiki/Solar_System">
	<img src="/static/hx_tiny_white.png" />
	Our Solar System - Wikipedia
	</a>
</div>

<div data-time="27">
	<a href="http://planetquest.jpl.nasa.gov/">
	<img src="/static/hx_tiny_white.png" />
	Exoplanets - NASA.gov
	</a>
</div>

</div>

The outer div has hx-vidlinks-static-1, because it's for video number one - the first one on the page. If I have a second video, it should say hx-vidlinks-static-2 and so forth.

The inner divs have data-time="9" where the 9 means the link is going to show up nine seconds into the video. You can also specify times in minutes:seconds format, or even hours:minutes:seconds.

The image inside is a little HX. It's 25 pixels tall. Feel free to replace it with a different image that's also 25 pixels tall.

The javascript will turn this set of divs into a list of static links, for folks who can't see or get to the pop-up links.

If you don't want to load this on a page, for instance on a page with a lot of videos that don't need links, you must set hxLocalOptions.dontLoadVideoStuff to true. You can't do this as a global option, because the global options are loaded along with the other scripts. It has to be done within the page.

Easter Egg

Up up down down left right left right B A

Jump To Time

Write a link that looks like this:

<a href="#video1" class="hx-vidtime" data-time="0:34">Go to 34 seconds</a>

The pound sign at the beginning of the href is a pound sign. The number at the end of the href tells us which video you want on the page (the top one is #1). The time can be given in hh:mm:ss format, or mm:ss, or just in seconds.

The link will jump you to the appropriate video, cue it up to the right time, and start it playing.

This will even work with /jump_to_id/ links! Just add the #video1 or #video2 or whatever at the end of URL.

Pop-up Assessments

This is a little complicated. First, make a Raw HTML component right above or below your video.

Then, make a <script> tag in that component and put a "timer" objet into it like so:

<script>
var HXPUPTimer = 
[
  {time: "8.5", title: "What Happened?"},
  {time: "4", title: "What Game?"},
  {time: "12", title: "What Was That?"},
  {time: "16", title: "Collision"},
  {time: "18", title: "Poll"}
];
</script>

The time can be in seconds, or in mm:ss, or hh:mm:ss format. The title is the exact name of one of the problems farther down on your page. It should work with any problem type except for Peer-Evaluated.

Then, add this block of HTML for your controls. You shouldn't need to change anything here.

<button id="hx-popUpPlayPause" aria-label="Start"><span id="hx-playpauseicon" class="hx-VQControls">&#8227;</span> <span id="hx-playpauseword">Play</span></button>
<button id="hx-popUpReset" aria-label="Answer Video Problems From Beginning"><span class="hx-VQControls">&#8617;</span> Restart</button>
<button id="hx-backOneProblem" aria-label="Go Back One Question"><span class="hx-VQControls">&#8676;</span> Back One</button>
<button id="hx-problemToggle" aria-label="Toggle Video Problems On/Off"><span id="hx-sunmoon" class="hx-VQControls">&#9788;</span> <span id="hx-onoff">Problems are On</span></button>

HX-js will do the rest!

To include items that do not have an h3 heading, such as a Word Cloud, make a small raw HTML component that includes the tag <span style="display:none" class="hx-includer">includenext</span>, and place that component directly before the one that you want to include. HX-js will display both items at once.

If you don't want to load this on a page, for instance on a page with a lot of videos that don't need pop-up videos, you must set hxLocalOptions.dontLoadVideoStuff to true. You can't do this as a global option, because the global options are loaded along with the other scripts. It has to be done within the page.

Automated Table of Contents for Long Pages

Either set makeTOC: true, in your hxGlobalOptions.js file, or put this little bit into a Raw HTML component on the page.

Warning: Once students see an Auto-TOC on one page, they'll see it on the rest of the pages in that subsection. You will probably want to set this to "true" or "false" manually on each page in a particular subsection.

<script>
var hxLocalOptions = {makeTOC: true};
</script>

This will auto-generate a hyperlinked table of contents from all visible h3 and h4 elements on your page, and drop it in the top-right-hand corner of the page.

Don't use this on pages where a video is the first thing. It will overlap and look ugly.

Automated External Link Markers

Either set markExternalLinks: true, in your hxGlobalOptions.js file, or put this little bit into a Raw HTML component on the page.

<script>
var hxLocalOptions = {markExternalLinks: false};
</script>

Every link that is not to an edx.org site will be marked with a box-and-arrow image to let students know that it's an external link. It's even accessible for screen readers! Naturally, this only works on pages where you have HX-JS enabled, so you may need to manually need to add it in a few places where javascript doesn't work (like the wiki).

Forum Tricks

Maybe you want in-page discussions, but you want them open right away so everyone can see all the different threads. Set openPageDiscussion: true, in your hxGlobalOptions.js file to automatically open every inline discussion as soon as someone comes to a page.

Future Features

Intro.js walkthroughs

(coming - but difficult.)

Audio Player

(coming - Luis is working on this.)

Full List of Preferences and Settings

The object below is the full set of default settings for hx-js. You can override these either by putting them into the hxGlobalOptions.js file (higher priority), or by putting this hxLocalOptions object into a raw HTML element on your page (highest priority).

<script>
var hxLocalOptions =  {
        // Table of Contents
        makeTOC: false,
        
        // Remove a lot of the navigation "chrome" - use only if you have just one page per unit.
        collapsedNav: false,

        // Remove the "Add a Post" button and/or auto-open the on-page discussions.
        removeAddPostButton: false,
        openPageDiscussion: false,

        // Marks all external links with an icon.
        markExternalLinks: false,

        // Highlighter: Yellow highlights that start turned off and go back to transparent afterward.
        highlightColor: '#ff0',
        highlightBackground: 'rgba(0,0,0,0)',
        highlightState: true,

        // Default options for the Slick image slider
        slickOptions: {
            arrows: true,
            dots: true,
            infinite: true,
            slidesToShow: 3,
            slidesToScroll: 3
        },
        // Default options for image slider navigation
        slickNavOptions: {
            asNavFor: '.hx-bigslider',
            variableWidth: true,
            focusOnSelect: true,
            slidesToShow: 3,
            slidesToScroll: 1
        },
        // Default options for single big image slider paired to nav.
        slickBigOptions: {
            asNavFor: '.hx-navslider',
            arrows: false,
            dots: true,
            fade: true,
            adaptiveHeight: true,
            slidesToShow: 1,
            slidesToScroll: 1
        },
        // Default options for pop-up problems
        PUPOptions: {
            width: 800,
            effect: 'fade',
            effectlength: 200,
            myPosition: 'center',
            atPosition: 'center',
            ofTarget: window
        },
        // Default options for in-video links
        VidLinkOptions: {
            hideLinkAfter: 5, //seconds
            effect: 'slide',
            hide: {'direction':'down'},
            show: {'direction':'down'},
            speed: 500,
            location: 'bl'  // Bottom Left. bl, br, tl, and tr are all ok.
        }
    };
</script>