Create easy to control Module slider with AdvancedContent and jQuery Roundabout plugin

This is once again one of the posts showing advantages and flexibility of CMSMS combined with great AdvancedContent module.
We can say we are back to AdvancedContent module Series.

This time we are going to create a nice looking Slider using AdvancedContent module and Roundabout jQuery plugin. You will probably say, "Oh again some jQuery slider post" but this time it is different.

Why?

We are not going to use only some text entered in content blocks or Gallery or whatever i already wrote about. This time we will take advantage of a great feature that comes with AdvancedContent, using multi_inputs block type. 

This will give us a possibility to control different modules and showing content of these in nice Roundabout slider.

This is what we are going to create.

roundabout-slider-with-advanced-content.JPG

So let's get to business!

First we will need some modules to get to our goal. For our slider control we need following modules:

With AdvancedContent we are going to build our Backend control of the slider, GBFilePicker will be used to upload images that we are going to use in the slider and CGSmartImage will help us resizing our images on the fly so we don't have to bother with it.

For my demonstration i will be using content from News, CGCalendar and ListItExtended modules.

The first thing we should do is switch Content Type of the page where we will be using our Slider to type of AdvancedContent instead of Content, so simply select from Dropdown "Content Type:" option AdvancedContent.

Next thing we need is Template logic. I will start with a template from scratch, to keep it clean, but you can simply edit your existing Template.
Go to "Layout »  Templates" and create new Template, let's simply name it "demo". So my starting point looks something like this.

<!doctype html>
{process_pagedata}
<html lang='en'>	
<head>		
	<title>{title} - {sitename}</title>
	<meta charset='utf-8'>
	{cms_stylesheet}
	{metadata}
</head>
	<body>
		<div id='container'>
			<header>
				<h1>{title}</h1>
			</header>	
			<div id='main' role='banner'>
				<section>	
					<h2>What is new here?</h2>
						<article></article>	
				</section>
			</div>
			<footer></footer>
		</div>
	</body>
</html>

So we have a simple starting markup where we can add content blocks we are going to use. On  top of Template we add following smarty calls.

<!doctype html>{strip}
{process_pagedata}

{* set_time uses block_type slider which will help us controling the speed/duration of slide transitions *}
{content block='set_time' label='Roundabout Speed' assign='set_time' block_type='slider' min='1' max='10' step='1' default='4' block_group='Roundabout Slider'}
{* block_type multi_input will create four fields in the backend for slider control and will be enhanced in AdvancedContent module *}
{content block='module_slider' label='Select from options below' block_type='multi_input' inputs='input,input,input,input' assign='get_slider' block_group='Roundabout Slider'}
{* using browsertools plugin for browser detection *}
{browsertools output='browser' assign='bro'}
{browsertools output='version' assign='ver' strip_space=true strip_dot=true}
{browsertools output='full' strip_space=true strip_dot=true assign='full'}

{/strip}<html lang='en'>	
<head>		
	<title>{title} - {sitename}</title>		
	<meta charset='utf-8'>		
	{cms_stylesheet}
	{metadata}		
	<link href='http://fonts.googleapis.com/css?family=Alike' rel='stylesheet' type='text/css'>                
	<link href='http://fonts.googleapis.com/css?family=Carme' rel='stylesheet' type='text/css'>		
	{if $bro == 'IE' && $ver lt '90'}		
		{cms_stylesheet name='ie'}
		<script src='http://html5shiv.googlecode.com/svn/trunk/html5.js'></script>		
	{/if}	
