Skip to content

Commit

Permalink
#971 Enhancements to tabbed navigator+ page:
Browse files Browse the repository at this point in the history
- New optional property to automatically number nested pages in tabs (useful if you have lots of nested pages)
- New optional property which adds navigation (next / previous) buttons at bottom of nested pages
- New optional property which allows breadcrumb links for nested pages to be hidden if navigation buttons is turned on
  • Loading branch information
FayCross committed Nov 17, 2023
1 parent e85397b commit 1df46d6
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 62 deletions.
Expand Up @@ -49,4 +49,9 @@
#txtHolder {
margin-bottom: 1em;
}

.nestedNavBtnHolder {
float: right;
margin: 1em 0 0 1em;
}

158 changes: 108 additions & 50 deletions modules/xerte/parent_templates/Nottingham/models_html5/tabNavExtra.html
Expand Up @@ -22,6 +22,8 @@
// other functions for model should also be in here to avoid conflicts
var tabNavExtra = new function() {

let $pageContents;

// Called from xenith if tab level deeplinking is available
this.deepLink = function(item) {
item = item.split(",");
Expand Down Expand Up @@ -66,18 +68,22 @@

$paneHolder.height($infoHolder.height() - $("#pageContents .tabList:visible").height() - ($paneHolder.outerHeight(true) - $paneHolder.height()));
}

var $pageContents = $("#pageContents");

if ($pageContents.data("count") != 0) {
$pageContents.data("count", $pageContents.data("count") + 1);
this.scaleImages();
} else {
$pageContents.data("count", $pageContents.data("count") + 1);
}
}

this.pageChanged = function() {
$pageContents = $('#pageContents');
}

