How to create a slider

From Sense/Net Wiki
Jump to: navigation, search
  •  
  •  
  •  
  •  
  • 100%
  • 6.3
  • Enterprise
  • Community
  • Planned

Overview

Slider banner
You can add a customizable slider banner to your Portlet Page with image or video background. As backgrounds the slider can use uploaded images from the Content Repository or video files as it is described in this article.

Steps

1. Install new CTD

Install a new CTD which will be used for displaying the slider items as customizable content in your Sense/Net solution. On these items the layout is customizable on the admin surface: title, text, alignment, background and one can also add call-to-action buttons to the slider. To display multiple link buttons please see How to create a custom field control.

<ContentType name="SliderItem" parentType="ListItem" handler="SenseNet.ContentRepository.GenericContent" xmlns="http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition">
  <DisplayName>$Ctd-SliderItem,SliderItem-DisplayName</DisplayName>
  <Description>$Ctd-SliderItem,SliderItem-Description</Description>
  <Icon>Image</Icon>
  <Preview>false</Preview>
  <Fields>
    <Field name="DisplayName" type="ShortText">
      <DisplayName>$Ctd-SliderItem,SliderItem-DisplayName</DisplayName>
      <Description>$Ctd-SliderItem,SliderItem-Description</Description>
    </Field>
    <Field name="Background" type="Reference">
      <DisplayName>$Ctd-SliderItem,Background-DisplayName</DisplayName>
      <Description>$Ctd-SliderItem,Background-Description</Description>
      <Configuration>
        <AllowMultiple>false</AllowMultiple>
        <AllowedTypes>
          <Type>Image</Type>
          <Type>Video</Type>
        </AllowedTypes>
      </Configuration>
    </Field>
    <Field name="YouTubeBackground" type="ShortText">
      <DisplayName>$Ctd-SliderItem,YouTubeBackground-DisplayName</DisplayName>
      <Description>$Ctd-SliderItem,YouTubeBackground-Description</Description>
    </Field>
    <Field name="VerticalAlignment" type="Choice">
      <DisplayName>$Ctd-SliderItem,VerticalAlignment-DisplayName</DisplayName>
      <Description>$Ctd-SliderItem,VerticalAlignment-Description</Description>
      <Configuration>
        <Options>
          <Option value="top">$Ctd-SliderItem,VerticalAlignment-Top</Option>
          <Option value="middle">$Ctd-SliderItem,VerticalAlignment-Middle</Option>
          <Option value="bottom">$Ctd-SliderItem,VerticalAlignment-Bottom</Option>
        </Options>
      </Configuration>
    </Field>
    <Field name="HorizontalAlignment" type="Choice">
      <DisplayName>$Ctd-SliderItem,HorizontalAlignment-DisplayName</DisplayName>
      <Description>$Ctd-SliderItem,HorizontalAlignment-Description</Description>
      <Configuration>
        <Options>
          <Option value="left">$Ctd-SliderItem,HorizontalAlignment-Left</Option>
          <Option value="center">$Ctd-SliderItem,HorizontalAlignment-Center</Option>
          <Option value="right">$Ctd-SliderItem,HorizontalAlignment-Right</Option>
        </Options>
      </Configuration>
    </Field>
    <Field name="Description" type="LongText">
      <Configuration>
        <TextType>LongText</TextType>
        <ControlHint></ControlHint>
      </Configuration>
    </Field>
    <Field name="OuterCallToActionButton" type="HyperLink">
      <DisplayName>$Ctd-SliderItem,OuterCallToActionButton-DisplayName</DisplayName>
      <Description>$Ctd-SliderItem,OuterCallToActionButton-Description</Description>
    </Field>
    <Field name="InnerCallToActionButton" type="LongText">
      <DisplayName>$Ctd-SliderItem,InnerCallToActionButton-DisplayName</DisplayName>
      <Description>$Ctd-SliderItem,InnerCallToActionButton-Description</Description>
      <Configuration>
        <ControlHint>sn:ButtonList</ControlHint>
      </Configuration>
    </Field>
  </Fields>
</ContentType>

2. Create custom field control to ButtonList

There is a customized Field Control used for displaying and editing the inner-links that defined in the InnerCallToActionButton field. To this, you need to apply the following files in your solution:

  • UI/Controls/FieldControlsButtonList.cs
  • Global/scripts/sn/SN.CallToAction.js
  • /Root/Global/fieldcontroltemplates/EditTemplate.ascx

This FieldControl allows you to add multiple links as a value of the InnerCallToActionButton field on the UI which means the list of buttons/links and their properties will be transformed to a JSON object and this JSON object will be saved as the value of the LongText field.

3. Create custom view

