Slider

To create a basic content slider, use the following HTML, CSS, and JavaScript. The Slider can contain any HTML (images, videos, text quotes, etc.), is responsive by default and can be customized in the JavaScript.

HTML

The HTML below provides the basic framework for a slider where each "slide" consists of an image (node 1) and a link (node 2). Technically, a slide can contain any amount of HTML as long as it fits within the constraints of the slide itself.

<div id="eventSlider">
<div class="sliderMask">
<div class="sliderContainer animate">
<cfset request.pc_content_id = 1>
<cfset request.pc_image_id = 1>
<cfset request.pc_link_id = 2>
<cfquery name="qry_pc_itm_#request.pc_content_id#" dbtype="query">
select fld_name, fld_value, fld_itemlist_id from qry_pagexml where fld_content_id = #request.pc_content_id# order by fld_itemlist_id
</cfquery>

<cfset request.qry_pc_items = Evaluate("qry_pc_itm_#request.pc_content_id#")>

<cfset request.pc_count = 0>
<cfoutput query="request.qry_pc_items" group="fld_itemlist_id">
<cfset request.pc_count = request.pc_count + 1>

<div class="slide">
<!--- If the link is defined --->
<cfif IsDefined("pcItem_#request.pc_content_id#_#request.pc_count#_#request.pc_link_id#") and len(Evaluate("pcItem_#request.pc_content_id#_#request.pc_count#_#request.pc_link_id#"))>
<a href="#Evaluate('pcItem_#request.pc_content_id#_#request.pc_count#_#request.pc_link_id#')#">
<div class="slide-img" style="background-image:url(#Evaluate('pcItem_#request.pc_content_id#_#request.pc_count#_#request.pc_image_id#')#);"></div>
</a>

<cfelseif IsDefined("pcItem_#request.pc_content_id#_#request.pc_count#_#request.pc_image_id#")>
<div class="slide-img" style="background-image:url(#Evaluate('pcItem_#request.pc_content_id#_#request.pc_count#_#request.pc_image_id#')#);"></div>
</cfif>
</div>
</cfoutput>
</div>
</div>
<div id="slidePrev" <cfif (request.pc_count EQ 1)> style="visibility:hidden"</cfif>></div>
<div id="slideNext" <cfif (request.pc_count EQ 1)> style="visibility:hidden"</cfif>></div>
</div>

CSS

#eventSlider {
  position: relative;
}

.sliderMask {
  position: relative;
  margin: 0 auto;
  height: auto;
  overflow: hidden;
}

.sliderContainer {
  position: absolute;
  left: 0;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-flow: row nowrap;
      -ms-flex-flow: row nowrap;
          flex-flow: row;
}

.sliderContainer.animate {
  transition: .25s cubic-bezier(0.4,0.0,0.2,1);;
}

.slide {
  position: relative;
  float: left;
  width: 380px;
  -webkit-flex: 0 0 auto;
      -ms-flex: 0 0 auto;
          flex: 0 0 auto; 
}

.slide-img {
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: 56.25%;
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
}


#slideNext,
#slidePrev {
  position: absolute;
  top: 50%;
  z-index: 100;
  width: 26px;
  height: 26px;
  font-size: 26px;
  text-align: center;
  line-height: 26px;
  cursor: pointer;
}

#slidePrev {
  left: 0;
  -webkit-transform: translate(-150%, -50%);
      -ms-transform: translate(-150%, -50%);
          transform: translate(-150%, -50%);
}

#slideNext {
  right: 0;
  -webkit-transform: translate(150%, -50%);
      -ms-transform: translate(150%, -50%);
          transform: translate(150%, -50%);
}

JavaScript

Instead of adding the JS code manually, you can include /includes/slider/slider.js to the layout file, which will always have the latest updates. Example:

<cfset request._js_array = [
    "/includes/slider/slider.js",
    "/js/_globals.js",
    "/js/_home.js"
]>
<cfloop array="#request._js_array#" index="request._js_file">
    <cfset request._js_file_url = REReplaceNoCase(request._js_file, "((\.css)|(\.js))", ".#Application.fileAutoTimestamp.getTimestamp(request._js_file)#\1")>
    <script src="<cfoutput>#request._js_file_url#</cfoutput>"></script>
</cfloop>

Manual Code

