Skip to content

Commit 63990fd

Browse files
committed
Initial commit
0 parents  commit 63990fd

9 files changed

Lines changed: 245 additions & 0 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Float, LLC
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

ReadMe.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
adapt-next-button
2+
=================
3+
The **Next Page Button** provides a button for easily navigating to the next page in an Adapt course.
4+
5+
Settings
6+
--------
7+
### Attributes
8+
**_component (string)**: This value must be: `next-button`.
9+
10+
**displayTitle (string)**: The title to display on the button.
11+
12+
**_classes (string)**: CSS class name to be applied to the button's containing div. The class must be predefined in one of the Less files. Separate multiple classes with a space.
13+
14+
**_layout (string)**: This defines the horizontal position of the component in the block. Acceptable values are full, left or right.
15+
16+
**_hoverText (string, optional):** This optional text appears when the user hovers over the next button.
17+
18+
**_requirePageCompletion (boolean, default=true):** By default, the next button is disabled until the rest of the page is complete. However, you can set the next button to always be enabled by setting this to `false`.
19+
20+
**_nextPage (string, optional)**: This component automatically determines the next page based on the structure of the course. However, if you want to explicitly set the next page, you can set the ID of the page here.
21+
22+
Limitations
23+
-----------
24+
No known limitations.
25+
26+
-----------
27+
The **Next Page Button** is a plugin for the Adapt Framework. [Adapt](https://www.adaptlearning.org) is a free and easy to use e-learning authoring tool that creates fully responsive, multi-device, HTML5 e-learning content using the award-winning Adapt developer framework.

bower.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "adapt-next-button",
3+
"version": "0.9.0",
4+
"framework": "^2.0.0",
5+
"authors": [
6+
"Daniel Pfeifffer <dpfeiffer@gowithfloat.com>"
7+
],
8+
"main": "/js/adapt-next-button.js",
9+
"component": "next-button",
10+
"displayName": "Next Page Button",
11+
"description": "Provides a button for easily navigating to the next page in an Adapt course",
12+
"keywords": [
13+
"adapt-plugin",
14+
"adapt-component"
15+
],
16+
"license": "MIT",
17+
"targetAttribute": "_nextButton",
18+
"homepage": "",
19+
"ignore": [
20+
"**/.*",
21+
"node_modules",
22+
"bower_components",
23+
"test",
24+
"tests"
25+
]
26+
}

example.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"_id":"c-30",
3+
"_parentId":"b-05",
4+
"_type":"component",
5+
"_component":"next-button",
6+
"_classes":"",
7+
"_layout":"left",
8+
"title": "Button",
9+
"displayTitle": "Button",
10+
"label": "Button Label (optional)",
11+
"instruction": "Instructions (optional)",
12+
"_hoverText": "Text displayed when hovering over the button",
13+
"_requirePageCompletion": true
14+
}

js/adapt-next-button.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
define([
2+
"coreJS/adapt",
3+
"coreViews/componentView",
4+
"./get-next-page"
5+
], function(Adapt, ComponentView, getNextPage) {
6+
var NextButton = ComponentView.extend({
7+
preRender: function() {
8+
var page = this.model.findAncestor();
9+
page.on("change:_isComplete", _.bind(this.onPageCompletionUpdate, this));
10+
11+
if (!this.model.has("_requirePageCompletion")) {
12+
this.model.set("_requirePageCompletion", true);
13+
}
14+
15+
if (!this.model.has("_nextPage") || this.model.get("_nextPage").length === 0) {
16+
var nextPage = getNextPage(page);
17+
if (nextPage) {
18+
this.model.set("_nextPage", nextPage.get("_id"));
19+
}
20+
}
21+
},
22+
23+
postRender: function() {
24+
this.setReadyStatus();
25+
26+
// In case the next button is not marked as optional,
27+
// mark it complete right away so that the button is waiting
28+
// on itself to become complete.
29+
this.setCompletionStatus();
30+
},
31+
32+
/**
33+
* Invoked when a change is detected in the page's completion status.
34+
*
35+
* @param {Model} The page where the _isComplete attribute has changed.
36+
*/
37+
onPageCompletionUpdate: function(page) {
38+
var isIncomplete = !page || page.get("_isComplete") === false;
39+
this.$(".button-widget button").attr("disabled", isIncomplete);
40+
}
41+
});
42+
43+
Adapt.register('next-button', NextButton);
44+
45+
return NextButton;
46+
});

