(function(){ var $ = jQuery, franklin = window.franklin, undefined; //To prevent more debug hunts, if franklin.Site is already defined, stop here and assume this script was already included. if(franklin.Site){ console.log("franklin.Site has already been defined. Check for multiple references."); return; } //Create the Site instance franklin.Site = Site.extend({ classPath:"franklin", className:"Site", componentAttr:"data-fti-component", componentOptionsAttr:"data-fti-component-options" }); var site = franklin.site = $(document.documentElement).controller(franklin.Site); //var site = franklin.site = ElementController.get(franklin.Site, document.documentElement); site.stackComponent = function(){ console.log("Deprecated "+site.getFullClassName()+ ".stackComponent() method called.", arguments); }; site.bind("beforeInit", function(evt){ //Store some jQuery wrappers for global use site.el.$win = $(window); site.el.$doc = $(document); site.el.$html = $(document.documentElement); site.el.$head = site.el.$html.children("head:first"); site.el.$body = site.el.$html.children("body:first"); site.el.$pgCanvas = $("#pgCanvas"); site.el.$pgTop = $("#pgTop"); site.el.$pgLeader = $("#pgLeader"); site.el.$pgContent = $("#pgContent"); site.el.$pgBottom = $("#pgBottom"); site.el.$mainContent = $("#mainContent"); site.el.$leftSidebar = $("#leftSidebar"); site.el.$a = $("a"); }); site.bind("init", function(evt){ }); site.bind("afterInitComponents", function(evt){ //Add the "ready" class to the html tag after the site, pages, and components have been initialized. The CSS can hook onto it to avoid FOUC. site.el.$html.addClass("ready"); }); //Intialize the site when the document is ready $(document).ready(function(){ site.init(); }); $(document).load(function(){ site.el.$html.addClass("loaded"); }); //Detect and react to the trouble of IE6 (or below) (function(){ if ($.browser.version) { var majorVersion = parseInt($.browser.version.substring(0,1)); site.isIE6 = $.browser.msie && majorVersion < 7; } })(); //Add the detection for CSS child selectors for lightweight IE6 support Modernizr.addTest("csschildselectors", function(){ return !site.isIE6; }); /* Franklin Page and Component base classes .......................................................... */ site.Page = Site.Page.extend({ classPath:"franklin.site.page", construct:function(){ this._super.apply(this, arguments); }, getQueryString:function(name){ var split = window.location.search.substring(1).split("&"); for(var q=0; q < split.length; q++){ var qs = split[q].split("="); if(qs[0]==name){ return qs[1]; } } return null; } }); site.Component = Site.Component.extend({ classPath:"franklin.site.component", construct:function(){ this._super.apply(this, arguments); }, getQueryString:site.Page.prototype.getQueryString }); /* Runtime/preview mode (site-wide) .......................................................... */ site.page.Common = site.Page.extend({ className:"Common", construct:function(){ this._super.apply(this, arguments); }, test:function(){ return true; }, _init:function(evt){ var I = this; $("input[placeholder]").placeholder(); //Make some select dropdowns "linkable" $("select.selLinkList").live("change", function(evt){ var $sel = $(this), url = $.trim($sel.val()); if(url && url.length){ window.location = url; } }); //Convert lightbox links $("a.lightbox").live("click", function(evt){ var $a = $(this), lbDataKey = site.component.Lightbox.prototype.getFullClassName(true), lightbox = $a.data(lbDataKey); //Create the lightbox if(!lightbox){ lightbox = site.component.Lightbox.generate($a.attr("title"), ""); $a.data(lbDataKey, lightbox); var isImage = /\.(jpg|gif|png)$/i.test($a.attr("href")); if(isImage){ $("").appendTo(lightbox.el.$content); }else{ //Assume we need to load some local content (ajax) lightbox.load($a.attr("href")); } } //Open the lightbox lightbox.open(); evt.preventDefault(); }); } }); /* Edit mode (site-wide) .......................................................... */ site.page.EditMode = site.Page.extend({ className:"EditMode", construct:function(){ this._super.apply(this, arguments); }, test:function(){ return $("#page-edit-html").length > 0; }, _init:function(evt){ } }); /* Public Home Page .......................................................... */ site.page.HomePublic = site.Page.extend({ className:"HomePublic", construct:function(){ this._super.apply(this, arguments); }, test:function(){ return site.el.$pgCanvas.hasClass("home"); }, _init:function(evt){ /* //Change pgLeader accordions to accordion style2 - this should ultimately be a part of the component configuration, but this is a workaround for now var sectionedAccordion = site.el.$pgLeader.find("div.sectionedContent").removeClass("fluidStyle3").closest("div.component").data("SectionedAccordion"); if(sectionedAccordion){ sectionedAccordion.bind("afterInit", function(){ sectionedAccordion.accordion.el.$container.removeClass("accordionStyle1").addClass("accordionStyle2"); sectionedAccordion.accordion.showPane(0, true); }); } */ //Add the HR guys and change the class on .linksList or .htmlBlock var $wraps = site.el.$pgLeader.find("div.linksList,div.htmlBlock"); $wraps.each(function(){ var $wrap = $(this), $content = $wrap.children(".content"), hr = "
"; if($wrap.is(".linksList")){ $wrap.removeClass("linksList").addClass("linksList2"); }else if($wrap.is(".htmlBlock")){ $wrap.removeClass("htmlBlock").addClass("htmlBlock2"); } $(hr).insertBefore($content); $(hr).insertAfter($content); }); } }); /* 2 Column 30/70 .......................................................... */ site.page.twoCol_30_70 = site.Page.extend({ className:"twoCol_30_70", construct:function(){ this._super.apply(this, arguments); }, test:function(){ return site.el.$pgContent.hasClass("threeCol-30-70"); }, _init:function(evt){ site.el.$leftSidebar.prepend(""); } }); /* 3 Column 30/45/25 .......................................................... */ site.page.threeCol_30_45_25 = site.Page.extend({ className:"threeCol_30_45_25", construct:function(){ this._super.apply(this, arguments); }, test:function(){ return site.el.$pgContent.hasClass("threeCol-30-45-25"); }, _init:function(evt){ site.el.$leftSidebar.prepend(""); $("#mainContentSidebar").prepend(""); } }); /* Billboard .......................................................... */ site.component.Billboard = site.Component.extend({ className:"Billboard", construct:function(){ var I = this; // http://jquery.malsup.com/cycle/options.html this.options.cycle = $.extend({}, this.options.cycle); this._super.apply(this, arguments); this.createDispatcher({setIndex:"_setIndex"}); this.createDispatcher({play:"_play"}); this.createDispatcher({pause:"_pause"}); this.createDispatcher({prev:"_prev"}); this.createDispatcher({next:"_next"}); //Relay the cycle events to this Billboard instance this.options.cycle.before = function(){ I._beforeSetIndex.apply(I, arguments); }; this.options.cycle.after = function(){ I._afterSetIndex.apply(I, arguments); }; }, options:{ cycle:{ startingSlide:0, activePagerClass:"active", fastOnEvent:500, fx:"fade", pause:true, timeout:5500 } }, _init:function(evt){ var I = this; //Bind to pager buttons this.el.$pager = this.el.$container.find("span.pager"); this.el.$pager.children("a").click(function(evt){ I.setIndex($(this).attr("data-index")); return false; }); //Create the jQuery.cycle this.el.$ulSlides = this.el.$container.find("ul.slides"); this.el.$ulSlides.cycle(this.options.cycle); //Bind all static context links var contextAliases = { Billboard:this }; this.bindContextAttr("click", this.el.$container.find("a[href^='#Billboard']"), "href", contextAliases, "#", true); //Some kind of IE6 bug where the tabs aren't showing...here's the fix if(site.isIE6){ setTimeout(function(){ I.el.$pager.children("a").addClass("ie6"); }, 1); } }, _setIndex:function(evt, index){ this.el.$ulSlides.cycle(parseInt(index)); }, _beforeSetIndex:function(currentSlideEl, nextSlideEl, options, forwardFlag){ if(this.el.$pager.length){ //Set the highlighted pager item var activeIndex = this.getSlideIndex(nextSlideEl); this.el.$pager.children("a").removeClass(options.activePagerClass).eq(activeIndex).addClass(options.activePagerClass); } }, _afterSetIndex:function(currentSlideEl, nextSlideEl, options, forwardFlag){ $(currentSlideEl).addClass("active").siblings("li").removeClass("active"); }, _play:function(evt){ this.el.$ulSlides.cycle("resume"); }, _pause:function(evt){ this.el.$ulSlides.cycle("pause"); }, _prev:function(evt){ this.el.$ulSlides.cycle("prev"); }, _next:function(evt){ this.el.$ulSlides.cycle("next"); }, getSlideIndex:function(slideEl){ var idx = -1; this.el.$ulSlides.children().each(function(i){ if(this === slideEl){ idx = i; return false; } }); return idx; } }); /* Maxims .......................................................... */ site.component.Maxims = site.Component.extend({ className:"Maxims", construct:function(){ var I = this; // http://jquery.malsup.com/cycle/options.html this._super.apply(this, arguments); this.createDispatcher({setIndex:"_setIndex"}); this.createDispatcher({play:"_play"}); this.createDispatcher({pause:"_pause"}); this.createDispatcher({prev:"_prev"}); this.createDispatcher({next:"_next"}); //Relay the cycle events to this component instance this.options.cycle.before = function(){ I._beforeSetIndex.apply(I, arguments); }; this.options.cycle.after = function(){ I._afterSetIndex.apply(I, arguments); }; }, options:{ cycle:{ activePagerClass:"active", containerResize:false, fastOnEvent:500, fx:"scrollHorz", height:"auto", pause:true, slideResize:false, startingSlide:0, timeout:0 } }, _init:function(evt){ var I = this; //Bind to pager buttons this.el.$pager = this.el.$container.find("span.pager"); this.el.$pager.children("a").click(function(evt){ I.setIndex($(this).attr("data-index")); return false; }); //Create the jQuery.cycle this.el.$ulSlides = this.el.$container.find("ul.slides"); //this.el.$ulSlides.height(this.el.$ulSlides.outerHeight(true)); //Set the container's height to the same as the first slide this.el.$ulSlides.cycle(this.options.cycle); //Bind all static context links var contextAliases = { Maxims:this }; this.bindContextAttr("click", this.el.$container.find("a[href^='#Maxims']"), "href", contextAliases, "#", true); }, _setIndex:function(evt, index){ this.el.$ulSlides.cycle(parseInt(index)); }, _beforeSetIndex:function(currentSlideEl, nextSlideEl, options, forwardFlag){ if(this.el.$pager.length){ //Set the highlighted pager item var highlightIndex = this.getSlideIndex(nextSlideEl); this.el.$pager.children("a").removeClass(options.activePagerClass).eq(highlightIndex).addClass(options.activePagerClass); } }, _afterSetIndex:function(currentSlideEl, nextSlideEl, options, forwardFlag){ this.el.$ulSlides.stop().animate({height:$(nextSlideEl).outerHeight(true)}, {duration:300}); }, _play:function(evt){ this.el.$ulSlides.cycle("resume"); }, _pause:function(evt){ this.el.$ulSlides.cycle("pause"); }, _prev:function(evt){ this.el.$ulSlides.cycle("prev"); }, _next:function(evt){ this.el.$ulSlides.cycle("next"); }, getSlideIndex:function(slideEl){ var idx = -1; this.el.$ulSlides.children().each(function(i){ if(this === slideEl){ idx = i; return false; } }); return idx; } }); /* IE6 Warning .......................................................... */ site.component.IE6Warning = site.Component.extend({ className:"IE6Warning", construct:function(){ var I = this; this._super.apply(this, arguments); this.createDispatcher({position:"_position"}); }, _init:function(evt){ if(!site.isIE6){ this.el.$container.remove(); return false; } var I = this; this.el.$container.appendTo("body"); this.el.$container.slideDown(1000); site.el.$win.bind("scroll", function(){ I.position(); }); I.position(); this.el.$container.find(".btnClose").click(function(){ I.el.$container.slideUp(200); }); }, _position:function(){ this.el.$container.css({ top: site.el.$win.scrollTop() }); } }); /* Carousel .......................................................... */ site.component.Carousel = site.Component.extend({ className:"Carousel", construct:function(){ var I = this; console.log("test"); this._super.apply(this, arguments); this.createDispatcher({prev:"_prev"}); this.createDispatcher({next:"_next"}); this.createDispatcher({setContentIndex:"_setContentIndex"}); }, carousel:null, options:{ // http://sorgalla.com/projects/jcarousel/#Configuration carousel:{ start:1, scroll:1 } }, _init:function(){ var I = this; this.el.$ulSlides = this.el.$container.find("ul.slides"); this.el.$contents = this.el.$ulSlides.siblings("div.contents"); this.options.carousel.itemVisibleInCallback = { onBeforeAnimation:$.proxy(I.onBeforeItemVisible, I) }; //Create the carousel this.el.$ulSlides.parent().jcarousel(this.options.carousel); this.carousel = this.el.$container.data("jcarousel"); this.el.$ulSlides.delegate("li", "mouseover", function(evt){ $(this).addClass("hover"); }); this.el.$ulSlides.delegate("li", "mouseout", function(evt){ $(this).removeClass("hover"); }); this.el.$ulSlides.delegate("li", "click", function(evt){ var idx = parseInt($(this).attr("data-index")); I.setContentIndex(idx); }); //Set start item as active this._contentIndex = this.options.carousel.start-1; this.el.$contents.children("div").not(":eq("+this._contentIndex+")").css({opacity:0}); this.el.$ulSlides.children("li").eq(this._contentIndex).addClass("active"); this.el.$contents.children("div").eq(this._contentIndex).addClass("active"); //Bind events to context attributes this.bindContextAttr("click", this.el.$container.find("a[href^='#Carousel']"), "href", {Carousel:this}, "#", true); }, _next:function(evt){ this.carousel.next(); }, _prev:function(evt){ this.carousel.prev(); }, _contentIndex:null, getContentIndex:function(){ return this._contentIndex; }, _setContentIndex:function(evt, index){ if(this._contentIndex === index) return evt.result = false; var $li = this.el.$ulSlides.children("li[data-index='"+index+"']"), $content = this.el.$contents.children("div").eq(index); this._contentIndex = index; //Unset previous actives $li.siblings("li.active").removeClass("active"); $content.siblings("div.active").removeClass("active"); //Set current actives $li.addClass("active"); $content.addClass("active"); $content.css({opacity:0}).animate({opacity:1}, { duration:"slow", complete:function(){ //IE has cleartype issues with text + opacity effects var styleObj = $content.get(0).style; if(styleObj && styleObj.removeAttribute){ styleObj.removeAttribute("filter"); } } }); }, onBeforeItemVisible:function(jcarousel, item, index, action, eventName){ if(this._contentIndex == (index-1)){ $(item).addClass("active"); } } }); /* Lightbox .......................................................... */ site.component.Lightbox = site.Component.extend({ className:"Lightbox", construct:function(el, options){ this._super.apply(this, arguments); site.component.Lightbox.instances.push(this); this.createDispatcher({open:"_open"}); this.createDispatcher({close:"_close"}); this.createDispatcher({position:"_position"}); this.createDispatcher({load:"_load"}); }, options:{ initDisplay:false, screenOpacity:.75, loadingClass:"loading" }, _init:function(evt){ var I = this; if(!this.el.$container) return false; this.el.$container.addClass("hidden"); this.el.$title = this.el.$container.find(".title").first(); this.el.$content = this.el.$container.find("div.content").first(); this.el.$actions = this.el.$container.find("div.actions").first(); //site.el.$body.append(this.el.$container); this.el.$screen = $("
").appendTo("body"); this.el.$screen.css({position:"fixed", top:0, left:0, width:"100%", height:"100%", zIndex:9999, opacity:this.options.screenOpacity}); this.el.$screen.click($.proxy(this.close, this)); this.el.$container.insertAfter(this.el.$screen); this.bindContextAttr("click", this.el.$container.find("a[href^=#Lightbox]"), "href", {window:window, Lightbox:this}, "#", true); if(this.options.initDisplay){ this.open(); } }, _open:function(evt){ this.el.$screen.removeClass("hidden").fadeIn("fast"); //show the bg screen this.el.$container.removeClass("hidden").css({display:"block", visibility:"hidden"}); //remove the hidden class from the container so we can get content heights, but keep it invisible //this.position(); this.el.$container.css({visibility:"visible", position:"fixed", zIndex:parseInt(this.el.$screen.css("zIndex")) + 1}); this.position(); }, _close:function(evt){ this.el.$screen.fadeOut("fast", function(){ //$(this).addClass("hidden").attr("style",""); }); this.el.$container.addClass("hidden").hide().removeAttr("style"); this.el.$content.removeAttr("style"); }, _position:function(evt){ var maxHeight = site.el.$win.height() - (this.el.$container.outerHeight(true) - this.el.$container.height()), titleHeight = this.el.$title.outerHeight(true), actionsHeight = this.el.$actions.outerHeight(true), contentVertPad = this.el.$content.outerHeight(true) - this.el.$content.height(); if(this.el.$container.outerHeight(true) > maxHeight){ //Size the container this.el.$container.height(maxHeight); //Size the content this.el.$content.height(this.el.$content.parent("div").innerHeight() - titleHeight - actionsHeight - contentVertPad); }else{ } this.el.$container.center(); }, _load:function(evt, url, ajaxOpts){ var I = this; I.el.$container.addClass(I.options.loadingClass); var opts = $.extend({ url:url, success:function(data, status, xhr){ I.el.$content.html(xhr.responseText); }, error:function(xhr, status, error){ I.el.$title.html(status); I.el.$content.html(error.toString()); }, complete:function(){ //console.log(arguments); I.el.$container.removeClass(I.options.loadingClass); I.position(); } }, ajaxOpts); return $.ajax(opts); } }); site.component.Lightbox.instances = []; site.component.Lightbox.generate = function(title, content, $template){ if(!$template){ $template = $("#lightboxTemplate"); } var $container = $template.clone(), $title = $container.find(".title").first(), $content = $container.find(".content").first(); site.el.$body.append($container); if(title){ $title.html(title); }else{ $title.html(""); } if(content){ $content.html(content); } return $container.controller(site.component.Lightbox); }; function getTabValue() { var vars = [], hash,tabSerach,tabvalue; var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); tabSerach = window.location.href; if((tabSerach.search("tabValue=") != -1)) { for(var i = 0; i < hashes.length; i++) { hash = hashes[i].split('='); vars.push(hash[0]); vars[hash[0]] = hash[1]; } tabvalue=vars['tabValue']-1; } else { tabvalue='0'; } return tabvalue; } /* Tabset .......................................................... */ site.component.Tabset = site.Component.extend({ className:"Tabset", construct:function(el, options){ this._super.apply(this, arguments); var I = this; this.createDispatcher({showTab:"_showTab", beforeShowTab:null, afterShowTab:null}); this.createDispatcher({toggleSubSection:"_toggleSubSection", beforeToggleSubSection:null, afterToggleSubSection:null}); }, options:{ initTab:getTabValue(), activeClass:"tabsetActive" }, _init:function(evt){ var I = this; this.el.$tabs = this.el.$container.children(".tabsetTabs").children("a"); this.el.$contents = this.el.$container.children(".tabsetContents").children(".tabsetContent"); //Bind to the tab clicks this.el.$tabs.click(function(evt){ var idx = $(this).prevAll("a").length; I.showTab(idx); return false; }); this.showTab(this.options.initTab); }, prevTab:null, currentTab:null, _beforeShowTab:function(evt, index){ if(this.currentTab === index){ return false; } }, _showTab:function(evt, index){ this.prevTab = this.currentTab; this.currentTab = index; this.el.$tabs.not(":eq("+index+")").removeClass(this.options.activeClass); this.el.$contents.not(":eq("+index+")").removeClass(this.options.activeClass); this.el.$tabs.filter(":eq("+index+")").addClass(this.options.activeClass); this.el.$contents.filter(":eq("+index+")").removeClass("hidden").addClass(this.options.activeClass); } }); /* Accordion .......................................................... */ site.component.Accordion = site.Component.extend({ className:"Accordion", construct:function(el, options){ this._super.apply(this, arguments); var I = this; this.createDispatcher({showPane:"_showPane", beforeShowPane:null, afterShowPane:null}); this.createDispatcher({hidePane:"_hidePane"}); }, options:{ fixedHeight:false, expandMultiple:true, expandSpeed:"fast", expandedClass:"expand" }, _init:function(evt){ var I = this; this.el.$panes = this.el.$container.children("div.pane"); this.el.$paneTitles = this.el.$panes.children(".title"); this.el.$paneContents = this.el.$panes.children(".content"); this.el.$btnExpandAll = this.el.$container.find("> .expand-collapse > .expand > a"); this.el.$btnCollapseAll = this.el.$container.find("> .expand-collapse > .collapse > a"); $("*").children().first().addClass("first"); $("*").children().last().addClass("last"); //Bind to the title this.el.$paneTitles.children("a").click(function(evt){ var idx = $(this).closest("div.pane").prevAll("div.pane").length; I.togglePane(idx); return false; }); //Bind to expand/collapse all this.el.$btnExpandAll.click(function(evt){ I.showAllPanes(); }); this.el.$btnCollapseAll.click(function(evt){ I.hideAllPanes(); }); //Set initially expanded panes this.el.$panes.each(function(p){ if($(this).is("."+I.options.expandedClass)){ $(this).removeClass(I.options.expandedClass); I.showPane(p, true); }else{ I.hidePane(p, true); } }); }, _showPane:function(evt, index, instant){ var I = this, $pane = this.el.$panes.eq(index); //If only one pane is allowed to be expanded at a time... if(!this.options.expandMultiple){ this.el.$panes.each(function(p, pane){ if(p !== index){ I.hidePane(p); } }); } //Show the requested pane if($pane.length && !$pane.hasClass(I.options.expandedClass)){ $pane.stop(); /*$pane.children(".content").slideDown(this.options.expandSpeed, function(){ $pane.addClass(I.options.expandedClass); }); return;*/ $pane.addClass(I.options.expandedClass); var $content = $pane.children(".content"), animateCss = { height:"show", marginBottom:"show", marginTop:"show", paddingTop:"show", paddingBottom:"show" }, animateOpts = { duration: !instant ? this.options.expandSpeed : 0 }; if(this.options.fixedHeight){ var containerHeight = this.el.$container.height(); //get the computed height of the container in case it's a percentage or something var takenHeight = 0; this.el.$panes.each(function(p, pane){ var $pane = $(pane); //takenHeight += $pane.children(".title").outerHeight(); if(p === index || !$pane.hasClass(I.options.expandedClass)){ //If requested pane or not expanded, add the height without content takenHeight += $pane.outerHeight() - $pane.children(".content:visible").outerHeight(); }else{ takenHeight += $pane.outerHeight(); } }); animateCss.height = containerHeight - takenHeight - 30; } //Show it. $pane.children(".content").animate(animateCss, animateOpts); } }, _hidePane:function(evt, index, instant){ var I = this, $pane = this.el.$panes.eq(index); if($pane.length && $pane.hasClass(I.options.expandedClass)){ $pane.stop(); $pane.removeClass(I.options.expandedClass); var $content = $pane.children(".content"), animateCss = { height:"hide", marginBottom:"hide", marginTop:"hide", paddingTop:"hide", paddingBottom:"hide" }, animateOpts = { duration: !instant ? this.options.expandSpeed : 0, complete:function(){ //Remove relevant style properties for(var propName in animateCss){ animateCss[propName]=""; } animateCss.display=""; $content.css(animateCss); } }; //Hide it. $content.css({display:"block"}).animate(animateCss, animateOpts); } }, togglePane:function(index){ var $pane = this.el.$panes.eq(index); if($pane.hasClass(this.options.expandedClass)){ this.hidePane(index); }else{ this.showPane(index); } return this; }, showAllPanes:function(){ var I = this; this.el.$panes.each(function(p, pane){ I.showPane(p); }); }, hideAllPanes:function(){ var I = this; this.el.$panes.each(function(p, pane){ I.hidePane(p); }); } }); /* Component Tab Controller .......................................................... */ site.component.ComponentTabController = site.Component.extend({ className:"ComponentTabController", construct:function(el, options){ this._super.apply(this, arguments); }, tabset:null, _init:function(){ var I = this; this.el.$tabset = this.el.$container; this.el.$tabs = this.el.$tabset.children(".tabsetTabs"); var tabCount = this.el.$tabs.children("a").length; //Move the components into the contents area of the tabset this.el.$componentWraps = this.el.$container.closest(".ls-cmp-wrap").nextAll("div.ls-cmp-wrap").not(":gt("+(tabCount-1)+")"); this.el.$componentWraps.find("script").remove(); //remove the scripts so they don't fire again this.el.$tabset.children("div.tabsetContents").empty().append(this.el.$componentWraps.addClass("tabsetContent")); //Create the tabset this.el.$componentWraps.first().addClass("active"); this.el.$tabs.children("a").first().addClass("active"); this.tabset = this.el.$tabset.controller(franklin.site.component.Tabset); } }); /* LinksList .......................................................... */ site.component.LinksList = site.Component.extend({ className:"LinksList", construct:function(){ this._super.apply(this, arguments); }, _init:function(evt){ } }); /* Quick Links (I am here to...) .......................................................... */ site.component.QuickLinks = site.Component.extend({ className:"QuickLinks", construct:function(){ this._super.apply(this, arguments); var I = this; I.createDispatcher({expand:"_expand"}); I.createDispatcher({collapse:"_collapse"}); }, options:{ expandSpeed:300, expandedClass:"expand" }, _init:function(evt){ var I = this; this.el.$container.removeClass(this.options.expandedClass); var $content = this.el.$container.find("div.content"); $content.data("originalHeight", $content.height()); this.el.$container.find(".trigger").click(function(evt){ I.toggle(); }); }, _expand:function(evt){ var $content = this.el.$container.find("div.content"); this.el.$container.addClass(this.options.expandedClass); $content.slideDown(this.options.expandSpeed); }, _collapse:function(evt){ var $content = this.el.$container.find("div.content"); this.el.$container.removeClass(this.options.expandedClass); $content.slideUp(this.options.expandSpeed); }, toggle:function(evt){ if(this.el.$container.hasClass(this.options.expandedClass)){ this.collapse(); }else{ this.expand(); } } }); /* EmailForm .......................................................... */ site.component.EmailForm = site.Component.extend({ className:"EmailForm", construct:function(el, options){ this._super.apply(this, arguments); var I = this; }, _init:function(evt){ var I = this; this.el.$form = this.el.$container; this.el.$errorMsg = this.el.$form.find("div.fluidError1"); this.el.$form.submit(function(evt){ return I.onFormSubmit(evt); }); }, onFormSubmit:function(evt){ var I = this; //Empty the validation message and this.el.$errorMsg.empty(); //Create the new message list var $ulErrors = $("
    ").appendTo(this.el.$errorMsg); this.el.$form.find(".wrapField:has(label > .required)").each(function(w, wrap){ var $wrap = $(wrap), $field = $wrap.find(".field :input"); if(($field.is(":checkbox") && !$field.is(":checked")) || ($field.not(":checkbox") && !$field.val() || !$field.val().length)){ $wrap.addClass("validError"); var errorMsg = $wrap.find("input[type='hidden'][name$='_required_msg']").val(); $ulErrors.append("
  • "+errorMsg+"
  • "); }else{ $wrap.removeClass("validError"); } }); if($ulErrors.children("li").length){ this.el.$errorMsg.removeClass("hidden"); return false; }else{ this.el.$errorMsg.addClass("hidden"); } } }); /* External Lightbox Component .......................................................... */ site.component.ExternalLightbox = site.component.Lightbox.extend({ className:"ExternalLightbox", construct:function(el, options){ var I = this; $.extend(this.options, site.component.Lightbox.prototype.options); if(options && options.safeHostnames){ //Replace the other hostnames with the ones passed in options I.options.safeHostnames = options.safeHostnames; delete options.safeHostnames; } this._super.apply(this, arguments); }, options:{ safeHostnames:["www.franklintempleton.com", "www.franklintempleton.it", "franklintempleton.it", "franklintempleton.sk", "www.franklintempleton.sk","franklintempleton.lu", "www.franklintempleton.lu", "a.blip.tv","www.ingim.com.mx","www.microsoft.com","www.apple.com","sta-historical.franklintempleton.com","www.franklinresources.com","historical.franklintempleton.com", "ebusiness.templeton-europe.com", "em.franklintempleton.ch", "em.franklintempleton.com.sg","mv.franklintempleton.com.sg", "frk.edgeboss.net","210.175.250.189"], // most of these are not a safe sites. it is a workaround to have a specific site message 2011-07-08 11:30 pm safeHostnames_IT:["www.franklintempleton.com", "www.franklintempleton.it", "franklintempleton.it", "franklintempleton.sk", "www.franklintempleton.sk", "a.blip.tv","www.ingim.com.mx","www.apple.com","sta-historical.franklintempleton.com","historical.franklintempleton.com", "ebusiness.templeton-europe.com", "em.franklintempleton.ch", "em.franklintempleton.com.sg", "brightcove.com", "bcove.me"], // most of these are not a safe sites. it is a workaround to have a specific site message 2011-07-08 11:30 pm safeHostnames_campaigns:[ "www.franklintempleton.com", "franklintempleton.sk", "www.franklintempleton.sk", "franklintempleton.de", "www.franklintempleton.de", "franklintempleton.at", "www.franklintempleton.at", "franklintempleton.lu", "www.franklintempleton.lu", "templetonoffshore.com", "www.templetonoffshore.com", "franklintempleton.com.mx", "www.franklintempleton.com.mx", "franklintempleton.com.pt", "www.franklintempleton.com.pt", "franklintempleton.co.kr", "www.franklintempleton.co.kr", "franklintempleton.com.es", "www.franklintempleton.com.es", "franklintempleton.com.sg", "www.franklintempleton.com.sg", "sta-historical.franklintempleton.com", "www.franklinresources.com", "historical.franklintempleton.com", "cam.franklintempleton.com", "pre-cam.franklintempleton.com", "origin-cam.franklintempleton.com", "ebusiness.templeton-europe.com", "global.beyondbullsandbears.com"], defaultTarget:"_blank" }, _init:function(){ this._super.apply(this, arguments); var I = this; I.el.$goLink = I.el.$container.find("a.goExternal"), I.el.$cancelLink = I.el.$container.find("a.cancel"); I.el.$goLink.click($.proxy(I.close, I)); //Bind to the links $("a:external:not(.goExternal)").live("click", $.proxy(I._onExternalLinkClick, I)); }, _onExternalLinkClick:function(evt){ //alert(link.href + " : " +hostname+" : "+ window.location + ":" + window.document.location.href); // Modified due to QC 3034 & QC XXX var I = this; link = evt.currentTarget; hostname = link.hostname; safeIndex = $.inArray(hostname, I.options.safeHostnames); var searchURL = window.document.location.href; if((searchURL.search("it_IT") != -1)||(searchURL.search("franklintempleton.it") != -1)||(searchURL.search("ja_JP") != -1)||(searchURL.search("franklintempleton.co.jp") != -1)) { safeIndex = $.inArray(hostname, I.options.safeHostnames_IT); } if ((searchURL.search("cam.franklintempleton.com") != -1) || (searchURL.search("origin-cam.franklintempleton.com") != -1)) { safeIndex = $.inArray(hostname, I.options.safeHostnames_campaigns); } I.log("External link clicked: ", hostname, "("+(safeIndex >= 0 ? "safe (index "+safeIndex+" )" : "unsafe")+")"); if(safeIndex < 0){ I.populate({hostname:hostname}); I.el.$goLink.attr("href", link.href); I.el.$goLink.attr("target", link.getAttribute("target") || I.options.defaultTarget); I.open(); return false; } } }); /* Footer Component .......................................................... */ site.component.Footer = site.Component.extend({ className:"Footer", construct:function(el, options){ this._super.apply(this, arguments); }, _init:function(){ } }); /* Fund Listing .......................................................... */ site.component.FundListing = site.Component.extend({ className:"FundListing", construct:function(el, options){ this._super.apply(this, arguments); var I = this; this.createDispatcher({filterFunds:"_filterFunds"}); }, _init:function(evt){ var I = this; this.el.$fundTable = this.el.$container.find("table.fundListing"); //Prep the filter dropdowns and reset button this.el.$fundFilter = this.el.$container.find("table:first"); this.el.$selVehicles = this.el.$container.find("select[name='vehicles']"); this.el.$selCategories = this.el.$container.find("select[name='categories']"); this.el.$btnReset = this.el.$container.find("a.reset"); this.el.$selVehicles.change(function(){ I.filterFunds($(this).val(), I.el.$selCategories.val()); }); this.el.$selCategories.change(function(){ I.filterFunds(I.el.$selVehicles.val(), $(this).val()); }); this.el.$btnReset.click(function(){ I.el.$selVehicles.val(""); I.el.$selCategories.val(""); I.filterFunds(); return false; }); //Get query strings for filter defaults I.el.$selVehicles.val(this.getQueryString("vehicle")); I.el.$selCategories.val(this.getQueryString("category")); //Filter rows initially I.filterFunds(I.el.$selVehicles.val(), I.el.$selCategories.val()); }, _filterFunds:function(evt, vehicleId, categoryId){ var $fundRows = this.el.$fundTable.find("tr[data-category]"), $vehicleHeaders = this.el.$fundTable.find("tr.thead2[data-vehicle]"); //If a Vehicle filter is chosen, remove the other headers $vehicleHeaders.removeClass("hidden"); if(vehicleId != null && vehicleId != ""){ $vehicleHeaders.not("[data-vehicle='"+vehicleId+"']").addClass("hidden"); } var vehiclesVisible = []; this.log(vehicleId, categoryId); //Filter the funds $fundRows.each(function(r, tr){ var $tr = $(tr), isVehicleMatch = (vehicleId == null || vehicleId == "" || vehicleId == $tr.attr("data-vehicle")), isCategoryMatch = (categoryId == null || categoryId == "" || categoryId == $tr.attr("data-category")); if(isVehicleMatch && isCategoryMatch){ $tr.removeClass("hidden"); vehiclesVisible.push($tr.attr("data-vehicle")); } //Hide by default else{ $tr.addClass("hidden"); } }); //Finally, remove any Vehicle headers without items $vehicleHeaders.filter(function(){ return $.inArray($(this).attr("data-vehicle"), vehiclesVisible) == -1; }).addClass("hidden"); } }); /* Fund Identities .......................................................... */ site.component.FundIdentities = site.Component.extend({ className:"FundIdentities", construct:function(el, options){ this._super.apply(this, arguments); var I = this; this.createDispatcher({filterFunds:"_filterFunds"}); }, _init:function(evt){ var I = this; this.el.$wrapFund = this.el.$container.find("div.wrapFund"); this.el.$formFilter = this.el.$container.find("form.filter"); this.el.$selCategory = this.el.$formFilter.find("select[name='category']"); this.el.$selCategory.change(function(evt){ I.filterFunds(this.value); }); }, _filterFunds:function(evt, category){ if(!category || category.length < 1){ //Show all categories this.el.$wrapFund.removeClass("hidden"); }else{ //Filter by selected category this.el.$selCategory.val(category); this.el.$wrapFund.removeClass("hidden").not("[data-category='"+category+"']").addClass("hidden"); } } }); /* Fund Performance .......................................................... */ site.component.FundPerformance = site.Component.extend({ className:"FundPerformance", construct:function(el, options){ this._super.apply(this, arguments); var I = this; this.createDispatcher({filterFunds:"_filterFunds"}); }, _init:function(evt){ var I = this; this.el.$fundTable = this.el.$container.find("table.tblFundPerformance"); //Prep the filter dropdowns and reset button this.el.$fundFilter = this.el.$container.find(".filter"); this.el.$selVehicles = this.el.$container.find("select[name='vehicles']"); this.el.$selCategories = this.el.$container.find("select[name='categories']"); this.el.$selShareClasses = this.el.$container.find("select[name='share_classes']"); this.el.$btnReset = this.el.$container.find("a.reset"); this.el.$selVehicles.change(function(){ I.filterFunds($(this).val(), I.el.$selCategories.val(), I.el.$selShareClasses.val(),I.el.$fundTable.find("input:radio:checked").val() ); }); this.el.$selCategories.change(function(){ I.filterFunds(I.el.$selVehicles.val(), $(this).val(), I.el.$selShareClasses.val(), I.el.$fundTable.find("input:radio:checked").val() ); }); this.el.$selShareClasses.change(function(){ I.filterFunds(I.el.$selVehicles.val(), I.el.$selCategories.val(), I.el.$selShareClasses.val(), I.el.$fundTable.find("input:radio:checked").val()); }); this.el.$btnReset.click(function(){ I.el.$selVehicles.val(""); I.el.$selCategories.val(""); I.el.$selShareClasses.val(""); I.filterFunds(); return false; }); //Get query strings for filter defaults I.el.$selVehicles.val(this.getQueryString("vehicle")); I.el.$selCategories.val(this.getQueryString("category")); I.el.$selShareClasses.val(this.getQueryString("shareClass")); //Filter rows initially I.filterFunds(I.el.$selVehicles.val(), I.el.$selCategories.val(), I.el.$selShareClasses.val()); this.el.$fundTable.find("input:radio").change(function(evt){ I.filterFunds(I.el.$selVehicles.val(), I.el.$selCategories.val(), I.el.$selShareClasses.val(),this.value); }); I.filterFunds(I.el.$selVehicles.val(), I.el.$selCategories.val(), I.el.$selShareClasses.val(),this.el.$fundTable.find("input:radio:checked").val()); }, _filterFunds:function(evt, vehicleId, categoryId, shareClass, performanceType){ var $fundRows = this.el.$fundTable.find("tr[data-category]"), $vehicleHeaders = this.el.$fundTable.find("tr.thead3[data-vehicle]"), $vehicleHeaders4 = this.el.$fundTable.find("tr.thead4[data-vehicle]"), $cpHeader = this.el.$fundTable.find("tr[cpheader]"), $pHeader = this.el.$fundTable.find("tr[pheader]"), $apHeader = this.el.$fundTable.find("tr[apheader]"), vehiclesVisible = []; this.log("filterFunds", arguments); if (performanceType == "calendar") { $cpHeader.each(function(r, tr){ var $tr = $(tr); $tr.removeClass("hidden"); }); }else{ $cpHeader.each(function(r, tr){ var $tr = $(tr); $tr.addClass("hidden"); }); } if (performanceType == "annualized") { $apHeader.each(function(r, tr){ var $tr = $(tr); $tr.removeClass("hidden"); }); }else{ $apHeader.each(function(r, tr){ var $tr = $(tr); $tr.addClass("hidden"); }); } if (performanceType == "cumulative") { $pHeader.each(function(r, tr){ var $tr = $(tr); $tr.removeClass("hidden"); }); }else{ $pHeader.each(function(r, tr){ var $tr = $(tr); $tr.addClass("hidden"); }); } //Filter the funds $fundRows.each(function(r, tr){ var $tr = $(tr), isVehicleMatch = (vehicleId == null || vehicleId == "" || vehicleId == $tr.attr("data-vehicle")), isCategoryMatch = (categoryId == null || categoryId == "" || categoryId == $tr.attr("data-category")), isShareClassMatch = (shareClass == null || shareClass == "" || shareClass == $tr.attr("data-shareClass")), isPerformanceTypeMatch = (performanceType == null || performanceType == "" || performanceType == $tr.attr("data-performance")); if(isVehicleMatch && isCategoryMatch && isShareClassMatch && isPerformanceTypeMatch){ $tr.removeClass("hidden"); vehiclesVisible.push($tr.attr("data-vehicle")); } //Hide by default else{ $tr.addClass("hidden"); } }); //Toggle Vehicle headers $vehicleHeaders.each(function(){ var $tr = $(this), isPerformanceTypeMatch = (performanceType == null || performanceType == "" || performanceType == $tr.attr("data-performance")); if(!isPerformanceTypeMatch){ $tr.addClass("hidden"); } //Hide by default else{ if (($.inArray($tr.attr("data-vehicle"), vehiclesVisible) == -1)){ $tr.addClass("hidden"); }else{ $tr.removeClass("hidden"); } } }); } }); /* Fund Prices .......................................................... */ site.component.FundPrices = site.component.FundPerformance.extend({ className:"FundPrices", _init:function(){ this._super.apply(this, arguments); this.el.$fundTable = this.el.$container.find("table.tblFundPrices"); } }); /* Fund Dividends .......................................................... */ site.component.FundDividends = site.Component.extend({ className:"FundDividends", construct:function(){ this._super.apply(this, arguments); var I = this; this.createDispatcher({filterFunds:"_filterFunds"}); }, _init:function(){ var I = this; //******************************************************************** this.el.$fundTable = this.el.$container.find("table.tblFundDividends"); //Prep the filter dropdowns and reset button this.el.$fundFilter = this.el.$container.find("table:first"); this.el.$selVehicles = this.el.$container.find("select[name='vehicles']"); this.el.$selCategories = this.el.$container.find("select[name='categories']"); this.el.$selShareClasses = this.el.$container.find("select[name='share_classes']"); this.el.$btnReset = this.el.$container.find("a.reset"); this.el.$selVehicles.change(function(){ I.filterFunds($(this).val(), I.el.$selCategories.val(), I.el.$selShareClasses.val()); }); this.el.$selCategories.change(function(){ I.filterFunds(I.el.$selVehicles.val(), $(this).val(), I.el.$selShareClasses.val()); }); this.el.$selShareClasses.change(function(){ I.filterFunds(I.el.$selVehicles.val(), I.el.$selCategories.val(), I.el.$selShareClasses.val()); }); this.el.$btnReset.click(function(){ I.el.$selVehicles.val(""); I.el.$selCategories.val(""); I.el.$selShareClasses.val(""); I.filterFunds(); return false; }); //Filter rows initially I.filterFunds(I.el.$selVehicles.val(), I.el.$selCategories.val()); //******************************************************************** }, _filterFunds:function(evt, vehicleId, categoryId, shareClass){ var $fundRows = this.el.$fundTable.find("tr[data-category]"), $vehicleHeaders = this.el.$fundTable.find("tr.thead2[data-vehicle]"), vehiclesVisible = []; this.log("filterFunds", arguments); //Filter the funds $fundRows.each(function(r, tr){ var $tr = $(tr), isVehicleMatch = (vehicleId == null || vehicleId == "" || vehicleId == $tr.attr("data-vehicle")), isCategoryMatch = (categoryId == null || categoryId == "" || categoryId == $tr.attr("data-category")), isShareClassMatch = (shareClass == null || shareClass == "" || shareClass == $tr.attr("data-shareClass")); if(isVehicleMatch && isCategoryMatch && isShareClassMatch){ $tr.removeClass("hidden"); vehiclesVisible.push($tr.attr("data-vehicle")); } //Hide by default else{ $tr.addClass("hidden"); } }); //Toggle Vehicle headers $vehicleHeaders.each(function(){ var $tr = $(this); if($.inArray($tr.attr("data-vehicle"), vehiclesVisible) == -1){ $tr.addClass("hidden"); }else{ $tr.removeClass("hidden"); } }); } }); /* Gateway Component .......................................................... */ site.component.Gateway = site.Component.extend({ className:"Gateway", construct:function(el, options){ this._super.apply(this, arguments); this.createDispatcher({setActor:"_setActor"}); this.createDispatcher({showActors:"_showActors"}); this.createDispatcher({showLogin:"_showLogin"}); this.createDispatcher({validateLogin:"_validateLogin"}); this.createDispatcher({showTerms:"_showTerms"}); }, _init:function(){ var I = this; site.el.$pgCanvas.addClass("gateway"); // Add the "gateway" class to the canvas. This should probably be moved to a page controller, but I think it is too little to warrant it, and will not conflict with other components or page controllers at this point. Ideally, it should be done server-side. this.el.$form = this.el.$container.find("form"); this.el.$formFields = this.el.$form.find(":input"); this.el.$inputActorDefault = this.el.$formFields.filter("[name='actor']").val(); this.el.$inputActor = this.el.$formFields.filter("[name='actor']").val(""); this.el.$interact = this.el.$container.find("div.interact"); this.el.$actorChoice = this.el.$interact.find("div.actorChoice"); this.el.$actorChoiceLinks = this.el.$actorChoice.find("a[data-actor]"); this.el.$login = this.el.$interact.find("div.login"); this.el.$userid = this.el.$interact.find("span.userId"); //Create the terms lightbox this.el.$terms = this.el.$container.find("div.terms"); this.termsLightbox = this.el.$terms.controller(franklin.site.component.Lightbox, null, true); this.el.$termsAgree = I.el.$form.find("input[name='termsAgree']"); this.el.$termsAgreeCheckbox = I.el.$terms.find(":checkbox[name='termsAgree']"); this.el.$showLoginOnLoad = I.el.$form.find("input[name='showLoginOnLoad']"); this.el.$passwordOnly = I.el.$form.find("input[name='passwordOnly']"); //Bind to the form submit/reset for gateway passage sequence this.el.$form.bind("submit", $.proxy(this._formSubmit, this)); this.el.$form.bind("reset", $.proxy(this._formReset, this)); this.log("Gateway actors", this.actors); if (this.el.$inputActorDefault != '') { I.setActor(this.el.$inputActorDefault); } //Bind to the actor buttons this.el.$actorChoiceLinks.click(function(evt){ I.setActor($(this).attr("data-actor")); return false; }); //Bind to the login submit button this.el.$login.find(":submit").click(function(evt){ I._validateLogin(); }); //Since the Lightbox class moves the terms element out of the form, we need to relay some events back to the Gateway form //If the terms agree checkbox exists... if(this.el.$termsAgreeCheckbox.length){ //Set the terms agree button to disabled this.el.$terms.find(":submit").attr("disabled","disabled").parent("span").addClass("disabled"); this.el.$termsAgreeCheckbox.change(function(evt){ var checked = $(this).is(":checked"); I.el.$termsAgree.val( checked+"" ); //Toggle terms agree button if(checked){ I.el.$terms.find(":submit").removeAttr("disabled").parent("span").removeClass("disabled"); }else{ I.el.$terms.find(":submit").attr("disabled","disabled").parent("span").addClass("disabled"); } }); }else{ //Change terms agree value on button click, if the checkbox is not required this.el.$terms.find("input[name='btnTermsAgree']").click(function(evt){ I.el.$termsAgree.val("true"); }); } this.el.$terms.find(":submit").click(function(evt){ I.el.$form.submit(); }); this.el.$terms.find(":reset").click(function(evt){ I.el.$termsAgree.val("false"); I.el.$form.trigger("reset"); }); //Kickstart the process by trying to submit the form this.el.$form.submit(); }, actors:{}, getActor:function(){return this.actors[this.el.$inputActor.val()]; }, _setActor:function(evt, actorKey){ this.el.$inputActor.val(actorKey); //Hide the terms that do not apply to this actor this.el.$terms.find("[data-actor]").each(function(){ if($(this).attr("data-actor") == actorKey){ $(this).removeClass("hidden"); }else{ $(this).addClass("hidden"); } }); this.el.$form.submit(); }, _showActors:function(evt){ this.el.$actorChoice.removeClass("hidden"); this.el.$login.addClass("hidden"); this.termsLightbox.close(); }, _showLogin:function(evt){ this.el.$actorChoice.addClass("hidden"); this.el.$login.removeClass("hidden"); if (this.el.$passwordOnly.val() == "true") { this.el.$userid.addClass("hidden"); } this.termsLightbox.close(); }, _isLoginSet:false, isLoginSet:function(){ return this._isLoginSet; }, _validateLogin:function(){ var isValid = true; //Empty the validation message and var $errorMsg = this.el.$login.find("div.fluidError1").empty(); //Create the new message list var $ulErrors = $("
      ").appendTo($errorMsg); var $user=this.el.$login.find("input[name='userid']"); var $pass=this.el.$login.find("input[name='password']"); var pass = $pass.val(); var passtest = ""; var passtest2 = ""; var titleText = $("title").text(); var searchURL = window.document.location.href; if((searchURL.search("it_IT") != -1)||(searchURL.search("franklintempleton.it") != -1)){ //if (titleText == "Franklin Templeton Investments, Itaila" || titleText == "Franklin Templeton Investments, Italia"){ passtest = "Globale2"; passtest2 = "zxc"; } if (this.el.$passwordOnly.val() == "true") { $user.val($pass.val()); } this.el.$login.find(".wrapField:has(label > .required)").each(function(w, wrap){ var $wrap = $(wrap), $field = $wrap.find(".field :input"); if(($field.is(":checkbox") && !$field.is(":checked")) || ($field.not(":checkbox") && !$field.val() || !$field.val().length)){ $wrap.addClass("validError"); if((searchURL.search("it_IT") != -1)||(searchURL.search("franklintempleton.it") != -1)){ //if (titleText == "Franklin Templeton Investments, Itaila" || titleText == "Franklin Templeton Investments, Italia"){ var errorMsg = $wrap.find("input[type='hidden'][name$='password_required_msg']").val(); }else{ var errorMsg = $wrap.find("input[type='hidden'][name$='_required_msg']").val(); } $ulErrors.append("
    • "+errorMsg+"
    • "); isValid = false; }else{ //if (titleText == "Franklin Templeton Investments, Itaila" || titleText == "Franklin Templeton Investments, Italia"){ if((searchURL.search("it_IT") != -1)||(searchURL.search("franklintempleton.it") != -1)){ if((pass == passtest)||(pass == passtest2)){ $wrap.removeClass("validError"); }else { $wrap.addClass("validError"); var errorMsg = $wrap.find("input[type='hidden'][name$='password_incorrect_msg']").val(); $ulErrors.append("
    • "+errorMsg+"
    • "); isValid = false; } }else{ $wrap.removeClass("validError"); } } }); if($ulErrors.children("li").length){ $errorMsg.removeClass("hidden"); return false; }else{ $errorMsg.addClass("hidden"); } return this._isLoginSet = isValid; }, isTermsSet:function(){ var is = this.el.$termsAgree.val() == "true" && (!this.el.$termsAgreeCheckbox.length || this.el.$termsAgreeCheckbox.is(":checked")); return is; }, _showTerms:function(){ //this.el.$terms.removeClass("hidden"); this.termsLightbox.open(); }, _formSubmit:function(evt){ //If actor is required and not set... if(this.isActorRequired && !this.getActor()){ this.showActors(); return false; } //If actor is set or not required, and the login is required and not set... if((!this.isLoginSet() && this.el.$showLoginOnLoad.val() == "true") || (!this.isLoginSet() && this.getActor().isLoginRequired)){ this.showLogin(); return false; } //If Terms of Condition is required if(!this.isTermsSet() && this.getActor().isTermsRequired){ this.showTerms(); return false; } return true; }, _formReset:function(evt){ this.setActor(null); this._isLoginSet = false; this.el.$login.find(":text").val(""); this.el.$showLoginOnLoad.val(""); this.el.$formFields.filter("[name='actor']").val(""); //restart the process by letting the form submit handle it this.el.$form.submit(); } }); /* Sectioned Tabset .......................................................... */ site.component.SectionedTabset = site.Component.extend({ className:"SectionedTabset", construct:function(el, options){ this._super.apply(this, arguments); var I = this; this.createDispatcher({toggleSubSection:"_toggleSubSection"}); }, options:{ sectionExpandClass:"expand" }, _init:function(evt){ var I = this; this.el.$tabset = this.el.$container.find("div[class^='tabset']"); this.el.$tabs = this.el.$tabset.children(".tabsetTabs").children("a"); this.el.$contents = this.el.$tabset.children(".tabsetContents").children(".tabsetContent"); this.tabset = this.el.$tabset.controller(site.component.Tabset); this.tabset.showTab(0); //Setup the sub section expandable areas this.el.$subSections = this.el.$contents.find("div.sections > div"); this.el.$subSections.find(" > h3 > a").click(function(evt){ I.toggleSubSection($(this).closest("div")); return false; }); }, _toggleSubSection:function(evt, sectionEl){ var $sectionEl = $(sectionEl); $sectionEl.toggleClass(this.sectionExpandClass); } }); /* Sectioned Accordion .......................................................... */ site.component.SectionedAccordion = site.Component.extend({ className:"SectionedAccordion", construct:function(el, options){ this._super.apply(this, arguments); var I = this; }, _init:function(evt){ var I = this; //Create the accordion this.el.$accordion = this.el.$container.find("div[class^='accordionStyle']"); this.accordion = this.el.$accordion.controller(site.component.Accordion, null, true); //Setup the sub section expandable areas /* this.el.$subSections = this.el.$contents.find("div.sections > div"); this.el.$subSections.find(" > h3 > a").click(function(evt){ I.toggleSubSection($(this).closest("div")); return false; }); */ } }); /* Header Component .......................................................... */ site.component.Header = site.Component.extend({ className:"Header", construct:function(el, options){ this._super.apply(this, arguments); }, _init:function(){ var I = this; this.el.$searchForm = this.el.$container.find("#siteSearch form"); //LiveSite only allows a form in a component to submit to itself, so we have to manually set the action URL var searchActionUrl = this.el.$searchForm.find("input[name='form_action']").val(); if(searchActionUrl && searchActionUrl.length){ this.el.$searchForm.attr("action", searchActionUrl); } //Don't let them search if the keywords are empty this.el.$searchForm.submit(function(evt){ var $q = I.el.$searchForm.find("input[name='q']"), query = $q.val(); placeholder = $q.attr("placeholder"); if(!query || !query.length || query === placeholder){ evt.preventDefault(); return false; } }); } }); /* Secondary Navigation Component .......................................................... */ site.component.SecondaryNavigation = site.Component.extend({ className:"SecondaryNavigation", construct:function(el, options){ this._super.apply(this, arguments); }, _init:function(){ //make hash links go to first child this.el.$container.find("a[href='#']").each(function(a, anchor){ //console.log(anchor.href); var $a = $(anchor), $firstChild = $a.siblings("ul").find("> li > a[href]").first(); if($firstChild.length){ $a.get(0).href = $firstChild.get(0).href; $a.get(0).hostname = $firstChild.get(0).hostname; } }); } }); /* Primary Landing .......................................................... */ site.component.PrimaryLanding = site.Component.extend({ className:"PrimaryLanding", construct:function(el, options){ this._super.apply(this, arguments); }, _init:function(){ } }); /* Commentary Listing .......................................................... */ site.component.CommentaryListing = site.Component.extend({ className:"CommentaryListing", construct:function(el, options){ this._super.apply(this, arguments); var I = this; this.createDispatcher({filter:"_filter"}); }, sorterOptions:{ sortList:[[0,1]], cssHeader:"sortable", headers:{ 2:{sorter:false} }, textExtraction:function(node){ //need to get the date from the data-sortDate attribute, if it exists var $node = $(node); if($node.is("[data-sortDate]")){ return $node.attr("data-sortDate"); }else{ return $node.text(); } } }, _init:function(evt){ var I = this; //Create the table sorter this.el.$tblCommentaryList = this.el.$container.find("table.tblCommentaryList"); this.el.$tblCommentaryList.tablesorter(this.sorterOptions); this.el.$filter = this.el.$container.find(".filter").first(); this.el.$filter.find("input:radio").change(function(evt){ I.filter(this.value); }); I.filter(this.el.$filter.find("input:radio:checked").val()); }, _filter:function(evt, months){ var I = this, now = new Date(), $colDates = this.el.$tblCommentaryList.find("tr > td.date[data-sortDate]"); //Filter by number of months $colDates.each(function(c, col){ var $col = $(col), sortDate = $col.attr("data-sortDate"), colDate = new Date(), allowedTimeDiff = (1000 * 60 * 60 * 24 * 30)*months; sortDate.replace(/^(\d{4})\-(\d{2})\-(\d{2}).*/, function(){ colDate.setYear(arguments[1]); colDate.setMonth(arguments[2]); colDate.setDate(arguments[3]); }); if(now - colDate > allowedTimeDiff){ $col.parent("tr").addClass("hidden"); }else{ $col.parent("tr").removeClass("hidden"); } I.log("filter", (now - colDate) + " : " + allowedTimeDiff); }); } }); /* Press Centre .......................................................... */ site.component.PressCentre = site.Component.extend({ className:"PressCentre", construct:function(el, options){ this._super.apply(this, arguments); var I = this; this.createDispatcher({filterReleases:"_filterReleases"}); this.createDispatcher({filterClippings:"_filterClippings"}); }, releasesSorterOptions:{ sortList:[[0,1]], cssHeader:"sortable", headers:{ 1:{sorter:false}, 2:{sorter:false} }, textExtraction:function(node){ //need to get the date from the data-sortDate attribute, if it exists var $node = $(node); if($node.is("[data-sortDate]")){ return $node.attr("data-sortDate"); }else{ return $node.text(); } } }, clippingsSorterOptions:{ sortList:[[0,1]], cssHeader:"sortable", headers:{ 1:{sorter:false}, 2:{sorter:false} }, textExtraction:function(node){ //need to get the date from the data-sortDate attribute, if it exists var $node = $(node); if($node.is("[data-sortDate]")){ return $node.attr("data-sortDate"); }else{ return $node.text(); } } }, _init:function(evt){ var I = this; //Create the Tabset this.el.$tabset = this.el.$container.find("div[class^='tabset']"); this.tabset = this.el.$tabset.controller(site.component.Tabset); //Prep the Releases this.el.$tblReleases = this.el.$container.find("table.tblReleases"); if(this.el.$tblReleases.find("> tbody > tr").length > 0){ //Create the Releases table sorter this.el.$tblReleases.tablesorter(this.releasesSorterOptions); //Create the Releases filter var $filter = this.el.$releasesFilter = this.el.$tabset.find("> div > div.releases").children(".filter"); $filter.find("input:radio").each(function(evt){ if($(this).is(":checked")){ I.filterReleases(this.value); } }).change(function(evt){ I.filterReleases(this.value); }); } //Prep the Clippings this.el.$tblClippings = this.el.$container.find("table.tblClippings"); if(this.el.$tblClippings.find("> tbody > tr").length > 0){ //Create the Clippings table sorter this.el.$tblClippings.tablesorter(this.clippingsSorterOptions); //Create the Clippings filter this.el.$clippingsFilter = this.el.$tabset.find("> div > div.clippings").children(".filter"); this.el.$clippingsFilter.find("input:radio").each(function(evt){ if($(this).is(":checked")){ I.filterClippings(this.value); } }).change(function(evt){ I.filterClippings(this.value); }); } }, _filterReleases:function(evt, months){ var I = this, $colDates = this.el.$tblReleases.find("td.date"), now = new Date(); //Filter by number of months $colDates.each(function(c, col){ var $col = $(col), sortDate = $col.attr("data-sortDate"), colDate = new Date(), allowedTimeDiff = (1000 * 60 * 60 * 24 * 30)*months; sortDate.replace(/^(\d{4})\-(\d{2})\-(\d{2}).*/, function(){ colDate.setYear(arguments[1]); colDate.setMonth(arguments[2]); colDate.setDate(arguments[3]); }); if(now - colDate > allowedTimeDiff){ $col.parent("tr").addClass("hidden"); }else{ $col.parent("tr").removeClass("hidden"); } I.log("filterReleases", (now - colDate) + " : " + allowedTimeDiff); }); //Toggle filter radio button states var $rdoFilters = this.el.$releasesFilter.find("input:radio[name$='filter_releases_range']"); $rdoFilters.each(function(){ var $rdo = $(this), $label = $("label[for='"+this.id+"']"); if($rdo.val() === months){ this.checked = true; $label.addClass("active"); }else{ this.checked = false; $label.removeClass("active"); } }); }, _filterClippings:function(evt, months){ var I = this, $colDates = this.el.$tblClippings.find("td.date"), now = new Date(); //Filter by number of months $colDates.each(function(c, col){ var $col = $(col), sortDate = $col.attr("data-sortDate"), colDate = new Date(), allowedTimeDiff = (1000 * 60 * 60 * 24 * 30)*months; sortDate.replace(/^(\d{4})\-(\d{2})\-(\d{2}).*/, function(){ colDate.setYear(arguments[1]); colDate.setMonth(arguments[2]); colDate.setDate(arguments[3]); }); if(now - colDate > allowedTimeDiff){ $col.parent("tr").addClass("hidden"); }else{ $col.parent("tr").removeClass("hidden"); } I.log("filterClippings", (now - colDate) + " : " + allowedTimeDiff); }); //Toggle filter radio button states var $rdoFilters = this.el.$clippingsFilter.find("input:radio[name$='filter_clippings_range']"); $rdoFilters.each(function(){ var $rdo = $(this), $label = $("label[for='"+this.id+"']"); if($rdo.val() === months){ this.checked = true; $label.addClass("active"); }else{ this.checked = false; $label.removeClass("active"); } }); }, tabset:null }); /* Contact Details .......................................................... */ site.component.ContactDetails = site.Component.extend({ className:"ContactDetails", construct:function(el, options){ this._super.apply(this, arguments); var I = this; }, _init:function(evt){ //Move a following contact form into this component this.el.$emailForm = this.el.$container.closest(".ls-cmp-wrap").nextAll("div.ls-cmp-wrap").filter(":has(form.emailForm)").first(); this.el.$container.find("div.replace").replaceWith(this.el.$emailForm); } }); })();