/*
* Globals
*/
//This has been moved to a global to support multiple paginated objects per DOM
var cc_startPage = 1;
var cc_pageBottom = 0;
function CollapsedContent(){
this.parent = ".sortable";
this.collapse = ".collapse";
this.trigger = ".trigger";
this.mobileTrigger;
this.backText = 'Back to Index';
this.setBehaviors = cc_setBehaviors;
this.setSlide = cc_setSlide;
this.setFade = cc_setFade;
this.setTabs = cc_setTabs;
this.setStepped = cc_setStepped;
this.setPagination = cc_setPagination;
this.setFixedPagination = cc_setFixedPagination;
this.setPaginationControls = cc_setPaginationControls;
this.setSortable = cc_setSortable; //This is set inline it seems in the page from the cascade template
this.animation = "Fade";
this.doSlide = cc_doSlide;
this.doFade = cc_doFade;
this.doTabs = cc_doTabs;
this.doStepped = cc_doStepped;
this.doMobileTabs = cc_doMobileTabs;
this.tabs = {
match: false,
current: false
};
this.paginate = {
enabled: false,
includeNumbers: true,
container: $('.paginate'),
height: 300,
target: 1,
forcePageHeights: false,
showParent: false, //used by the accordions to get height calcs
controlParent: $('.paginate'),
flexLastHeight: false,
countOverride: false,
itemsPerPage: 5
};
this.sortable = {
enabled: false,
categories: new Array(),
uniqueCategories: new Array(),
node: '.category',
container: '.sortable',
filters: false,
splitChar: ';'
};
this.__construct = function(){
var obj = this;
$("body").ready(function(){
obj.setBehaviors();
});
};
}
function cc_setBehaviors(){
var obj = this;
eval('obj.set'+obj.animation+'();');
//$(obj.parent+" "+obj.collapse).hide();
$(obj.parent+" "+obj.trigger).bind('click', function(){
eval('obj.do'+obj.animation+'(this);');
});
$(obj.parent+" "+obj.mobileTrigger).bind('click', function(){
eval('obj.doMobile'+obj.animation+'(this);');
});
$(obj.parent+" .nextStep").bind('click', function(){
var target = $(obj.parent).find('.steppedMenu .selected').next();
obj.doStepped(target);
});
$(obj.parent+" .prevStep").bind('click', function(){
var target = $(obj.parent).find('.steppedMenu .selected').prev();
obj.doStepped(target);
});
if(obj.paginate.enabled){
obj.setPagination();
}
if(obj.sortable.enabled){
$(obj.sortable.container).ready(function(){
obj.setSortable();
});
}
if(obj.animation == "Tabs" || obj.animation == "Stepped"){
$(obj.parent).each(function(){
$(this).find(obj.collapse).filter(":first").show();
});
}
if(obj.animation == "Slide"){
$(obj.collapse).each(function(){
$(this).hide();
});
}
$(document).ready(function(){
//Open hashed liknks for collapsed content
function openHash(hash){
if(obj.animation == 'Tabs'){
//tabbed menu
var tabIndex = Math.floor($(hash).parents(obj.collapse).index()/2);
obj.doTabs($(obj.trigger + ':eq(' + tabIndex + ')'));
setTimeout(function(){
$('html, body').animate({
scrollTop: $(hash).offset().top + 'px'
}, 700);
}, 300);
} else if(obj.animation == 'Slide') {
//collapsed
var openTitle = $(hash).parents(obj.parent).find(obj.trigger);
var openContent = $(hash).parentsUntil(obj.parent);
obj.doSlide(openContent);
openTitle.toggleClass(openTitle.attr('data-icon')+' '+openTitle.attr('data-icon-close'));
setTimeout(function(){
$('html, body').animate({
scrollTop: $(hash).parents(obj.parents).find(hash).offset().top + 'px'
}, 700);
}, 300);
}
}
setTimeout(function(){
if (window.location.hash != "") {
var hash;
hash = window.location.hash;
openHash(hash);
}
$('body').on('click', 'a', function(e){
if (/#/.test(this.href)) {
var hash;
hash = $(this).prop("hash");
window.location = this.href;
openHash(hash);
}
});
}, 300);
});
}
function cc_setSlide(){
var obj = this;
$(obj.parent+" "+obj.trigger).addClass("collapsible icon-circlePlus").attr('tabindex', '1').attr('data-icon','icon-circlePlus').attr('data-icon-close','icon-circleMinus');
}
function cc_doSlide(clicked){
var obj = this;
var target = $(clicked).parent().find(obj.collapse);
$(clicked).toggleClass(''+$(clicked).attr('data-icon')+' '+$(clicked).attr('data-icon-close')+'');
if(target.is(":visible")){
target.slideUp();
$(clicked).removeClass("expanded");
}
else{
$(clicked).addClass("expanded");
target.slideDown(500, function(){
//show the first tab if it is there
if(target.children('.tab').length > 0){
target.children('.tabMenu').children('li:first').trigger('click');
}
});
}
}
function cc_setFade(){
var obj = this;
}
function cc_doFade(clicked){
var obj = this;
$(clicked).parent().nextAll().hide();
$(clicked).parent().prevAll().hide();
$(clicked).parent().find(obj.collapse).fadeIn();
$(obj.parent+":first").before('
'+obj.backText+'
');
$(obj.parent+":first").parent().find('.back').click(function(){
$(obj.parent+':visible').fadeOut('normal', function(){
$(obj.parent+" "+obj.collapse).hide();
$(obj.parent).parent().children(':not(script)').fadeIn();
$(obj.parent+":first").parent().find('.back').remove();
});
obj.setBehaviors();
});
$(clicked).unbind();
$(clicked).css("text-decoration","none");
$(clicked).css("cursor","auto");
}
function cc_setPagination(){
//this version does not support table chunking. Use jquery-pagination.js for that.
var obj = this;
obj.paginate.target = cc_startPage;
if( (obj.paginate.showParent == true) && (obj.paginate.container.parent().is(":not(:visible)")) ){
var myParent = obj.paginate.container.parent();
myParent.show();
}
var localBottom = 0;
//wait until the images in the element load:
var images = obj.paginate.container.children().find('img');
if(images.length > 0){
images.filter(':last').load(function(){
doThisPagination();
});
}
else{
doThisPagination();
}
function doThisPagination(){
obj.paginate.container.children().each(function(){
var localHeight = 0;
if(jQuery.support.cssFloat == true){
cc_pageBottom += $(this).outerHeight(true);
localBottom += $(this).outerHeight(true);
localHeight = $(this).outerHeight(true);
}
else{
/*
* IE already adds margins and padding to objects' heights, so don't use outerHeight
* and also seems to be messing up with the heights of floated children.
*/
cc_pageBottom += $(this).height();
localBottom += $(this).outerHeight();
localHeight = $(this).outerHeight();
if(($(this).children(':first').css('float') == 'left') || ($(this).children(':first').css('float') == 'right')){
$(this).children(':not(:first)').each(function(){
cc_pageBottom -= $(this).outerHeight();
localBottom += $(this).outerHeight();
localHeight += $(this).outerHeight();
});
}
}
if(localBottom >= obj.paginate.height){
obj.paginate.target++;
localBottom = localHeight;
}
$(this).attr("bottom", localBottom);
$(this).attr("target", obj.paginate.target);
});
if( (obj.paginate.showParent == true) && (typeof(myParent) != 'undefined') ){
myParent.hide();
}
//Chunk the copy content based on position values
for(var n=obj.paginate.target; n>=cc_startPage; n--){
obj.paginate.container.children(":first").before('');
}
obj.paginate.container.children(":not(.page)").each(function(){
$("#page"+$(this).attr("target")).append($(this));
});
/*
* find the tallest page and set all heights equal to that one. This stops the bouncing effect.
* if this.forcePageHeight is set, use that instead (accordions use this)
*/
if(obj.paginate.forcePageHeights == false){
var pageHeight = 0;
obj.paginate.container.find(".page").each(function(){
$(this).show();
if($(this).height() > pageHeight){
pageHeight = $(this).height();
}
$(this).hide();
});
}
else{
var pageHeight = obj.paginate.forcePageHeights;
}
obj.paginate.container.find(".page").height(pageHeight);
obj.paginate.container.find(".page:first").show();
obj.setPaginationControls();
//let the last page height flex if true:
if(obj.paginate.flexLastHeight == true){
obj.paginate.container.find(".page:last").css('height','auto');
}
}
//if the first page is empty remove it.
setTimeout(function(){
if(obj.paginate.container.find(".page:first").children().length == 0){
obj.paginate.container.find(".page:not(:has(*))").remove();
obj.paginate.container.find(".page:has(*):first").show();
}
}, 100);
}
function cc_setFixedPagination(){
//Pagination for fixed height elements
var obj = this;
obj.paginate.target = cc_startPage;
//remove pages from previous setFixedPagination calls
if(obj.paginate.container.find('.page')){
var unpaginatedContent = '';
obj.paginate.container.find('.page').each(function(){
unpaginatedContent += $(this).html();
});
obj.paginate.container.find('.page').remove();
obj.paginate.container.prepend(unpaginatedContent);
}
//Use items per page to chunk up items into pages
var pageQuantity = Math.floor(obj.paginate.container.children().length/obj.paginate.itemsPerPage);
//Chunk the copy content
var itemHeight = Math.floor(100/obj.paginate.itemsPerPage);
var remainder = 100 - itemHeight*obj.paginate.itemsPerPage;
//break content into pages
for(var n=0; n<=pageQuantity; n++){
obj.paginate.target++;
obj.paginate.container.append('');
obj.paginate.container.children(':not(.page):lt('+obj.paginate.itemsPerPage+')').appendTo(obj.paginate.container.find('.page:last'));
}
//remove any empty pages
obj.paginate.container.children('.page').each(function(){
if($(this).children().length == 0){
$(this).remove();
}
});
//apply height for each item and remainder if necessary
obj.paginate.container.children('.page').children().each(function(){
$(this).css('height', itemHeight+'%');
});
if(remainder > 0){
obj.paginate.container.children('.page').children(':first-child').css('height', itemHeight+remainder+'%');
}
//create pagination controls and show first page
if(pageQuantity > 1){
obj.setPaginationControls();
}
obj.paginate.container.find(".page:first").show();
}
function cc_setPaginationControls(){
//if(cc_startPage != 0){
//If the startPage counter is not zero, this means there are other objects paginated, and we need a new page
//cc_startPage++;
//}
var obj = this;
//if there is more than one page, add the pagination controls
if(obj.paginate.target != cc_startPage){
obj.paginate.controlParent.append('
');
var controls = obj.paginate.controlParent.find(".paginationControls");
controls.children(".left").hide();
if(obj.paginate.includeNumbers == true){
controls.addClass('has-numbers');
//if more than 10 pages, show 1 - 10, then every tenth page and the last one
for(var n=obj.paginate.target; n>=cc_startPage; n--){
var visibleNum = n-cc_startPage+1;
if((visibleNum<=10) || (visibleNum%10 == 0) ){
controls.children(".controls").prepend(''+visibleNum+' ');
if( (visibleNum%10 == 0) && (visibleNum!=obj.paginate.target) ){
controls.find(".controls > span[name='"+n+"']").after(' ... ');
}
}
}
controls.children(".controls").children("span:first").addClass('selected');
}
//Events:
controls.children(".right").click(function(){
if(typeof(siteTracker) != 'undefined'){
siteTracker._trackEvent('GeneralPaginationToggle', $(this).attr('class'));
}
controls.children(".left").show();
var currentPage = obj.paginate.container.find(".page:visible");
var nextPage = currentPage.next();
if(nextPage.attr("class") == 'page'){
nextPage.fadeIn();
currentPage.hide();
}
if(nextPage.html() == obj.paginate.container.find(".page:last").html() ){
controls.children(".right").hide();
}
else controls.children(".right").show();
nextPage.find('.responsiveImg:not(:hidden)').each(function(){
resizeImg($(this));
});
controls.children(".controls").children("span").removeClass('selected');
controls.children(".controls").children("span[name='"+nextPage.attr('id').substr(4)+"']").addClass('selected');
});
controls.children(".left").click(function(){
if(typeof(siteTracker) != 'undefined'){
siteTracker._trackEvent('GeneralPaginationToggle', $(this).attr('class'));
}
controls.children(".right").show();
var currentPage = obj.paginate.container.find(".page:visible");
var nextPage = currentPage.prev();
if(nextPage.attr("class") == 'page'){
nextPage.fadeIn();
currentPage.hide();
}
if(nextPage.html() == obj.paginate.container.find(".page:first").html() ){
controls.children(".left").hide();
}
else controls.children(".left").show();
nextPage.find('.responsiveImg:not(:hidden)').each(function(){
resizeImg($(this));
});
controls.children(".controls").children("span").removeClass('selected');
controls.children(".controls").children("span[name='"+nextPage.attr('id').substr(4)+"']").addClass('selected');
});
//$("body").delegate('.paginationControls > .controls > .continuation','click', function(){
$(document).on('click', '.paginationControls > .controls > .continuation', function(){
//add the next 9 spans:
for(var n=0; n<9; n++){
var start = parseInt($(this).attr('start'))+n;
var displayStart = parseInt($(this).attr('displayStart'))+n;
if(start < cc_startPage){
controls.find(".controls span[name='"+(start-1)+"']").after(''+displayStart+' ');
}
}
$(this).remove();
});
//$("body").delegate('.paginationControls > .controls > .number','click', function(){
$(document).on('click', '.paginationControls > .controls > .number',function(){
if($("#page"+$(this).attr('name')).html() != obj.paginate.container.find(".page:visible").html()){
if(typeof(siteTracker) != 'undefined'){
siteTracker._trackEvent('GeneralPaginationToggle', $(this).attr('name'));
}
controls.children(".controls").children("span").removeClass('selected');
var current = obj.paginate.container.find(".page:visible");
obj.paginate.container.find("#page"+$(this).attr('name')).fadeIn();
current.hide();
if( obj.paginate.container.find("#page"+$(this).attr('name')).prevAll('.page').length == 0 ){
$(".paginationControls .left").hide();
}
else{
controls.children(".left").show();
}
if( obj.paginate.container.find("#page"+$(this).attr('name')).nextAll('.page').length == 0 ){
controls.children(".right").hide();
}
else{
controls.children(".right").show();
}
$(this).addClass('selected');
}
else return true;
});
//$("body").delegate('.paginationControls, .paginationControls > .controls, .paginationControls > .controls > span','dbclick', function(){
$(document).on('dbclick', '.paginationControls, .paginationControls > .controls, .paginationControls > .controls > span', function(){
return false;
});
}
//set the globals for a new call to this object (for accordions)
cc_startPage = obj.paginate.target + 1;
cc_pageBottom = obj.paginate.target*obj.paginate.height;
}
function cc_setTabs(){
/*
* Classname functions:
* .open = classname for open tabs when operating as an accordian at mobile resolutions
* .tabsOpen = classname for single open profile when at desktop resolutions
* .selected = classname for the tabMenu, only for desktop resolution, its .index() should sync up with the active profile with the .tabsOpen class
* .on = classname for the mobile buttons when functioning as an accordian
*/
var obj = this;
//only run this if there is more than one tab
if($(obj.parent+' > '+obj.collapse).length > 1){
$(obj.collapse).hide(); //hide all collapsable elements, reveal one of them later
$(obj.parent).each(function(){
var parentNode = $(this);
parentNode.prepend('
');
}
});
});
obj.tabs.match = obj.trigger;
obj.trigger = ".tabMenu li";
obj.mobileTrigger = ".profileWrap .mobileTab";
}
}
function cc_doTabs(clicked){
/*
* Classname functions:
* .open = classname for open tabs when operating as an accordian at mobile resolutions
* .tabsOpen = classname for single open profile when at desktop resolutions
* .selected = classname for the tabMenu, only for desktop resolution, its .index() should sync up with the active profile with the .tabsOpen class
* .on = classname for the mobile buttons when functioning as an accordian
*/
var obj = this;
var needle = $(clicked).text();
var tabIndex = $(clicked).index();
$(clicked).siblings().removeClass("selected");
$(clicked).addClass("selected");
var parentNode = $(clicked).parent().next();
var h = parentNode.height();
parentNode.height(h);
parentNode.find('.mobileTab.on').toggleClass(''+parentNode.find('.mobileTab.on').attr('data-icon')+' '+parentNode.find('.mobileTab.on').attr('data-icon-close')+'').removeClass('on');
parentNode.find('.mobileTab:eq('+tabIndex+')').toggleClass(''+parentNode.find('.mobileTab:eq('+tabIndex+')').attr('data-icon')+' '+parentNode.find('.mobileTab:eq('+tabIndex+')').attr('data-icon-close')+'').addClass('on');
parentNode.find('.tabsOpen').fadeOut(100, function(){
$(this).removeClass('tabsOpen open').hide();
parentNode.find(obj.collapse+':eq('+tabIndex+')').addClass('open tabsOpen').css('opacity', 0).show();
parentNode.height('auto');
parentNode.find(obj.collapse+'.tabsOpen').animate({ 'opacity': 1 }, 100);
});
}
function cc_doMobileTabs(clicked){
/*
* Classname functions:
* .open = classname for open tabs when operating as an accordian at mobile resolutions
* .tabsOpen = classname for single open profile when at desktop resolutions
* .selected = classname for the tabMenu, only for desktop resolution, its .index() should sync up with the active profile with the .tabsOpen class
* .on = classname for the mobile buttons when functioning as an accordian
*/
var obj = this;
var needle = $(clicked).text();
var tabMenu = $(clicked).parent().prev();
var item = $(clicked).next();
var parentNode = $(clicked).parent();
var currentHeight = item.height();
var tabIndex;
tabMenu.children().removeClass('selected');
tabMenu.find('li').each(function(){
if(needle == $(this).text()){
$(this).addClass('selected');
}
tabIndex = tabMenu.find('li.selected').index();
});
parentNode.find(obj.collapse+'.tabsOpen').removeClass('tabsOpen');
parentNode.find(obj.collapse+':eq('+tabIndex+')').addClass('tabsOpen');
if($(clicked).hasClass('on')){
$(clicked).removeClass('on');
item.height(currentHeight);
item.animate({ height: 0 }, 250, function(){
item.removeClass('open');
item.height('auto');
item.hide();
});
} else {
$(clicked).addClass('on');
var elem = item.clone().css({ height : 'auto', width : 'auto', opacity : 0 }).appendTo('body');
var height = elem.css('height');
elem.remove();
item.height(0);
item.animate({ height: height }, 250, function(){
item.addClass('open');
item.height('auto');
item.show();
});
item.addClass('open');
}
$(clicked).toggleClass(''+$(clicked).attr('data-icon')+' '+$(clicked).attr('data-icon-close')+'');
}
function cc_setStepped(){
/*
* Classname functions:
* .open = classname for open tabs when operating as an accordian at mobile resolutions
* .selected = classname for the steppedMenu, its .index() should sync up with the active profile with the .tabsOpen class
*/
var obj = this;
//only run this if there is more than one tab
//console.log($(obj.parent).hasClass('course-list'));
if($(obj.parent+' > '+obj.collapse).length > 1) {
$(obj.collapse).hide(); //hide all collapsable elements, reveal one of them later
$(obj.parent).each(function () {
var parentNode = $(this);
parentNode.prepend('
');
$(this).find(obj.trigger).hide();
});
parentNode.find(".steppedMenu li:first").addClass("selected on");
parentNode.children(obj.collapse).find(obj.trigger).filter(":first").addClass("selected");
parentNode.find(obj.collapse).wrapAll('');
parentNode.find(obj.collapse).each(function(){
$(this).prepend('').append('');
if(!$(this).is(":first-child")){
var index = $(this).index() - 1;
var text = 'Previous: ' + $(obj.parent).find('.steppedMenu li:eq('+index+')').text();
$(this).find('.stepControls').append('
'+text+'
');
}
if(!$(this).is(":last-child")){
var index = $(this).index() + 1;
var text = 'Next: ' +$(obj.parent).find('.steppedMenu li:eq('+index+')').text();
$(this).find('.stepControls').append('
'+text+'
');
}
});
parentNode.find(obj.collapse).first().addClass('on');
});
obj.tabs.match = obj.trigger;
obj.trigger = ".steppedMenu li";
//obj.mobileTrigger = ".profileWrap .mobileTab";
}
}
function cc_doStepped(clicked){
/*
* Classname functions:
* .open = classname for open tabs when operating as an accordian at mobile resolutions
* .selected = classname for the steppedMenu, its .index() should sync up with the active profile with the .tabsOpen class
*/
var obj = this;
var needle = $(clicked).text();
var tabIndex = $(clicked).index();
$(clicked).siblings().removeClass("selected on");
$(clicked).addClass("selected on").prevAll().addClass("on");
var parentNode = $(clicked).parent().next();
var h = parentNode.height();
parentNode.height(h);
parentNode.find('.on').fadeOut(100, function(){
$(this).removeClass('on').hide();
parentNode.find(obj.collapse+':eq('+tabIndex+')').addClass('on').css('opacity', 0).show();
parentNode.height('auto');
parentNode.find(obj.collapse+'.on').animate({ 'opacity': 1 }, 100);
});
if(parentNode.offset().top < $(window).scrollTop()) {
$('html, body').animate({
scrollTop: parentNode.offset().top + 'px'
}, 200);
}
}
function cc_setSortable(){
var obj = this;
//trim whitespace from a string
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
};
if($('#switchContainer').length == 0){
$(obj.sortable.container).prepend('
Filters
');
}
//obj.sortable.node can be a string or an array; if it is an array, we will need multiple drop downs
if(typeof(obj.sortable.node) == 'object'){
for(var n=0; n 0){
createFilter(obj.sortable.node[n]);
}
}
}
else{
if($(obj.sortable.node).length > 0){
createFilter(obj.sortable.node);
}
}
function createFilter(node){
if( (typeof($(node).attr('title')) != 'undefined') && ($(node).attr('title').length > 0) ){
var defaultText = $(node).attr('title');
var selectTitle = $(node).attr('title');
}
else{
var defaultText = 'View all';
var selectTitle = 'Filter list';
}
$('#switchContainer').append('');
var thisSwitch = $('#switchContainer select.switch[target="'+node+'"]');
thisSwitch.append('');
obj.sortable.categories = new Array();
obj.sortable.uniqueCategories = new Array();
$(obj.sortable.container).find(node).each(function(){
//Split on semicolons, trim white space, and then push all values.
var cat = $(this).text();
//obj.sortable.categories.push(cat.trim());
var cats = cat.split(obj.sortable.splitChar);
for(var n=0; n'+obj.sortable.uniqueCategories[n]+'');
}
/*
* turn on all of the items;
* take them away if they don't match the search criteria
*/
thisSwitch.change(function(){
var displaySet = $(obj.sortable.container).find(node).parents(obj.parent)
displaySet.hide().addClass('on');
$('#switchContainer select.switch').each(function(){
var val = $(this).val();
if(val != ''){
var targetSet = $(this).attr('target');
displaySet.each(function(){
var cat = $(this).find(targetSet).text();
var cats = cat.split(obj.sortable.splitChar);
var matches = false;
for(var n=0; n