var slider = (function(){
  var Slider = function(p) {
    //SET DEFAULTS AND FIND USER-DEFINED PARAMETERS
    var self = this;
    this.params = p;
    this.mask = this.params.parent.down(".sliderMask");
    this.container = this.params.parent.down(".sliderContainer");
    this.slides = this.params.parent.select(".slide");
    this.slidesCount = this.slides.length;
    this.active = this.params.start || 1;
    this.toDisplay = this.params.toDisplay || 1;
    this.slideBy = this.params.slideBy || 1;
    this.touch = this.params.touch || false;
    this.isTransitioning = false;
  
    //DUPLICATE SLIDES FOR INFINITE SLIDING EFFECT
    this.cloner = function() {
      var first_slide = this.slides.first(),
        last_slide = this.slides.last()
      function _clone(orig) {
        return orig.clone(true).addClassName("cloned-slide");
      }
      // clone first two slides to append to end
      this.container.insert(_clone(first_slide));
      this.container.insert(_clone(first_slide.next(".slide")));
      // clone last two slides to prepend to beginning
      this.container.insert({top: _clone(last_slide)});
      this.container.insert({top: _clone(last_slide.previous(".slide"))});
    }
  
    //SIZE SLIDER
    this.setWidths = function() {
      var hi = 0;
      this.slides.each(function(el){
        var h = el.getHeight();
        if (h > hi) {
          hi = h;
        }
      });
      this.slideWidth = this.slides[0].getWidth() + (parseInt(this.slides[0].getStyle('margin-left')) + parseInt(this.slides[0].getStyle('margin-right')));
      this.slideHeight = hi;
      var current = this.container.down(".slide.active");
      if (current) { this.slideHeight = current.getHeight();}
      this.mask.setStyle({
        width: (this.slideWidth * this.toDisplay) + "px",
        height: this.slideHeight + "px",
      });
      this.container.setStyle({
        width: (this.slideWidth * (this.slidesCount + 4)) + "px",
        height: this.slideHeight + "px",
      });
      if (this.params.prevBtn) {
        if (this.slidesCount <= this.toDisplay) {
          this.params.prevBtn.hide();
          this.params.nextBtn.hide();
        }
      }
    }
  
    //RESET THE SLIDES TO DISPLAY
    this.toDisplayReset = function(toDisplay) {
      if (toDisplay >= this.slidesCount) {
        this.toDisplay = this.slidesCount;
      } else if (toDisplay > 0) {
        this.toDisplay = toDisplay;
      } else {
	      this.toDisplay = 1;
      }
      this.slideBy = this.params.slideBy || toDisplay;
      this.setWidths();
    }
  
    //SET BASIC SLIDING FUNCTION
    this.moveTo = function(slide) {
      this.isTransitioning = true;
      //MOVE SLIDER
      this.container.setStyle({
        left: -((slide + 1) * this.slideWidth) + "px"
      })
      var current = this.container.down(".slide.active");
      if (current) { current.removeClassName("active");}
      this.container.select(".slide")[slide + 1].addClassName("active");
      var mask_height = this.container.down(".slide.active").getHeight();
      this.mask.setStyle({
        "height": mask_height + "px"
      });
      //SET ACTIVE SLIDE
      this.active = slide;
      this.isTransitioning = false;
    }
  
    //SET NEXT AND PREVIOUS FUNCTIONS
    this.next = function() {
      this.container.removeClassName("animate");
      if ((this.active + this.slideBy) > this.slidesCount) {
        this.moveTo(1 - (this.slideBy));
      }
      setTimeout(function(){
        self.container.addClassName("animate");
        self.moveTo(self.active + (self.slideBy));
      }, 10);
    }
    this.previous = function() {
      this.container.removeClassName("animate");
      if ((this.active - this.slideBy) <= 0) {
        this.moveTo(this.slidesCount + (this.slideBy));
      }
      setTimeout(function(){
        self.container.addClassName("animate");
        self.moveTo(self.active - (self.slideBy));
      }, 10);
    }
  
    //SET BUTTONS FOR SLIDER
    if (this.params.prevBtn) {
      self.params.prevBtn.on("click", function() {
        self.previous();
        if (p.playState == "play") { self.reset(); }
      })
    }
    if (this.params.nextBtn) {
      self.params.nextBtn.on("click", function() {
        self.next();
        if (p.playState == "play") { self.reset(); }
      })
    }
    
    //TOUCH EVENTS
    if (p.touch === true) {
      var hammertime = new Hammer(this.container, {
        domEvents: true,
        velocity: 0.65
      });
      hammertime.on("swipeleft swiperight", function(ev) {
        if (!this.isTransitioning) {
          if (ev.type == "swiperight") {
            self.previous();
            if (p.playState == "play") { self.reset(); }
          }
          if (ev.type == "swipeleft") {
            self.next();
            if (p.playState == "play") { self.reset(); }
          }
        }
      });
    }
  
    //PLAY STATE ACTIONS
    var play;
    this.playTimer = p.playTimer || 5000;
    this.start = function(){
      play = setTimeout(function(){self.autoPlay()}, self.playTimer);
    }
    this.reset = function() {
      clearTimeout(play);
      play = setTimeout(function(){self.autoPlay()}, self.playTimer);
    }
    this.stop = function() {
      clearTimeout(play);
    }
    this.autoPlay = function() {
      self.next();
      self.reset();
    }
    if (p.playState == "play") {
      this.start();
      /*
      this.container.on("mouseover", function(event,element){
        self.stop();
      });
      this.container.on("mouseout", function(event,element){
        self.start()
      });
      */
    }
  
    //SET INITALIZATION
    this.init = function() {
      this.cloner();
      this.setWidths();
      this.moveTo(this.active);
      if (!this.params.toDisplay) {
        this.toDisplayReset(Math.floor(self.params.parent.getWidth() / self.slideWidth))
      }
    }
    
    this.resetInit = function() {
      this.setWidths();
      this.moveTo(this.active);
      if (!this.params.toDisplay) {
        this.toDisplayReset(Math.floor(self.params.parent.getWidth() / self.slideWidth))
      } 
    }
  
    this.init();
  
    //RE-INITIALIZE ON BROWSER RESIVE (IF RESPONSIVE)
    Event.observe(window, "resize", function() {
      self.resetInit();
    });
  };
  
  var slider = new Slider({
    parent: $("eventSlider"),
    prevBtn: $("slidePrev"),
    nextBtn: $("slideNext"),
    toDisplay: 1,
    touch: true,
    playState: "play"   //COMMENT THIS LINE OUT IF YOU DO NOT WANT THE SLIDER TO AUTO ROTATE
  });
  
  return slider
}());
 

Enabling touch controls

If the slider has touch gestures enabled by using the parameter touch: true, we need to include Hammer.js in our layout file before our slider script to enable gesture support:

<script src="/includes/hammerjs_2.0.4/hammer.js"></script>