js/get-next-page.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
define(function() {
2+
/**
3+
* Retrieves the page logically following the specified page (if one exists).
4+
*
5+
* @param {Model} The current page.
6+
* @return {Model} The next page, or null if there is no next page.
7+
*/
8+
function getNextPage(page) {
9+
if (!page) {
10+
return null;
11+
}
12+
13+
var siblings = page.getSiblings(true);
14+
15+
// Find the page after the current page
16+
var pageIndex = siblings.indexOf(page);
17+
if (pageIndex < 0) {
18+
return null;
19+
}
20+
21+
var next = siblings.at(pageIndex + 1);
22+
23+
return _getFirstChildPage(next);
24+
}
25+
26+
/**
27+
* If the specified model is a menu, it iterates through the menu until it finds the first page.
28+
*
29+
* If the specified model is already a page, it just returns the page.
30+
*
31+
* @param {Model} A page or menu model.
32+
* @return {Model} A page or null if no child page could be found.
33+
*/
34+
function _getFirstChildPage(model) {
35+
if (!model) {
36+
return null;
37+
}
38+
39+
var type = model.get("_type");
40+
if (type === "menu") {
41+
var contents = model.getChildren();
42+
return _getFirstChildPage(contents.at(0));
43+
} else if (type === "page") {
44+
return model;
45+
}
46+
47+
return null;
48+
}
49+
50+
return getNextPage;
51+
});

less/next-button.less

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.next-button-component {
2+
.button-inner {
3+
button {
4+
display: block;
5+
width: 100%;
6+
}
7+
}
8+
}

properties.schema

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"type":"object",
3+
"$schema": "http://json-schema.org/draft-04/schema",
4+
"id": "http://jsonschema.net",
5+
"$ref": "http://localhost/plugins/content/component/model.schema",
6+
"properties":{
7+
"_supportedLayout": {
8+
"type": "string",
9+
"required": true,
10+
"enum": ["full-width", "half-width", "both"],
11+
"default": "both",
12+
"editorOnly": true
13+
},
14+
"_hoverText": {
15+
"type": "string",
16+
"required": false,
17+
"inputType": "Text",
18+
"title": "Hover Text",
19+
"default": "",
20+
"validators": [],
21+
"help": "Text to display when the user hovers over the button",
22+
"translatable": true
23+
},
24+
"_requirePageCompletion": {
25+
"type": "boolean",
26+
"required": true,
27+
"inputType": {
28+
"type": "Boolean",
29+
"options": [true, false]
30+
},
31+
"title": "Require Page Completion",
32+
"default": true,
33+
"validators": ["required"],
34+
"help": "Require the page to be complete before enabling the next button"
35+
},
36+
"_nextPage": {
37+
"type": "string",
38+
"required": false,
39+
"inputType": "Text",
40+
"title": "Override Next Page ID",
41+
"default": "",
42+
"validators": [],
43+
"help": "Specify the ID of the next page to override the default behavior",
44+
"translatable": true
45+
}
46+
}
47+
}

templates/next-button.hbs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div class="button-inner">
2+
<div class="button-widget component-widget">
3+
<button class="{{_classes}}" onClick="location.href='#/id/{{_nextPage}}'" aria-label="{{displayTitle}}" title="{{_hoverText}}" {{#_requirePageCompletion}}disabled{{/_requirePageCompletion}}>{{{displayTitle}}}</button>
4+
</div>
5+
</div>

0 commit comments

Comments
 (0)