Archive for Tutorials
September 26, 2006 at 5:46 pm · Filed under Javascript, Tutorials, jQuery
Update 10/17/2006: As requested, I've added two new arguments to the menu that will toggle the hide on page load (hideOnLoad) and also toggle the autohide (autoHide) when the mouse leaves the menu area. The 2nd argument is only useful when the triggerEvent is set to click or dblclick
Here is my first jQuery plugin. It is a very simple sliding menu using the effects provided by Interface (think Script.aculo.us for Prototype)
I really like jQuery. I also really like Prototype and Script.aculo.us. I've come to learn that each one has its strengths and weaknesses and you should decide which one to use based on your needs. I use them both, depending on the project at hand.
Here's an example of the menu in action (click menu label). This particular menu has the following options set: triggerEvent: 'click', hideOnLoad: false, autoHide: false
The defauly behavior of the menu is to hide after 1000ms (1 sec.) and to display when your mouse hovers over the "menu" label. The menu will also auto-hide after 1000ms when the mouse leaves the menu area. Most of these values, including the sliding effect, can be customized.
Visit this example page to view the source and see how to use the menu and customize it. I haven't provided alot of documentation on it, but the source code is pretty self explanatory.
source: rb_menu.js
October 18, 2005 at 10:35 pm · Filed under Resources, Tutorials
I recently found out about some cool GMail search keywords you can use to filter through your emails. I was always frustrated that I couldn't select all the unread emails I have within all my filters. Sure, I could click on All Mail and do it that way, but that it's very difficult to sort through emails that way. I found out about the is: command. Very handy and you can pass it all kinds of modifiers. Try this one out. is:unread
There's many more that I don't know about. Perhaps the GMail help section has a listing of all the possible commands and modifiers, but I don't like going through help pages. They should just have a little popup (not window, but a div/container) with all or the most common/useful commands.
Ok, so for the sake of my readers and because now I'm just curious, I went to the GMail help pages and found these other useful search filters.
Now if only GMail would add a delete or send to trash button! I hate using the drop down to delete emails I don't want.
October 18, 2005 at 3:12 pm · Filed under Ruby on Rails, Tutorials
Would you like to play around with Ruby and RoR but your hosting provider doesn't have either one installed? No problem! If your host allows you to run CGI scripts, you're all ready to install them both. Use ssh (PuTTy) to login to your account and type this in your home directory:
curl http://home.leetsoft.com/dropbox/private-ruby/install | sh
Yes, it's that simple. If you would like more details about the process, visit the original article.
May 18, 2005 at 9:35 am · Filed under Javascript, Tutorials
In part 2a of our tutorial we went over the Dashboard, how it was created and what it was used for. You do not need to read and/or understand part 2a to read part 2b. They are totally unrelated, save for the fact that I am using them both on the same project.
In this tutorial I will be discussing the technique used to save the current scroll position of the page when submitting a form and returning to the same page. In some cases, it is desirable that you maintain the scroll position when returning to the same page after a form submittal. This tutorial is a lot shorter and probably easier to implement and understand.
The basic concept is this:
- using javascript, we get the current X and Y scroll positions of the page.
- set those values to hidden fields within our form.
- submit the form, which now contains the X and Y scroll values.
- perform server-side logic.
- this is the most important part: when redirecting back to our original page, we need to pass back the X and Y values as querystring variables. Otherwise, we have no idea where to scroll to.
- at the bottom of the page or using onload, we get the X and Y values and using some more javascript, we scroll to the original position we were at before the page was submitted.
That's it really. Usually this happens very fast, especially if most of the content on the page has already been downloaded and cached by the browser. You barely ever notice the sudden jerk or jump as the page jumps to the previous scroll position. In my tests, it almost appeared as if I never left the page at all.
Example Link
Here is the javascript funtion I use to save the scroll position of the page right before I submit the page. This function can either be called onsubmit or within a custom function which actually submits a form for you.
function saveScrollPositions(theForm) {
if(theForm) {
var scrolly = typeof window.pageYOffset != 'undefined' ? window.pageYOffset : document.documentElement.scrollTop;
var scrollx = typeof window.pageXOffset != 'undefined' ? window.pageXOffset : document.documentElement.scrollLeft;
theForm.scrollx.value = scrollx;
theForm.scrolly.value = scrolly;
}
}
Note that I have not tested this on many browsers, but it works fine in IE 6.x and FF. I'm assuming it'll work in IE 5.5 and most other mozilla browsers.
Now on the server-side we do all the necessary logic and when it is time to redirect back to the original page, we simply pass back the scrollx and scrolly values as part of the query string. Since I was using ASP for the Leaflink project, this is how it looked:
scrollx = Request.QueryString("scrollx")
scrolly = Request.QueryString("scrolly")
' redirect back to original page (index.asp in this case)
' with scrollx and scrolly passed back as query string variables
Response.Redirect "/leaflink/?scrollx=" & scrollx & "&scrolly=" & scrolly
Once we're back on the originating page, we simply grab the scrollx and scrolly values from the query string and scroll to their position(s).
// use this to scroll to the previous scroll position
// when form was submitted.
window.scrollTo(< %= Request.QueryString("scrollx") %>, < %= Request.QueryString("scrolly") %>);
PHP version of the above code, at the bottom of our page:
$scrollx = 0;
$scrolly = 0;
if(!empty($_REQUEST['scrollx'])) {
$scrollx = $_REQUEST['scrollx'];
}
if(!empty($_REQUEST['scrolly'])) {
$scrolly = $_REQUEST['scrolly'];
}
// use this to scroll to the previous scroll position
// when form was submitted.
window.scrollTo(< ?= $scrollx ?>, < ?= $scrolly ?>);
I put that last bit of code at the bottom of my page, but it could've been put inside an onload event handler as well. Either one would work just fine.
That's it for this tutorial. Hope you find it useful. If you have any questions and/or comments, feel free to contact me.
May 11, 2005 at 2:14 pm · Filed under Tutorials
In part one of this two part series, I explained the reason behind Leaflink and gave an overview of the different technologies used in creating it. In this next part, I will explain in detail just about every feature that was put into Leaflink.
The first aspect of Leaflink that I want to talk about is the "Dashboard". The Dashboard came about as an afterthought to Leaflink. I thought to myself, why have these very useful links only appear on the Leaflink site. Why not put a handy little toolbar or dashboard on top of EVERY internal page?! And so I created the Dashboard, which is simply a nicer representation of the links added to Leaflink, arranged by icon (sort of like the thumbnail or icon view in windows explorer.)