this.init = function() {
// tabWidth attribute is ignored as it is automatic
$pageContents = $('#pageContents');

if (x_currentPageXML.getAttribute("text") != undefined && x_currentPageXML.getAttribute("text") != "") {
$('#txtHolder').html(x_addLineBreaks(x_currentPageXML.getAttribute("text")));
Expand All @@ -103,8 +109,8 @@
// have to clone topics / tabs / pages in seperate functions as otherwise it clones the data from previous topic
var $topic = $("#pageContents .topic"),
$infoHolder = $("#pageContents .infoHolder");
$("#pageContents").data("count", 0);

$pageContents.data("count", 0);

$(x_currentPageXML).children()
.each(function(i) {
Expand All @@ -122,7 +128,6 @@
.data("index", i)
.html(this.getAttribute("name"))
.click(function(e) {

e.preventDefault();

$this = $(this);
Expand All @@ -138,20 +143,17 @@

if (x_currentPageXML.getAttribute("rememberTab") == "true") {
// auto select same tab / nested page as that viewed in previous topic
var $pageContents = $("#pageContents"),
$currentTab = $thisHolder.find(".tabHeader a:contains(" + $pageContents.data("currentTab") + ")");

$currentTab.trigger("click");

var $currentTab = $thisHolder.find(".tabHeader a:contains(" + $pageContents.data("currentTab") + ")");
if ($currentTab.length != 0) {
$currentTab.trigger("click");
var $currentPaneHolder = $thisHolder.find(".paneHolder:eq(" + $currentTab.parent().index() + ")"),
$currentPane = $currentPaneHolder.find(".paneList a:contains(" + $pageContents.data("currentPane") + ")");

if ($currentPane.length != 0) {
$currentPane.trigger("click");
tabNavExtra.nestedLinkClick($currentPane.index());
} else {
// no match so go to 1st nested page on tab
$currentPaneHolder.find(".paneList a:eq(0)").trigger("click");
tabNavExtra.nestedLinkClick(0);
}

$currentTab.parent().focus();
Expand All @@ -163,7 +165,6 @@
} else {
// 1st tab and 1st nested page in highlighted topic
$thisHolder.find(".tabHeader:eq(0) a").trigger("click").parent().focus();
//$thisHolder.find(".paneHolder:eq(0) .paneList a:eq(0)").trigger("click");
}

tabNavExtra.scaleImages();
Expand Down Expand Up @@ -203,11 +204,30 @@
.each(function(i) {
$(this).children()
.each(function(j) {
var $paneHolder = $("#pageContents .infoHolder:eq(" + i + ") .paneHolder:eq(" + j + ")"),
$paneList = $paneHolder.find(".paneList"),
$paneInfo = $paneHolder.find(".paneInfo"),
$link = $paneList.find("a");

var $paneHolder = $("#pageContents .infoHolder:eq(" + i + ") .paneHolder:eq(" + j + ")"),
$paneList = $paneHolder.find(".paneList"),
$paneInfo = $paneHolder.find(".paneInfo"),
$link = $paneList.find("a");

// create navigation (next/prev) buttons - they will only be shown when more than one nested page
let $thisNavBtns;
if (x_currentPageXML.getAttribute('nextBtns') == 'true') {
$thisNavBtns = $('<div class="nestedNavBtnHolder"></div>');
$('<button class="nestedPrevBtn">' + (x_currentPageXML.getAttribute('prevBtn') != undefined ? x_currentPageXML.getAttribute('prevBtn') : 'Previous') + '</button>')
.appendTo($thisNavBtns)
.button()
.click(function () {
tabNavExtra.nestedLinkClick('previous');
});

$('<button class="nestedNextBtn">' + (x_currentPageXML.getAttribute('nextBtn') != undefined ? x_currentPageXML.getAttribute('nextBtn') : 'Next') + '</button>')
.appendTo($thisNavBtns)
.button()
.click(function () {
tabNavExtra.nestedLinkClick('next');
});
}

$(this).children()
.each(function(k) {
var $thisLink, $thisPaneInfo;
Expand All @@ -219,29 +239,25 @@
$thisLink = $link;
$thisPaneInfo = $paneInfo;
}


// nested page navigation will only show if more than 1 nested page
if ($(this).parent().children().length > 1) {
if (k != $(this).parent().children().length - 1) {
$paneList.append(" | ");
// show breadcrumb link list
if (x_currentPageXML.getAttribute('nextBtns') != 'true' || (x_currentPageXML.getAttribute('nextBtns') == 'true' && x_currentPageXML.getAttribute('hideBreadcrumbs') != 'true')) {
if (k != $(this).parent().children().length - 1) {
$paneList.append(" | ");
}

$thisLink
.html(x_currentPageXML.getAttribute('autoNumber') == 'true' ? k + 1 : this.getAttribute("name"))
.click(function (e) {
e.preventDefault();
tabNavExtra.nestedLinkClick($(this).index());
});
} else {
$paneList.addClass("delete");
}
$thisLink
.html(this.getAttribute("name"))
.click(function(e) {
e.preventDefault();

var $this = $(this);
if ($this != $("#pageContents .paneList a.selected")) {
$(".customHTMLHolder").detach();
$this.parent().find("a.selected").removeClass("selected");
$("#pageContents .paneInfo:visible").hide();
$this.addClass("selected");
$this.parents(".paneHolder").find(".paneInfo:eq(" + $this.index() + ")").show().focus();
$("#pageContents").data("currentPane", $this.html());

tabNavExtra.scaleImages();
tabNavExtra.loadCustomHTML();
}
});

} else {
$paneList.addClass("delete");
}
Expand All @@ -253,19 +269,19 @@
var newString = "";
if (url.split('.').pop().slice(0, -1) == "swf") {
newString += '<div class="centerAlign"><div id="pageSWF' + i + '" class="paneSWF"><h3 class="alert">' + x_getLangInfo(x_languageData.find("errorFlash")[0], "label", "You need to install the Flash Player to view this content.") + '</h3><p><a href="http://www.adobe.com/go/getflashplayer"><img class="flashImg" src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="' + x_getLangInfo(x_languageData.find("errorFlash")[0], "description", "Get the Flash Player") + '" /></a></p></div></div>';
} else if (url.split('.').pop().slice(0, -1) == "html") {

} else if (url.split('.').pop().slice(0, -1) == "html") {
// sets up savedData for current page as an array so it can contain the initObject and any additionally saved data for this customHTML file
if (x_pageInfo[x_currentPage].savedData == undefined) {
x_pageInfo[x_currentPage].savedData = [];
}
x_pageInfo[x_currentPage].savedData.push(new Object());

if (this.getAttribute("initObject") != undefined && this.getAttribute("initObject") != "") {
x_pageInfo[x_currentPage].savedData[x_pageInfo[x_currentPage].savedData.length - 1].initObject = x_sortInitObject(this.getAttribute("initObject"));
}
newString += '<div class="jsHolder"></div>';

} else {
newString += '<div class="paneImg"><img ';
if (this.getAttribute("tip") != undefined && this.getAttribute("tip") != "") {
Expand Down Expand Up @@ -313,7 +329,14 @@
});
}
});
$link.addClass("selected");

if ($thisNavBtns != undefined && $paneHolder.find('.paneInfo').length > 1) {
$thisNavBtns
.appendTo($paneHolder)
.find('.nestedPrevBtn').button('disable');
}

$link.addClass('selected');
});
});

Expand All @@ -323,7 +346,7 @@

$(".paneList.delete").remove();

$("#pageContents").data({
$pageContents.data({
"currentTopic": 0,
"currentTab": $(x_currentPageXML).children().children()[0].getAttribute("name"),
"currentPane": $(x_currentPageXML).children().children().children()[0].getAttribute("name")
Expand All @@ -334,8 +357,7 @@
$("#pageContents .infoHolder").tabs({
activate: function(event, ui) {
if (firstLoad != true) {
var $pageContents = $("#pageContents"),
$panel = $(ui.panel);
var $panel = $(ui.panel);

$(".customHTMLHolder").detach();
$pageContents.data("currentTab", ui.newTab.find("a").html());
Expand Down Expand Up @@ -387,11 +409,47 @@

x_pageLoaded();
}

// change nested page on tab - by clicking either a breadcrumb link or a next/previous button
this.nestedLinkClick = function(index) {
const $currentPaneHolder = $pageContents.find(".infoHolder:visible .paneHolder:visible");
const currentIndex = $currentPaneHolder.find(".paneInfo:visible").index() - $currentPaneHolder.find('.paneList').length;
const newIndex = index == 'next' ? currentIndex+1 : index == 'previous' ? currentIndex-1 : index;
const $newPage = $currentPaneHolder.find(".paneInfo:eq(" + newIndex + ")");

if (currentIndex != newIndex) {
$(".customHTMLHolder").detach();
if ($currentPaneHolder.find('.paneList').length > 0) {
$currentPaneHolder.find('.paneList a.selected').removeClass("selected");
$currentPaneHolder.find('.paneList a:eq(' + newIndex + ')').addClass("selected");
$pageContents.data("currentPane", $currentPaneHolder.find('.paneList a:eq(' + newIndex + ')').html());
} else {
$pageContents.data("currentPane", undefined);
}
$currentPaneHolder.find('.paneInfo:visible').hide();

$newPage.show().focus();

if (newIndex == 0) {
$currentPaneHolder.find('.nestedPrevBtn').button('disable');
$currentPaneHolder.find('.nestedNextBtn').button('enable');
} else {
$currentPaneHolder.find('.nestedPrevBtn').button('enable');
if (newIndex == $currentPaneHolder.find('.paneInfo').length - 1) {
$currentPaneHolder.find('.nestedNextBtn').button('disable');
} else {
$currentPaneHolder.find('.nestedNextBtn').button('enable');
}
}

this.scaleImages();
this.loadCustomHTML();
}
}

// function scales image on visible panel - have to do them individually after panel change as I can't get dimensions of images on hidden panels
this.scaleImages = function() {
var $pageContents = $("#pageContents"),
$img = $pageContents.find(".paneImg:visible img");
var $img = $pageContents.find(".paneImg:visible img");

// is there an image currently visible? Has it already been scaled to fit this?
if ($img.length > 0 && $pageContents.data("count") != $img.data("count")) {
Expand Down
17 changes: 13 additions & 4 deletions modules/xerte/parent_templates/Nottingham/wizards/en-GB/data.xwd
Expand Up @@ -398,7 +398,7 @@
PersonalAvgLabel = "Avg. of your attempts"
PersonalLastLabel = "Your last attempt"
AvgLabel = "Avg. of all attempts"
></showGraph>]]></showGraph><slideshow><![CDATA[<slideshow name="Enter Page Title" text="Enter text for the page here" panelWidth="Medium" nextBtnTip="Next" priorBtnTip="Previous" slideCount="Slide {i} of {n}"/>]]></slideshow><stopTracking><![CDATA[<stopTracking name="Enter Page Title" textIntro="Instruction" buttonLbl="Stop and finish tracking of this session" textAfter="You can now close the window">Enter text for the page here</stopTracking>]]></stopTracking><summary><![CDATA[<summary name="Enter Page Title" summaryHeader="Summary" summary="Summarise the key points" nextstepsHeader="Next Steps" nextsteps="Suggest how the knowledge can be applied and any useful next steps"/>]]></summary><tabNav><![CDATA[<tabNav name="Enter Page Title" text="Enter text for the page here" panelWidth="Medium"/>]]></tabNav><tabNavExtra><![CDATA[<tabNavExtra name="Enter Page Title" panelWidth="Large"/>]]></tabNavExtra><table><![CDATA[<table name="Enter Page Title" text="Enter text for the page here" align="left"><tableData name="Table Name" data="data|data" size="medium" borders="simple" header="header" shadeHeader="true" shade="true"/></table>]]></table><text><![CDATA[<text name="Enter Page Title">Enter text for the page here</text>]]></text><textCorrection><![CDATA[<textCorrection name="Enter Page Title" copyText="false" align="Left" introduction="Enter text for the page here" wrongText="Enter the wrong text here" answer="Enter the correct text here" feedback="Enter the feedback here" panelWidth="Medium" disableAnswers="true" checkBtn="Submit" textRight="Your answer is correct" textWrong="Your answer is incorrect" FurtherClarificationLabel="Feedback" answerLabel="Answer" attemptLabel="Attempts remaining" correctLabel="Correct Answer" textIncomplete="You have not attempted the question"/>]]></textCorrection><textDrawing><![CDATA[<textDrawing name="Enter Page Title" desc="Enter a description" align="left" interactivity="off"> </textDrawing>]]></textDrawing><textGraphics><![CDATA[<textGraphics name="Enter Page Title" align="Left" imagesize="auto" url="Select an Image" tip="" transcriptbuttonlabel="Transcript">Enter text for the page here</textGraphics>]]></textGraphics><textHighlight><![CDATA[<textHighlight name="Enter Page Title"
></showGraph>]]></showGraph><slideshow><![CDATA[<slideshow name="Enter Page Title" text="Enter text for the page here" panelWidth="Medium" nextBtnTip="Next" priorBtnTip="Previous" slideCount="Slide {i} of {n}"/>]]></slideshow><stopTracking><![CDATA[<stopTracking name="Enter Page Title" textIntro="Instruction" buttonLbl="Stop and finish tracking of this session" textAfter="You can now close the window">Enter text for the page here</stopTracking>]]></stopTracking><summary><![CDATA[<summary name="Enter Page Title" summaryHeader="Summary" summary="Summarise the key points" nextstepsHeader="Next Steps" nextsteps="Suggest how the knowledge can be applied and any useful next steps"/>]]></summary><tabNav><![CDATA[<tabNav name="Enter Page Title" text="Enter text for the page here" panelWidth="Medium"/>]]></tabNav><tabNavExtra><![CDATA[<tabNavExtra name="Enter Page Title" panelWidth="Large" nextBtn="Next" prevBtn="Previous"/>]]></tabNavExtra><table><![CDATA[<table name="Enter Page Title" text="Enter text for the page here" align="left"><tableData name="Table Name" data="data|data" size="medium" borders="simple" header="header" shadeHeader="true" shade="true"/></table>]]></table><text><![CDATA[<text name="Enter Page Title">Enter text for the page here</text>]]></text><textCorrection><![CDATA[<textCorrection name="Enter Page Title" copyText="false" align="Left" introduction="Enter text for the page here" wrongText="Enter the wrong text here" answer="Enter the correct text here" feedback="Enter the feedback here" panelWidth="Medium" disableAnswers="true" checkBtn="Submit" textRight="Your answer is correct" textWrong="Your answer is incorrect" FurtherClarificationLabel="Feedback" answerLabel="Answer" attemptLabel="Attempts remaining" correctLabel="Correct Answer" textIncomplete="You have not attempted the question"/>]]></textCorrection><textDrawing><![CDATA[<textDrawing name="Enter Page Title" desc="Enter a description" align="left" interactivity="off"> </textDrawing>]]></textDrawing><textGraphics><![CDATA[<textGraphics name="Enter Page Title" align="Left" imagesize="auto" url="Select an Image" tip="" transcriptbuttonlabel="Transcript">Enter text for the page here</textGraphics>]]></textGraphics><textHighlight><![CDATA[<textHighlight name="Enter Page Title"
text="&lt;p&gt;Enter text for the page here&lt;/p&gt;" textPos="top" textTitle="Introduction"
initialText="&lt;p&gt;Enter initial text here&lt;/p&gt;" initialPos="panelA" initialTitle="Initial Text"
suggestedText="&lt;p&gt;Enter suggested answer text here&lt;/p&gt;" suggestedPos="panelB" suggestedTitle="Suggested Text"
Expand Down Expand Up @@ -8485,13 +8485,22 @@
<tabWidth label="Tab Width" type="NumericStepper" min="20" max="250" step="1" defaultValue="100" width="100" deprecated="Width is now set automatically"/>
<panelWidth label="Panel Width" options="Small,Medium,Large" type="ComboBox" data="Small,Medium,Large" defaultValue="Large" width="100" mandatory="true"/>

<txtGroup type="group" label="Page Text" optional="true">
<txtGroup type="group" label="Page Text" optional="true" tooltip="Add introductory text, either at the top of the page or above the topic list.">
<text label="Text" type="TextArea" defaultValue="Enter text for the page here" height="200" optional="true"/>
<textPos label="Position" options="Top,Above Topic List" type="ComboBox" data="Top,Above" defaultValue="Top" width="100" optional="true"/>
</txtGroup>


<nestedPageNav type="group" label="Nested Page Navigation" optional="true" tooltip="By default, when a tab contains more than one nested page, a list of page title links is shown to allow navigation between them.">
<autoNumber label="Auto-Number Links" type="CheckBox" optional="true" defaultValue="false" condition="nextBtns=='false'||(nextBtns=='true'&amp;&amp;hideBreadcrumbs=='false')" tooltip="Use automatically generated numbers for page links, instead of the page title text."/>
<nextBtns label="Include Navigation Buttons" type="CheckBox" optional="true" defaultValue="false" conditionTrigger="true" tooltip="Add navigation (next / previous) buttons when a tab contains more than one nested page."/>
<hideBreadcrumbs label="Hide Title Links" type="CheckBox" optional="true" defaultValue="false" conditionTrigger="true" condition="nextBtns!='false'" tooltip="Hide nested page links when navigation buttons are shown."/>
</nestedPageNav>

<rememberTab label="Stay on Current Tab" type="CheckBox" optional="true" tooltip="Display the currently viewed tab when changing between topics containing tabs of the same name"/>


<nextBtn label="Next Button Label" type="TextInput" wysiwyg="true" defaultValue="Next" mandatory="true" language="true"/>
<prevBtn label="Previous Button Label" type="TextInput" wysiwyg="true" defaultValue="Previous" mandatory="true" language="true"/>

<newNodes>
<topic><![CDATA[<topic name="Enter Topic Name"><nestedTab name="Enter Tab Name"><nestedPage name="Nested Page Name" text="Content for the pane"/></nestedTab></topic>]]></topic>
</newNodes>
Expand Down

0 comments on commit 1df46d6

Please sign in to comment.