/* * 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(''); parentNode.children(obj.collapse).each(function(){ parentNode.find(".tabMenu").append('
  • '+$(this).find(obj.trigger).text()+'
  • '); $(this).find(obj.trigger).hide(); }); parentNode.find(".tabMenu li:first").addClass("selected"); parentNode.children(obj.collapse).find(obj.trigger).filter(":first").addClass("selected"); parentNode.find(obj.collapse).wrapAll('
    '); parentNode.find(obj.collapse).each(function(){ if($(this).index() == 0){ $(this).before('
    '+$(this).find(obj.trigger).text()+'
    '); $(this).addClass('open tabsOpen'); } else { $(this).before('
    '+$(this).find(obj.trigger).text()+'
    '); } }); }); 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(''); parentNode.children(obj.collapse).each(function () { parentNode.find(".steppedMenu").append('
  • ' + $(this).find(obj.trigger).text() + '
  • '); $(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