Home >
The Adobe Spry Framework is ideal for creating your own little widgets using existing Spry components as your tools. The best thing about Spry is that it requires very little knowledge of JavaScript, HTML and CSS. With the two files that we will be using today, I will teach you how to create the most amazing widgets your self!
Note: All source code is available for download at the end part 2
In part 1 of this article I will show you how to a build your own widget using SpryDOMUtils and SpryEffects. I will teach you how to build it up from scratch, how to style it and of course how to make it functional. I will be explaining each step in detail so it will be easy to follow for everybody.
In part 2 we are going to evolve the widget, making it more powerful, unobstructive and easier to use. We will replace the Spry Effects and make it in to a effect cluster. I will also give you some tips and show how to tackle some potential issues.
Requirements:
- Adobe Spry Framework 1.6.1+
- Dreamweaver CS3 (optional)
Sample files:
- SprySideBar.zip
- -SideBar basic
- -SideBar Advanced
- -SideBar Skinned with SpryAccordion
Prerequisite knowledge:
Familiarity with building HTML, CSS and JavaScript can be considered as a bonus.
Recommend reading:
Effect Coding [http://labs.adobe.com/technologies/spry/articles/effects_coding/index.html]
Preparing our files:
We are going to start with a basic HTML file (basic tags, like doctype, html, header and body). It might also be helpful to create a SpryAssets folder and place our required JavaScript files (SpryEffects.js and SpryDOMUtils.js) and a CSS file in this folder.
Part 1: The skeleton of the widget.
We want to create a simple widget that shows a little box, or menu when a user clicks on the tab. To achieve this behavior we will need a good skeleton for our widget that allows us to fully control the process.
Let's open our HTML file and start adding our required files to the header of the page:
<link type="text/css" rel="stylesheet" href="SpryAssets/SprySideBar.css" />
<script type="text/javascript" src="SpryAssets/SpryDOMUtils.js"></script>
<script type="text/javascript" src="SpryAssets/SpryEffects.js"></script>
There is no required order of placing the files in the header. Now that we have our components add to the page we are going to start on the skeleton of our widget. Let's create a container for our SideBar we will be using a <div> tag for this and you can place this <div> under the <body> of our page. Because we want to be able to easily access our widget we are going to add a id='example1' to the div, this will help our components later on to identify the div as the widget. As we want flexible skinning for the widget as well we are also going to add a class to it, use easily identifying names for your classes I'm going to use SprySideBar here, there are almost no limits in the amount of classes you can add to an element, it has been tested that most browsers can read up to 2000 classes for a element, this is more than we hopefully will ever use!
<div id="example1" class="SprySideBar">
</div>
That is how your code should look like, now let's continue with creating the content of our widget and add a <div> tag inside the div we just created. We will use this div for our animations to slide or scale it. Give the <div> a id that you can easily remember, I'm using example_content as it's the content of my example1 id also add a class to this element and give it a value of SprySideBarContent.
<div id="example1" class="SprySideBar">
<div class="SprySideBarContent" id="example_content">
</div>
</div>
We have our content <div>, now we want to add our tab to the skeleton. <a> element for this as we want to click on it, for the href attribute we will not be using a link but a 'javascript://' some of you might think why not use a simple #? This is because I have found out that some Opera browsers think it still a link, and actually reload the page. So it's rather to be save than sorry! Add an id='SideBarTab' and class='SprySideTab' to the <a> element, the id will be used to attach the event listener on and the class is used to skin the button. Between the <a> </a> tags I placed a <em> </em> code, these will be used as status indicators of our widget. Add in a image or some text to indicate the current status of the widget.
<div id="example1" class="SprySideBar">
<div class="SprySideBarContent" id="example_content">
</div>
<a href="javascript://" id="sideBarTab" class="SprySideTab"><em> >> </em></a>
</div>
Now that already looks like a nice skeleton to me, but we are not done yet! It's time to add something in the content, you can basically put anything you want in here, from images, SpryTabbedPanels till complete SpryDataSets! In this example I will be using a simple menu that is created from <ul> and <li> elements with a little header to inform the user, but before you add anything, create a new <div> with a class=''SprySideBarMenu" and id='menu' so we can attach another effect for showing up the content of the menu and place your menu inside of it.
<div id="example1" class="SprySideBar">
<div class="SprySideBarContent" id="example_content">
<div class="SprySideBarMenu" id='menu'>
<h1>SprySideBar</h1>
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 1</a></li>
</ul>
</div>
2
</div>
<a href="javascript://" id="sideBarTab" class="SprySideBar"><em> >> </em></a>
</div>
Because we want an always visible background, and the background of the content <div> will scale away from the effect we need to create a little wrapper for the content. This will be a mostly CSS powered background. This <div> only needs to be wrapped around the SprySideBarContent <div> and it only requires a class='SprySideBarGroup'. This is the last addition to our skeleton!
Your final skeleton should look similar to this:
<div id="example1" class="SprySideBar">
<div class="SprySideBarGroup">
<div class="SprySideBarContent" id="example_content">
<div class="SprySideBarMenu" id='menu'>
<h1>SprySideBar</h1>
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
<li><a href="#">Link 4</a></li>
<li><a href="#">Link 5</a></li>
</ul>
</div>
</div>
</div>
<a href="javascript://" id="sideBarTab" class="SprySideTab"><em></em></a>
</div>
Part 2: Styling the widget!
Now that we have our widget's skeleton done we can take a closer look at our CSS and focus on styling our widget, this is just as important as creating the skeleton because this is the skin of our widget. Let's open up our SprySideBar.css that we created in our SpryAssets folder.
I will be discussing all required attributes of our widget, so this will help you understand the working of it. Let's stop the blah blah and start working on our skin!
.SprySideBar {
left:0px;
position:absolute;
text-align:left;
top:140px;
}
This is class of our container, I have positioned this absolute because this gives all of rock solid freedom of positioning our widget, the left:0px; makes sure that the widget is on it's absolute left side, top:140px; is the height of our widget, how much space from the top of our widget to the top of the view port.
As we are using <a> tags in our widget, and we don't want the dotted outlines to be shown when the users focus or clicks on it I have add:
.SprySideBar a {outline:none;}
This will remove all outlines from the <a> elements that are INSIDE of your container, all other <a> element in your page will not be affected by this, that is the beauty and power CSS.
.SprySideBarGroup{
background-color:#F3F3F3;
border:1px solid #CCCCCC;
min-height:100px;
float:left;
}
There are no limitations for the background of the group, you can use an image or add a simple background color with a nice border like I'm currently doing. The min-height attribute makes sure that background doesn't become smaller than our tab button (which I'm also going to give a height of 100px). The float:left allows us to place our tab button next to our group.
.SprySideBarContent {
display:none;
height:150px;
overflow:hidden !important;
width:200px;
}
The first thing that you might notice is the display:none attribute, this will hide our content and allows us to show a closed default state of the widget when the page loads. In this class u can customize the overall height and width of the widget. I have add overflow:hidden to the class to make sure the content doesn't go outside our widget.
NOTE: The next few classes are only needed if you are using the same menu as I am. They are not required for the functionality of the widget.
.SprySideBarMenu h1 {
color:#000;
font:bold 110% arial;
margin:10px;
}
This gives my H1 a nice black color, I'm using a CSS shorthand for my font, this will save me some file size and space, it's allot shorter than writing: font-weight:bold; fontsize: 110%; font-family:arial;, I also gave it a margin of 10px to give it some white space around the text.
.SprySideBarMenu ul {
margin:0px;
padding:0px;
}
Reset the margin and padding of our UL element to 0px;
.SprySideBarMenu li {
4
list-style-type:none;
margin:0px 10px 3px;
padding:2px;
width:170px;
}
The list-style-style:none will hide the dot that is usually next to a list element, this will make it look more like a menu instead of a list. The margin is used to give some extra space between the items of the list, and padding gives is a bit bigger 'click able' target area (same counts for the width:170px wich will allow users to click next to text and still hit the link!).
.SprySideBarMenu ul li a:link, .SprySideBarMenu ul li a:visited {
color:#000;
display:block;
font-family:verdana;
font-size:100%;
text-decoration:none;
}
This is to style our <a> elements in side the <li>'s display:block will enable the big target area for us that we had set in our previous class) The rest doesn't require any extra words as they style our text, except for our text-decoration:none this will hide underline from the links.
NOTE: The following CSS style is required for the widget again!
.SprySideTab, .SprySideTab a{
float:left;
height:100px;
width:25px;
display:block;
border:1px solid #CCCCCC;
background-color:#F3F3F3;
margin-left:-1px;
text-decoration:none;
}
Time finish up our CSS and style the last part of our widget, the tab! The float:left will place our tab next to our group. As a said a few styles back that I would set the height of the tab 100px; here it is. Together with the width:25px attribute we have created a nice block for uses to click and activate our menu, display:block will make sure that they can press on the whole background to activate the widget. I gave it the same background and border as the SprySideBarGroup so they match! I don't like having a double border on the left side so I gave the tab a negative margin on the left side. This will slide the SprySlideTab a bit over the group. And text-decoration:none; to hide the underline again.
Note: if you wish to style indicator you can do this by adding styles to the following line:
.SprySideTab a em{
/* styles here */
}
Part 3: Building the muscles of our widget!
Yes, it's time to power our skeleton with the muscles of Spry! I already decided what effects I wanted to use for this widget, the effect Squish to move the sidebar, and Fade to fade in the menu's content. can find allot pre-build Spry Effects in the Effects demo that you can find here: http://labs.adobe.com/technologies/spry/demos/effects/index.html.
Instead of the Squish effect it's also possible to use the Slide effect. Just pick what you think works best for your widget.
Let's start off by creating the tags. This helps the browsers to identify JavaScript from HTML codes. Inside our script tags we will begin with setting up our effects.
You can set up effects with the following effect constructor:
var squish = new Spry.Effect.Squish('example_content',{options})
This basicly means:
var (variable) variablename = new (a new effect) Spry.Effect.Squish(the effect
name)('Id_of_elemement',{effect options});
Let's set the options for our effect, the widget will be initially hidden with the display:none that we have set in our CSS. This will allow us scale the widget from:'0%' to:'100%' in size. We can even set how long much milliseconds the effect should take, and the duration of the effect. We want to be able to toggle, open and close the effect. Now that we know our options we can set the options for our effect.
{from:'0%', to:'100%', duration:1000, toggle:true}
And set these options in your constructor. The finished constructor should look like this:
var squish = new Spry.Effect.Squish('example_content',{from: '0%', to: '100%', duration:
1000, toggle: true});
We wanted to fade our content to, so we have to add another effect for that, the good thing is we can use the same options for it and only have to switch effect name.
var fade = new Spry.Effect.Fade('menu',{from: '0%',to: '100%', duration: 1000, toggle:
true});
Now we have gotten our effects configured and attached to our required Id's, it's time to set up our status indicators, Spry allows you set up Observers. The name already says it, to observ the effect. Before the effect starts we want to change the content of our indicators this is called onPreEffect. So let's set up our observer:
var myObserver = new Object;
myObserver.onPreEffect = function(effect){
};
The variable myObserver is now an object. We have attached a function to the onPreEffect value of our object. This function will recieve information about the effect with the effect variable. Let's expand the function a bit more, if the effect is going forward (starting) we want that the content of your <em> changes. Let's set up the effect direction first:
var myObserver = new Object;
myObserver.onPreEffect = function(effect){
if(effect.direction == Spry.forwards)
//do something
else
//do something else
};
That would indicate the direction of the effect. Now we want to be able to access the our element, this where we are going to use our SpryDOMUtils. It has a nice short hand function to access our element: Spry.$('sideBarTab'). That will give us acces to the <a> element, but we want to acces the <em> element, you could attach ANOTHER id to that element but you can also access the element through the <a> element. you can see the HTML structure as a family with childeren, sibblings and parents. The <a> is the parent of <em> so that makes <em> the child of <a>. In JavaScript you can call this the FirstChild or ChildNode so Spry.$('sideBarTab').childNodes[0] would allow access to our <em>. With the .innerHTML attribute we can change the content of the <em>.
var myObserver = new Object;
myObserver.onPreEffect = function(effect){
if(effect.direction == Spry.forwards)
Spry.$('sideBarTab').childNodes[0].innerHTML = '>>';
else
Spry.$('sideBarTab').childNodes[0].innerHTML = '<<';
};
You can attach the Observer to any effect you want, I'll be attaching it our content Squish effect, You can attach it by using: effects_var_name.addObserver(myObserver);. Our complete script should look like this:
var squish = new Spry.Effect.Squish('example_content',{from: '0%', to: '100%', duration:
1000, toggle: true});
var fade = new Spry.Effect.Fade('menu',{from: '0%',to: '100%', duration: 1000, toggle:
true});
var myObserver = new Object;
myObserver.onPreEffect = function(effect){
if(effect.direction == Spry.forwards)
Spry.$('sideBarTab').childNodes[0].innerHTML = '>>';
else
Spry.$('sideBarTab').childNodes[0].innerHTML = '<<';
};
squish.addObserver(myObserver);
Now we want to attach the effects to the SprySideBarTab, when a user clicks on it the effect gets activated we will be using addEventListener and addLoadListener for this. The addEventLister will allow us to attach a function to a certain element without having to write any in line JavaScript. We going to start with setting up our AddLoadListener
Spry.Utils.addLoadListener(function(){
});
All load listeners require a function inside. you can create a new function outside the Loadlistener or declare a function inside it. If you declare it outside the listener you can still access it normally by calling the function name, if you declare it inside the listener you wont be able to call the function again, unless the page reloads. As you can see I created a function inside of it as there is no need to access it again. Within this function we are going to place our EventListener, the same function concept counts here to.
Note: If you add a function outside of the listeners, make sure you don't execute the code within it. So leave the () out of the function name.
Spry.Utils.addEventListener("sideBarTab", "click", function(){
squish.start();
fade.start();
}, false);
That is how our EventListener should look like: Spry.Utils.addEventListener('id of the element','eventtype',function,capture); for the function I'm using a in line function again. Within in this function I have add the start commands for our effects. var_name_of_effect.start(); place the EventListener inside the LoadListener and we are done.
Spry.Utils.addLoadListener(function(){
Spry.Utils.addEventListener("sideBarTab", "click", function(){
squish.start();
fade.start();
}, false);
});
Load your page and it should work properly if you followed my steps correctly! If you click on the Tab button the menu appears and Squishes in full position and the menu gets faded in. This is the end of the basic part of creating your side bar widget, in the next part of this article I will show you how to make the animation a bit smoother, clean up your code, and only require ONE id to power up this widget! And in the last part will describe some basic tweaks for the scripts, to improve it even more!
In part 2 we are going to evolve the widget, making it more powerful, unobstructive and easier to use. We will replace the Spry Effects and make it in to a effect cluster. I will also give you some tips and show how to tackle some potential issues.




Facebook Application Development
Hi Arnout
thanks for sharing your code with the community. I'm starting to look at Spry, and your tutorial is very useful.
Regards
Andrea
very useful tutorial & thanks for sharing your code with the community
How would you make the effect go from right to left so it could be on the right hand side of the page?