</head>
	<body>		
		<div id='container'>			
			<header>				
				<h1>{title}</h1>			
			</header>			
			{* here comes our multi input logic *}
			<div id='main' role='banner'>				
				<section>					
					<h2>What is new here?</h2>					
					<article>
					
					</article>				
				</section>			
			</div>{* // here comes our multi input logic *}

			<div id='content' role='main'>
				<article>
					{content}	
				</article>
			</div>		
			
			<footer>{global_content name='footer'}</footer>		
		</div>	
	</body>
</html>

What do we have so far?

We have added two new content blocks on top of our Template which we will use with AdvancedContent module. Then with help of Browsertools plugin we detect user Browser and load html5.js for older Browser that don't understand HTML5. We have also added common CMSMS tags like {cms_stylesheet}, {metadata}, {sitename}, {title} and {content}, as well as Global Content block for our Copyright notice.

Next step we need to do is prepare Detail templates for modules we are going to use. I will only quickly explain this step for News module, it should be fairly easy to understand what to do with other modules.

To create a Detail Template for News module we go to "Content » News" and click on "Detail Templates" tab where we create new Template, i will name it simply "demo".
This is the markup i used for my Templates.

<header>
	<h3>{$entry->title|cms_escape:htmlall}</h3>   
	{if $entry->postdate}   
		<time datetime='{$entry->postdate|date_format:'%Y-%m-%d'}'>
			{$entry->postdate|cms_date_format}
		</time>
	{/if}
</header>
{if $entry->summary}     
	<p>{eval var=$entry->summary|truncate:'200'|strip_tags}</p>
{else}     
	<p>{eval var=$entry->content|truncate:'200'|strip_tags}</p>
{/if}

<p style='color:#f00;'>This is News module</p>

Now as we have our Module template ready we can move on to AdvancedContent module and create the logic which will alow us to control our slider.
To do this go to "Extensions » AdvancedContent" click on MultiInput tab and create new MultiInput named "input". This is where we will add additional Content blocks that will be used as our Module and Slider control.

In my demo this is what i have used: 

{content block='module_select' block_type='dropdown' items='None|News|CGCalendar|ListIt2' label='Select a Module'}
{content block='detail_id' label='Enter ID' block_type="text" oneline='true' description='Enter alias or ID number of Item that should be shown. Depends on module.'}
{content block='heading_title' label='Enter Title' block_type='text' oneline='true' size='80'}
{content block='description' label='Short Summary' block_type='text' wysiwyg='false' cols='40' rows='10'}
{content_module block='teaser' module='GBFilePicker' mode='browser' label='Select Background image'}

In the first block we have a Dropdown block which will have values "None, News, CGCalendar, ListIt" and will be used to select a module, the second block is a simple input field where Article ID or Alias can be entered. For example News and CGCalendar modules use parameter arcticleid and event_id where you are able to enter the ID number of Article or Event, where ListIt2 is using item parameter and accepts only Article/Item alias.
The third and fourth content blocks are used in case we don't want to use a Module output but rather enter some custom text. Meaning that third content block is using a simple input field for title and fourth content block uses textarea field for short summary text.
The fifth and last content block is GBFilePicker module call which will allow us to upload or select and image in the backend and include it in our Slider.

In MultiInput Templates field you can select a Template that is used for Backend presentation of these content blocks. In our case the Default template is enough, which i have slightly editet for better readability.

<div class="pageoverflow" style="border-bottom: 1px solid #ccc; margin-bottom:10px;">
{foreach from=$inputs item=elm}  
	<div class="pageoverflow">	
		<label><strong>{$elm.label}:</strong><br />
			{$elm.description}
		</label>    
	</div>  
	<div style="padding-top: 5px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">   
		<p>{$elm.input}</p>  
	</div>
{/foreach} 
</div>

The outcome we have so far can be seen in the page we have created at the begining.

Controls for Roundabout slider created with AdvancedContent 

Now what? There is still nothing to see on Frontend?

I asume you would come with a question like this, so don't panic. Now it's time we go back to our Page Template and start building our Output from AdvancedContent.
To do that go again to "Layout » Templates" open the Template we used at the beginning, in my case it was "demo" and create following smarty code where we had a comment {* here comes our multi input logic *}.

{strip}

{if $get_slider != ''}{* if slider values are not empty *}
<div id='main' role='banner'>

    {assign var='slide_values' value='<!-- multi_input_delimiter -->'|explode:$get_slider}{* assign and explode values *}
    <section>
        <h2>What is new here?</h2>
        <ul id='article-slider'>
            {foreach from=$slide_values item='one'}
            {if $one != ''}
            <li>
                <div class='summary-wrapper'>
                    {assign var='one_value' value='<!-- multi_input_value_delimiter -->'|explode:$one}
                    {* load image from gbfilepicker field *}
                    <article class='summary'>
                        {if $one_value[0] == 'None'}{* if dropdown is None show custom text *}
                        <header>
                            <h3>{$one_value[2]}</h3>
                        </header>
                        <p>
                            {$one_value[3]}
                        </p>
                        {elseif ($one_value[0] == 'News')}{* if news call module *}
                            {news action='detail' articleid="`$one_value[1]`" detailtemplate='demo'}
                        {elseif ($one_value[0] == 'CGCalendar')}{* if cgcalendar call module *}
                            {cms_module module="`$one_value[0]`" display='event' event_id="`$one_value[1]`" eventtemplate='demo'}
                        {elseif ($one_value[0] == 'ListIt2')}{* if listit2 call module *}
                            {ListIt2 action='detail' item="`$one_value[1]`" detailtemplate='demo'}
                        {/if}
                    </article>
                    {if !empty($one_value[4])}
                        {CGSmartImage src="uploads/`$one_value[4]`" height='345' width='595'}
                    {/if}
                </div>
            </li>
            {/if}
            {/foreach}
        </ul>
    </section>
</div>
{/if}

{/strip}

So first we check if our content block on top of Page Template has a value at all, if it does we start building our Markup and output values. Then we explode our content block to an Array so we can loop with foreach through input value and explode those values so we can retrive content from individual content blocks.
Then we simply check for specific values and output a Module based on that value.

For field where we used GBFilePicker  we include CGSmartImage module so images are sized on the fly. A nice sideeffect of CGSmartImage is that it also has the ability of Browser detection and we can output uri encoded images to save our http requests.

As we have all our Template logic ready we can move on to final step, which is including Roundabout jQuery plugin and attaching a Stylesheet to the Template.

Go to FredHQ homepage and download the jQuery plugin (use For Production link if you don't want to play around with the plugin). Upload that downloaded file "query.roundabout.min.js" to your Server for example in /uploads/theme/js and add following code in your Template before </body>.

<script src='//ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js'></script>
<script src='{uploads_url}/theme/js/jquery.roundabout.min.js'></script> {* // make sure to check your path *}
<script>
$(document).ready(function() {
    var interval;
    $('ul#article-slider').roundabout({ //id of wraping element
        btnNext : '#next',
        btnPrev : '#previous',
        duration : 300,
        minScale : 0.4
    }).hover(function() { // stop on hover function
        clearInterval(interval);
    }, function() {
        interval = startAutoPlay();
    });
    interval = startAutoPlay();
});

function startAutoPlay() {
    return setInterval(function() {
        $('ul#article-slider').roundabout_animateToNextChild();
    }, {$set_time}000); //call set_time content block here for slider duration control
}
</script>

Now we have jQuery framework and Roundabout plugin included and we have defined the behaviour of our Roundabout Plugin. All we have to do now, is add some style and we are done.
Go to "Layout  » Templates » Stylesheets" and edit your Stylesheet or create a new one, we will create a new one, call it whatever you like, for example "roundabout" and add the CSS code below, at least if you want it to look like in my demo.

ul, ol {
    margin: 1em 0;
    padding: 0 0 0 40px;
}

h2 {
    color: #635F30;
    text-align: center;
    text-shadow: 1px 1px 0px #000;
    padding: 0;
}

#article-slider {
    width: 600px;
    margin: auto;
}

.roundabout-holder {
    padding: 0;
    height: 350px;
    list-style: none;
}

.roundabout-moveable-item {
    height: 345px;
    width: 595px;
    cursor: pointer;
    background: #000;
    border: 5px solid #17100b;
    overflow: hidden;
}

.roundabout-in-focus {
    cursor: auto;
    border: 5px solid #a98972;
}

div.summary-wrapper {
    height: 100%;
    width: 595px;
    overflow: hidden;
    position: relative;
}

article.summary {
    height: auto;
    position: absolute;
    z-index: 10;
    bottom: 20px;
    background: rgba(23,16,11,0.9);
    padding: 15px;
    font: normal 12px/1.3 'Carme' sans-serif;
}

article h3 {
    font-size: 22px;
    color: #635F30;
}

And thats it, you can see a working demo.

Arvixe Hosting

Comments