A Content collection Portlet will display the slider on a portlet page with the following custom view, which will be added to the Content Repository.

<%@ Control Language="C#" AutoEventWireup="true" Inherits="SenseNet.Portal.Portlets.ContentCollectionView" %>
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="SenseNet.Portal.Portlets" %>
<%@ Import Namespace="SenseNet.Portal.Helpers" %>
<%@ Import Namespace="SenseNet.ContentRepository.Storage" %>
<%@ Import Namespace="SenseNet.Portal.UI.ContentListViews" %>
<%@ Import Namespace="SenseNet.ContentRepository.Fields" %>
<%@ Import Namespace="System.Web.UI.WebControls" %>
<ul class="example-orbit-content sn-slider" data-orbit>
    <%foreach (var content in this.Model.Items)
      { %>
    <li class=" <%= (content["VerticalAlignment"] as List<string>).First() %> <%= (content["HorizontalAlignment"] as List<string>).First() %>">
        <span class="text">
            <span>
                <h2><%= content["DisplayName"] %></h2>
                <p><%= content["Description"] %></p>
                <% 
          var outerCallToAction = content["OuterCallToActionButton"] as SenseNet.ContentRepository.Fields.HyperLinkField.HyperlinkData;
          var innerCallToAction = content["InnerCallToActionButton"];
          if (!String.IsNullOrEmpty(innerCallToAction.ToString()) || outerCallToAction.Href != String.Empty)
          { 
                %>
                <div class="buttons">
                    <%if (!String.IsNullOrEmpty(innerCallToAction.ToString()))
                      { %>
                    <input type="hidden" value='<%=innerCallToAction.ToString() %>' class="innerCallToActions" />
                    <%} %>
                    <% if (outerCallToAction != null && !String.IsNullOrEmpty(outerCallToAction.Text))
                       {%>
                    <a class="button" target="<%= outerCallToAction.Target %>" href="<%= outerCallToAction.Href %>" title="<%= outerCallToAction.Title %>"><%= outerCallToAction.Text %></a>
                    <%} %>
                </div>
                <%} %>
            </span>
        </span>
        <% 
          if (content.ContentHandler.GetReference<Node>("Background") != null)
          {
              if (content.ContentHandler.GetReference<Node>("Background").NodeType.IsInstaceOfOrDerivedFrom("Image"))
              {%>
        <img src="<%= content.ContentHandler.GetReference<Node>("Background").Path %>" alt="<%= content["DisplayName"] %>" />
        <%}
              else
              { %>
        <video autoplay preload="auto" loop muted width="100%">
            <source src="<%= content.ContentHandler.GetReference<Node>("Background").Path %>" type="video/mp4">
            <source src="<%= content.ContentHandler.GetReference<Node>("Background").Path %>" type="video/webm">
            <source src="<%= content.ContentHandler.GetReference<Node>("Background").Path %>" type="video/ogg">
            Your browser does not support the video tag.
        </video>
        <%} %>
        <%}
          else
          {
              var youtubebackground = content["YouTubeBackground"].ToString();
              if (!String.IsNullOrEmpty(youtubebackground))
              { %>
        <iframe src='<%=youtubebackground %>' height="100%" width="100%"></iframe>
        <% }%>
        <%} %>
    </li>
    <%} %>