The idea was to have the Dashboard sit on top of every one of our internal pages. This way we could easily jump from one page to another. This works better than using bookmarks because links can change, pages can be removed or new ones can be added at any time.
Simply put, the Dashboard is nothing more than a DIV that fades in and out when the user clicks on the top black bar on the page. In this example, you will see that when you click on the Dashboard bar on top, the Dashboard fades into view as the background fades out. The background doesn't fade out completely though.
Example Link
The default behavior of the Prototype Effects are to be automatically run whenever you instantiate them. So if you create a new fade effect and pass it the id of the element you want to fade, it will run the fade effect right away. This is not what I wanted, as I needed to modify a few attributes before I ran the fade effect. To accomplish this, I had to modify the Prototype library just a bit. Only a one line change:
// node snippet. around lines 595 - 605
Effect.Fade = Class.create();
Effect.Fade.prototype = {
initialize: function(element) {
this.element = $(element);
this.speed = 10; // new accessor added to control fade speed
this.timeout = 50; // new accessor added to control fade speed
this.start = 100;
this.finish = 0;
this.current = this.start;
/* comment out this line to stop the fade effect
from automatically running when instantiated.
The same line of code should also be commented
out in the Effect.Appear function. */
//this.fade();
},
.....
This takes care of Prototype. The next step is to create our own Dashboard object in javascript. The reason I did this was mainly to allow me to use this Dashboard effect on multiple DIVs easily. I was also inspired by Prototype's object oriented coding style.
The code for the Dashboard object is a little lengthy and there are some confusing references to variables with strange names (wrapper, glass). I will explain them both shortly:
var Dashboard = new Object();
Dashboard = Class.create();
Dashboard.prototype = {
initialize: function(element, wrapper) {
this.element = $(element);
this.wrapper = $(wrapper);
this.dbEffect = null;
this.wrapperEffect = null;
this.wrapperOpacity = 25;
this.fadeSpeed = 25;
this.timeout = 50;
this.glass = this.createGlass();
},
createGlass: function() {
g = document.createElement('DIV');
g.id = 'glass-' + new Date();
g.className = 'glass';
g.style.display = 'none';
g.style.height = document.body.offsetHeight;
g.style.width = document.body.offsetWidth;
return g;
},
isOpen: function() {
return this.element.style.display == 'block' ? true: false;
},
show: function() {
if (this.isOpen() || !this.element) return;
if(!this.glass) {
this.glass = this.createGlass();
} else {
this.wrapper.appendChild(this.glass);
}
this.dbEffect = new Effect.Appear(this.element);
this.wrapperEffect = new Effect.Fade(this.wrapper);
this.wrapperEffect.finish = this.wrapperOpacity;
this.dbEffect.speed = this.wrapperEffect.speed = this.fadeSpeed;
this.dbEffect.timeout = this.wrapperEffect.timeout = this.timeout;
this.dbEffect.fade();
this.wrapperEffect.fade();
this.glass.style.display = 'block';
},
hide: function() {
if (!this.element) return;
this.dbEffect = new Effect.Fade(this.element);
this.wrapperEffect = new Effect.Appear(this.wrapper);
this.wrapperEffect.current = this.wrapperOpacity;
this.dbEffect.speed = this.wrapperEffect.speed = this.fadeSpeed;
this.dbEffect.timeout = this.wrapperEffect.timeout = this.timeout;
this.dbEffect.fade();
this.wrapperEffect.fade();
this.glass.style.display = 'none';
if(this.glass) {
this.wrapper.removeChild(this.glass);
//this.glass = null;
}
}
}
Let's go through this step by step. To keep in stride with the Prototype coding style, I create and instantiate my object the same way. Here, element refers to the element we are declaring as our Dashboard object. wrapper refers to the area (most likely a DIV) that will be fading out when our Dashboard is fading in. I usually label my outer DIV (which holds the content of my page) #wrapper, and that just happens to be the element I am fading out, so I just called this variable "wrapper".
The next two variables are dbEffect and wrapperEffect. These variables will be used to assigned the effects to be applied to our Dashboard and Wrapper objects, repectively. I chose to use the Fade and Appear effects, but any effect that accepts an element or ID would work (for example, Scale, Squish, etc. from the Prototype library.)
The next few variables are just to control the opacity and speed at which the Dashboard fades in and out. They are pretty much self explanatory. You can play around with them to get the desired opacity and speed for your Dashboard. These are simply default values and can be overridden.
The next important variable is the glass variable. The glass variable holds the element created by the createGlass function. What this does is create an empty DIV with a transparent background image tiled across it. Every time the Dashboard appears, this glass element is put on top of everything else behind the Dashboard. In other words, there is an invisible glass layer that sits in between the wrapper and the dashboard. The width and height of this glass layer is set to the width and height of our content. This allows us to do two things.
- Stop the user from interacting with the rest of the page while the DB is open.
- Assign event handlers to the glass to control the showing and hiding of the DB (explained blow)
The first usage of the glass layer is simple enough to understand. The second usage was an added extra feature that I added to enhance the "oooh, ahhh" effect of the DB. Since we have a reference to this glass layer when we create our DB, we can easily attach event handlers to it. When I first created my DB object, I added a onmouseover event handler to the glass layer. When the user would mouse over the glass layer, the Dashboard would hide and the wrapper would come back into focus. This became a little annoying as sometimes the user would accidentally move their mouse around, but did not want the DB to hide. All I did was change the onmouseover to on click and the problem was solved. Now when the user tries to click anywhere outside of the DB, the DB will hide and the background will fade back into focus (optionally, there is also a close button which does the same exact thing.)
The rest of the code in our DB object is to control the hiding and appearing effects of both the DB as well as the wrapper. Also note that I give the glass layer a unique ID every time it is created. This was done to allow for multiple DB objects on the same page, each with its own glass layer.
Here is the code to instantiate the DB object and add the event handler to the glass layer:
/* 'db' is the ID of the DIV which holds the contents of our dashboard.
'wrapper' is the ID of the outer DIV that holds the content of our page.
note: the DB DIV cannot be inside the wrapper DIV, otherwise it would
also fade out with the wrapper
*/
var db = new Dashboard('db', 'wrapper');
db.glass.onclick = function() {
db.hide();
}
I hope I was able to fully explain how the Dashboard works. Feel free to visit the example page and play around with it. I would recommend looking through the source code to get a better understanding of it. I haven't really commented my code too much, as most of it is pretty self explanatory. If you have any questions, feel free to contact me.
Oh yeah. You can download the code and do with it as you please. I just ask that you let me know of any improvements that you make to it and also a link to different applications of it would be nice as well.
That's it for part 2a. In part 2b, I will be going over the techniques required to save the current scroll position of a site on a form submittal. I'm sure you've been to pages where you are at the bottom of a form, you click on a link or a button to perform an action which submits a form. The page returns and you are all the way at the top again. However whatever you were doing is at the bottom, so now you got to scroll back down again. Very annoying.
Note: I am going to be away on vacation this weekend and won't be returning until next week, so part 2b may not be written until some time next week. Until then, play with the Dashboard and make your own versions of it :-)
Next entries »