curvy-tabs-pager
v2.2.0
Published
Paged content for curvy-tabs tab bar
Readme
curvy-tabs-pager
Injects a user control for controlling paged tab bar content:

The main tab (typically the first tab) contains an <iframe> element that hosts the pages. Each page may contain <div>s with markup for other tabs with <iframe> elements to create the effect of paging a whole set of tabs in parallel. Tabs with no matching <div> are hidden, hence “conditional tabs.”
Synopsis
Paging tab bar consists of (in any order):
- The paging user control panel (required)
- A main paging tab (required) - Tab A in this case
- Represented by
<div><iframe></iframe><div>- loaded by the pager with markup for itself and other paging tabs - The main frame is the first such tab whose
<iframe>has nosrcattribute
- Represented by
- Zero or more static tabs (optional)
- Represent by
<div>arbitrary static content</div> - May include an
<iframe>but it must have asrcattribute (to differentiate it from the main tab)
- Represent by
- Zero or more conditional paging tabs (optional)
- Must have class
curvy-tab-conditional - Content of these tabs is included in main tab's markup in a similar element (same
classandnameattributes) - When no such element is found in main tab's markup, this tab is hidden
- Must have class
Markup
<div id="page-panel" style="position:absolute; top:48px; right:24px;">
<!-- Injected with the paging user control. -->
</div>
<div class="curvy-tabs-container">
<div style="background-color:lightblue" name="Tab A">
<!-- This is the main paging tab: Always visible. Has an `<iframe>` with no initial `src` value. -->
<iframe></iframe>
<!-- This `<iframe>`'s markup may (or may not) include divs with content for conditional tabs. -->
</div>
<div style="background-color:lightcyan" name="Notes">
This is a tab with static content (no iframe).
There may be 0 or more of these peppered throughout.
While Tab A's content (and hence and Tab B's content) pages, this tab stays the same.
</div>
<div class="curvy-tab-conditional" style="background-color:lightcyan" name="Tab B">
<!--
This is a conditional tab.
There may be 0 or more of these peppered throughout.
It is paged in parallel with the main tab.
Content comes from element in the markup of the main tab with same `class` and `name` as the tab.
If no such element is found in the main tab's markup, the tab is hidden.
-->
<iframe src="blank.html"></iframe>
</div>
</div>Instantiate the pager
var options = { toc, maxPage, startPage, path }; // required: toc or maxPage
var myPager = new CurvyTabsPager(pagerContainer, tabbedContent, options);- Injects a
<style>element into<head>which:- styles paging user control
- stretches
<iframe>to fit tab content area
- Injects the paging user control markup into given container element
pagerContainer - Wires the user control up to the
CurvyTabstab bar given intabbedContent
See the CurvyTabsPager constructor in the API section below for more details.
In addition to the user interacting with the paging user control, the myPager.page(pageNumberOrName) method may be called to programmatically switch between pages.
Main tab page script
Pages loaded into the main tab’s <iframe> must register with the pager in the parent window:
parent.dispatchEvent(new CustomEvent('curvy-tabs-pager-register', { detail: { window: window }}));Note: This module injects the
CustomEventpolyfill required by IE 11.
Conditional tab iframe source markup
Conditional tabs typically source a local blank.html that <link>s to a local CSS stylesheet to style the page content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="myPageContentStylesheet.css">
</head>
</html>Main tab’s markup for conditional tab content
For each conditional tab to be shown, markup is placed in an element in the main tab’s page with the same class and name as the tab:
<div class="curvy-tab-conditional" name="Tab B">
This markup is copied to Tab B's `<iframe>`'s `<body>`!
</div>Because there’s no <div class="curvy-tab-conditional" name="Tab C">…</div> in this example markup, Tab C is hidden.
Description
Constructor
The CurvyTabsPager constructor creates a user control which it injects into the given pagerContainer element. This lets the user navigate pages which are displayed in multiple tabs of a CurvyTabs tab bar (given in the tabbedContent parameter).
The page’s filenames are given in the options.toc array. These filenames are prefixed with the path given in options.path. Table of contents is optional. If not given, files are referenced by page number instead: path/1.html, path/2.html, etc., through page options.maxPage (which must be given when options.toc is not).
The first page shown is the page number or page name in options.startPage. If not given, loads the first page listed in the table of contents. If there’s no table of contents, loads page path/1.html.
User control interface
The paging user control features:
- Previous page and next page icons;
- a range control (slider);
- displays page number as "Page m of n"; and
- listeners for
ArrowLeftandArrowRightkeydown events.
Pages
The start page is loaded into the main tab’s <iframe> as described above.
All pages loaded into the main tab must register with the parent window as shown in the synopsis above. That line would typically be included in a common script loaded by all pages. The registration forwards ArrowLeft and ArrowRight keyboard events to the pager and processes conditional tab content.
Conditional tabs
As outlined above, all content for all conditional tabs is included in the main tab's markup. The main tab’s <iframe> is loaded by the HTTP response. The conditional tab(s) (e.g., <div class="curvy-tab-conditional" name="Tab Name">...</div>) are loaded programmatically with the contents of hidden elements with same class and name found in the main tab. These tabs are become visible; all other conditional tabs are hidden.
Dependency
The constructor takes a CurvyTabs object (v2.3.1 or higher) as a required second parameter (tabbedContent in the synopsis above).
Distribution
Published in two formats:
- An npm module published on the npm Registry (npmjs.org), for developer use at build time:
var CurvyTabsPager = require('curvy-tabs-pager'); - A script to be loaded by the client at run-time (sets global
CurvyTabsPager), either of:
Any SEMVER string can be used.<script src="https://unpkg.com/[email protected]/umd/curvy-tabs-pager.js"></script> <script src="https://unpkg.com/[email protected]/umd/curvy-tabs-pager.min.js"></script>2.0in the above means load the latest of the 2.0.* range. See the npm semver calculator and npm’s semantic versioning page.
API
CurvyTabsPager constructor
Given a curvy-tabs instance:
var tabbedContentContainer = document.querySelector('.curvy-tabs-container'); // or whatever
var tabbedContent = new CurvyTabs(tabbedContentContainer);
tabBar.paint();The following instantiates a CurvyTabsPager object (values are illustrative):
var pagerContainer = document.getElementById('page-panel');
var options = { // required: toc or maxPage; the rest are optional
toc: ['Synopsis.html', 'Description.html', 'See Also.html'],
maxPage: 3, // iff `toc` given, means file names are 1.html, 2.html, 3.html
startPage: 12, // may be page number or file name (default: first page)
path: 'content/', // default = no path prefixed (synonym: `subfolder`)
cookieName: 'page', // falsy value means don’t set cookie at all (default: 'p')
autoSwitch: false // falsy means don’t switch to main tab on new page (default: true)
};
var myPager = new CurvyTabsPager(
pagerContainer, // required
tabbedContent, // required
options // required; must have `toc` or `maxPage`
);Note that path, cookieName, and autoSwitch are instance vars that can also be set after instantiation.
CurvyTabs.prototype.getPageNum(pageNumberOrName) method
Accepts either:
- A 1-based integer page number (or string representation thereof); or
- A filename listed in the table of contents array
Returns:
- Integer page number
- 0 if given integer is out of range or given filename not found in table of contents
Examples:
myPager.getPageNum(2); // returns 2
myPager.getPageNum('2'); // returns 2
myPager.getPageNum('99'); // returns 0 (out of range)
myPager.getPageNum('-3'); // returns 0 (out of range)
myPager.getPageNum('Description.html'); // returns 2 (not integer but found in ToC)
myPager.getPageNum('Splat.html'); // returns 0 (not integer AND not found in ToC)
myPager.getPageNum('2.5'); // returns 0 (not integer AND not found in ToC either)CurvyTabs.prototype.page(pageNumberOrName, path) method
To go to a page programmatically:
myPager.page(2); // go to 2nd page (1-based)
myPager.page('Description.html'); // also goes to 2nd pageThis method performs the following actions:
- Navigate iframe to the new page
- Display new page number
- Disable fist and previous page icons iff first page
- Disable next and final page icons iff last page
- Reposition range control
- Switch to main tab iff
autoSwitchproperty is truthy (which is the default) - Copy conditional tab content to conditional tabs and shows/hides them as needed
Fails silently if page does not exist.
Button elements
The following instance variables reference DOM elements:
Variable | Description
-------- | -----------
myPager.goFirstEl | First page button
myPager.goPrevEl | Next page button
myPager.goNextEl | Previous page button
myPager.goLastEl | Final page button
myPager.sliderEl | Page range control
myPager.numEl | Current page number
myPager.maxEl | Final page number
For example, to hide the first and final buttons:
myPager.goFirstEl.style.display = myPager.goLastEl.style.display = 'none';CurvyTabsPager.version static property
Contains the version string 2.2.0 (major.minor.patch with no leading v).
CurvyTabsPager.stylesheet and CurvyTabsPager.html static properties
The stylesheet and the markup to be injected may be overridden if desired by setting these static properties before instantiation.
Events
curvy-tabs-pager-paged
Dispatched to pager container on paging.
See Also
Version History
2.2.0- Add
autoSwitchproperty and instantiation option - Remove
CustomEventpolyfill because its now installed incurvy-tabs
- Add
2.1.0- Dispatch event
curvy-tabs-pager-pagedto pager container element on page transitions - Add
CustomEventpolyfill for IE 11
- Dispatch event
2.0.7- IE 11 issue: Avoid 2-param overload of DOMTokenList.prototype.toggle
2.0.6- Substitute
25c4for25c0on Windows to get a better "previous" and "first" (left arrow) icons
- Substitute
2.0.5- Add first page and last page buttons
- Document instance variables that reference DOM elements
- Retire
page-button-enabled-nextandpage-button-enabled-prevCSS classes
2.0.4- Update README.md with correct
<script>tag snippet
- Update README.md with correct
2.0.3- Update build.sh to create
umdfolder forunpkg.comCDN support for this and all future versions. See revised installation snippet above. (curvy-tabs-pager.github.iowill no longer be updated with new versions, although previous versions will remain there.)
- Update build.sh to create
2.0.2(9/26/2018)options.startPagenow correctly accepts a page file name (as well as a page number)- As user pages through tutorial, browser's query string is updated with
?p=n(where n = page number)
2.0.1(9/13/2018)- Fix defect in copying conditional tab content
- Rename
options.subfoldertooptions.path(howeveroptions.subfolderis still accepted for backwards compatibility)
2.0.0(9/12/2018)- Remove
toc,startPage, andsubfolderinstantiation parameters in favor of a singleoptionsobject parameter with those keys - Add
options.maxPagewhich can be given in place ofoptions.tocin which case file names are the page numbers themselves (path/1.html,path/2.html, etc.)
- Remove
1.0.0(9/11/2018)- Initial release