</ul>
<script style="text/javascript">
    $(function () {
        Foundation.global.namespace = '';
        var $firstVideo = $('.example-orbit-content').children('li:first-child').children('video');
        if ($firstVideo.length > 0) {
            setTimeout(function () {
                $firstVideo.get(0).play();
            }, 200);
        }
        var $videoSlide = $('video').closest('li');
        $('.sn-slider iframe').each(function () {
            var $this = $(this);
            var url = $this.attr('src');
            // Grab text
            var matches = url.match(/(?:http:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(.+)/g);
            if (!matches) {
                return true;
            }
            var a, link;
            if (matches[0].indexOf('embed') === -1) {
                if (matches[0].indexOf('.com') > -1) {
                    a = matches[0].split('.com');
                    link = 'https://' + a[0] + '.com/embed' + a[1] + '?wmode=opaque&autohide=1&autoplay=1&loop=1&mute=0&enablejsapi=1';
                }
                else if (matches[0].indexOf('.be') > -1) {
                    a = matches[0].split('.be');
                    link = 'https://www.youtube.com/embed' + a[1] + '?wmode=opaque&autohide=1&autoplay=1&loop=1&mute=0&enablejsapi=1';
                }
                $this.attr('src', link);
            }
        });
        $(document).foundation({
            orbit: {
                snmaxheight: 600,
                after_slide_change: function (idx, slideslength, slidescontainer) {
 
                    if (typeof slidescontainer.children('li:eq(' + idx + ')').children('video') !== 'undefined' && slidescontainer.children('li:eq(' + idx + ')').children('video').length > 0) {
                        slidescontainer.find('video')[0].pause();
                        slidescontainer.children('li:eq(' + idx + ')').find('video')[0].play();
                    }
                    else {
 
                        slidescontainer.find('video').each(function () {
                            $(this).get(0).pause();
                        });
                    }
 
                }
            }
        });
        var buttons;
        $('.innerCallToActions').each(function () {
            var $this = $(this);
            if ($this.val().length > 2) {
                var innerLinks = $this.val();
                buttons = JSON.parse(innerLinks);
 
                $.each(buttons, function (i, item) {
                    var $button = $('<a class="button" target="' + item.linkTarget + '" href="' + item.buttonPath + '" title="' + item.linkTitle + '">' + item.buttonText + '</a>').appendTo($this.parent());
                });
            }
        });
    });
</script>

4. Add custom functionality with javascript

This view will use additional scipts and css files to display the slider properly. For these custom files we used originally the Orbit-slider resources from Foundation Framework, but Foundation is not supporting this feature anymore. The files you find here are not the original Foundation files, but they are customized to fit in the Sense/Net solution. Load the foundation.js, that can be downloaded from the website of Zurb Foundation

Complete foundation.orbit.js with the following snipplets:

Find self.compute_dimensions function in the code and add the following variable:

var h = current.outerHeight();

and the following if-statement:

  if (!settings.variable_height) {
                self.slides().each(function () {
                    if ($(this).outerHeight() > h) { h = $(this).outerHeight(); }
                });
                if (settings.snmaxheight)
                    h = settings.snmaxheight;
 
                slides_container.each(function () {
                    var $that = $(this);
                    if ($that.find('img').length > 0) {
                        $that.find('img').each(function () {
                            var $this = $(this);
                            if ($this.height() < settings.snmaxheight) {
                                h = $this.height();
                            }
                        });
                        $that.find('img').each(function () {
                            var $this = $(this);
                            if ($this.height() > h) {
                                var diff = ($this.height() - h) / 2;
                                $this.css({ 'margin-top': -diff });
                            }
                        });
                    }
                    if ($that.find('video').length > 0) {
                        $that.find('video').each(function () {
                            var $this = $(this);
                            if ($this.height() < settings.snmaxheight)
                                h = $this.height();
                        });
                        $that.find('video').each(function () {
                            var $this = $(this);
                            if ($this.height() > h) {
                                var diff = ($this.height() - h) / 2;
                                $this.css({ 'margin-top': -diff });
                            }
                        });
                    }
                    $that.height(h).css({ 'overflow': 'hidden' });
                    $that.children($("li")).height(h);
                });
            }

Find self.build_markup function in the code and add the following:

            function resizeFonts() {
                var sliderWidth = $('.orbit-slides-container li').width();
                $('.text h2').css('font-size', sliderWidth * 0.035 + 'px');
                $('.text p').css('font-size', sliderWidth * 0.015 + 'px');
                $('.text a').css('font-size', sliderWidth * 0.010 + 'px');
            }
            window.onresize = function (event) {
                resizeFonts();
            };

5. Add style rules

Add a custom stylesheet, /Root/Global/styles/snSlider.css, which is created responsively on the base of the foundation solution.

6.Create slider, slider items and background items

Find a right place in the tree under your site where slider will be built up. Create a folder to your SliderItems, where they will be collected. Make sure, that you add SliderItem as Allowed Childtype on the required node.

Slider in the Content Repository

Add images and videos as „Image” and „Video” content, which will be used as backgrounds on SliderItems. Make sure, that you add Image and Video as Allowed Childtypes on the required node.

Upload Video or image for background

Add SliderItems and setup the slider layout on the admin page in edit mode. You can setup ont he admin interface:

  1. Display name: will be shown up as the title of the slide
  2. Background: will be the image or video content of the slide
  3. YouTube video link: will show up a YT video as background, if other background item in the previous field is not set
  4. Vertical alignment: align slide text vertically
  5. Horizontal alignment: align slide text horizontally
  6. Description: will be shown up as slide text
  7. Call-to-action outer link: call-to-action button links to outer-content
  8. Call-to-action inner link: call-to-action button links to inner-content.
  9. Index: slides will be ordered according to index values.
Slider item configuration

7.Usage

Add a Content collection Portlet to the selected portletpage, where slider will be implemented. According to the following steps: 1. Add portlet 2. At view add the path to the custom view 3. Set bind target to custom root 4. Add custom root path 5. Set collection source to Children 6. Sort sliders by „Index”


Use as a main-page banner

Related links

References