Finding the Bottom of the Page

I ran into a challenge the other day where I had to calculate how much space was left between an HTML element and the bottom of the browser window. We were using Google’s Search-As-You-Type code (http://code.google.com/p/search-as-you-type/) which, according to a fellow developer, “worked like a dream”. He then handed it off to me to implement in another section of the application.

He had been using the search bar at the top of the page with no problems, whereas I needed it further down in a form. I dropped in the code and found that the JavaScript was somehow not calculating a dimension correctly. Depending on where you had scrolled the page to, the search box would either shrink the height of the dropdown results to barely anything, or sometimes nothing at all!

The Google code has a function called updateDimensionsAndShadow(), and that seemed to be the culprit. So after trying to modify what was in there and getting nowhere, I added a small section of code for the script to calculate the dropdown height correctly. Now, the big challenge for me here was that I’ve never had to try and find where the current “bottom of the page” was. I usually worry about the positioning of an element from the top of the page. So here is what I learned, and the code I wrote to fix the height issue.

Finding the Bottom
Finding the Bottom

The first thing we do is find the y-coordinate for the top of our input element of our search box, relative to the top of the document. This is done by first grabbing the offsetTop of the element which is it’s position relative to the container it’s in. We add the offsetHeight of the input because we are going to actually want the position of the bottom of the input box (that’s where the dropdown list will start).

var sf = document.getElementById('searchField');
var searchTop = sf.offsetTop + sf.offsetHeight;

Next we will cycle through all of the element’s ancestor’s (via offsetParent) and continuously add each of their offsetTop coordinates to our caclulation. This will give us the y-coordinate of the bottom of the search box relative to the very top of the document.

var sfParent = sf.offsetParent;
while (sfParent) {
 searchTop += sfParent.offsetTop;
 sfParent = sfParent.offsetParent;
};

Next we will get the position of the bottom of the browser’s toolbar, relative to the top of the document.

var yOffset = (window.pageYOffset) ? window.pageYOffset : document.body.scrollTop;

We can now finally calculate the max height of our search results dropdown list (refer to the diagram).

var maxSearchResultsHeight =
document.documentElement.clientHeight - (searchTop - window.pageYOffset) - searchAsYouTypeConfiguration.bottomPageMargin;

What we are saying here is “The height we have available is [the visible height in the browser] minus [the difference between the top of the element in the document and the bottom of the browser toolbar in the document] minus [the margin we want between the droplist and bottom of the browser]”.

Now the one thing I do need to fix yet is cross-browser compatibility (cough, IE, cough, cough), but the above modifications appear to be working in the real browsers.

Please let me know if you have a better way of finding the bottom of the page.

How To Write a Simple Facebook Share App

facebook developer
Developing Apps for Facebook

Can I Just Cut Some Code Already?

All I wanted to do was to let users share a video link from a web app I was building. I thought it would be easy. And you know what, it probably is. It’s probably easier than what I’m going to show you here. But is it simply stated somewhere in Facebook’s documentation? Not that I could find. So piecing together parts of their docs, plowing through search after search and reading a multitude of blog posts, I came up with this solution.

Quick Overview

The idea is a simple one. The web app let’s you choose a video and view it within the site. If the “share this” button is clicked, the familiar Facebook dialog will popup, letting the user add an additional message to the built-in metadata for the share. If the user has not yet logged into Facebook, they will be prompted to do so. OK, here we go.

Set Up a Facebook App

I thought that you could simply call a Facebook url with some extra information and you were all set, but all of the examples I saw included an application id as part of the call. So I needed to setup an app. For those of you that haven’t done this before, here is a quick summary.

Search for the Developer App in the search bar and install it to your Facebook account.

Add the Developer App
Add the Developer App

After you install, you will be presented with a page that allows you to configure the app. There are a lot of settings here, and many of them pertain to applications with a lot more complexity. For our purposes, we are really interested in only a few things. Fill out the basic info as desired (such as website, support email, etc.) and add a logo to spruce up the share dialog box. You will notice on the main settings page that an application id is presented for you. You need that for your share code.

One other note is that apps can have sandbox mode enabled. When in sandbox mode, only you, as the developer, can use the app. This is of course useful for testing. Don’t forget to disable the sandbox when you are ready to go live.

Sandbox Mode
Sandbox Mode

Writing the Code

OK, now let’s get down to it. Like I mentioned, this is quick.

$('#shareFacebook').click(function(event) {
 window.open(FB_FEED_DIALOG_URL +
 'app_id=' + FB_APP_ID +
 '&redirect_uri=' + FB_LINK_DOMAIN +
 '&name=' + FB_TITLE_PREFIX + data.title +
 '&caption=' + data.title +
 '&description=' + data.description +
 '&source=' + FB_YOUTUBE_SOURCE_PREFIX + data.videoId +
 '&link=' + FB_YOUTUBE_LINK_PREFIX + data.videoId +
 '&picture=' + FB_YOUTUBE_PICTURE_PREFIX + data.videoId + FB_YOUTUBE_PICTURE_SUFFIX
 );
});

I have the call to Facebook wrapped inside a jQuery click event which opens a new window. The heart of it is the URL inside of window.open().

  • The call starts out with FB_FEED_DIALOG_URL which is set to ‘http://www.facebook.com/dialog/feed?’.
  • Set your application id which you obtained earlier.
  • Add the URL that you want Facebook to redirect the user to after they’ve shared the link. Note that Facebook will append a ‘/?postId=xxxx’ to the URL so be prepared to handle that. I simply ignored it by telling our routing rules to trim off the question mark and everything after before handing it to the dispatcher.
  • The name, caption, description, source, link and picture will show up in the share dialog box.

As you may have noticed, I’m sharing a YouTube video. That also brought it’s own challenges on how to set these parameters correctly. I believe I obtained these settings from a blog somewhere, which I can’t remember (thank you to the author):

  • FB_YOUTUBE_SOURCE_PREFIX = ‘http://www.youtube.com/v/’
  • FB_YOUTUBE_LINK_PREFIX = ‘http://www.youtube.com/watch?v=’
  • FB_YOUTUBE_PICTURE_PREFIX = ‘img.youtube.com/vi/’

The YouTube video id is appended to each of the above constants.

The dialog looks like this:

Facebook Share Dialog
Facebook Share Dialog

After the user clicks the Publish button, the link is posted to their wall and they are redirected to the URL you specified.

Conclusion

I really hope this helps some of you out there as I could not figure out why something seemingly so simple was taking me forever to figure out. Also, I’m sure there are a lot of alternatives to this method — some much simpler I’m afraid. I’d be interested in hearing your solutions.

My Subversion and Dropbox Setup

I’ve really come to love my version control setup that I’ve been using heavily over the last several months, and I wanted to share it. It’s really quite simple and it has saved me a lot of headaches. I had been using a central, cloud-based storage method for uploading my working code (Google Docs, Dropbox, etc.) so that I had access to the code wherever I was and whatever device I happened to be using.

Here is the problem, though. For example, I’m coding on my desktop and am about ready to head out the door to continue coding at the coffee shop. So I zip up all of my files, upload them to the cloud, then download them to my notebook. That’s not too horrible of a process, but how do I fit version control into this scenario? My first try ended in more steps and more headaches as I could never keep the working copies and repositories in sync.

Then I heard of Dropbox’s synced folder feature. This was the answer. Now I don’t even move or package my files at all! I simply commit them to the repository. Here’s how it works.

First, I setup Dropbox with the synced folder feature enabled on all of the devices that I intend to use.

svn setup 01
Setup Dropbox on all devices

Any files I drop into any of these folders will automatically replicate to the other folders. Next, I setup a Subversion repository in the Dropbox folder of any one of the devices, which of course then replicates.

svn setup 02
Create a Subversion repository in any of the Dropbox folders

So here I am, back on the desktop. I checkout the latest version of the project code from the repository in the Dropbox folder, make my changes, then commit those changes back to the repository. The repository is now updated on all devices.

svn setup 03
Checkout a working copy, make changes and commit

On over to my laptop, let’s say I’ve already been working on the code from there as well. I perform a Subversion update on my working copy of the project, which grabs all of the changes I made on my desktop, then merges them into my local working copy. As usual, I make changes and commit back to the repository, and so on and so on.

One final note. It’s good to have that repository backed up, so on one of my devices, I have Amazon’s Jungle Disk installed, which backs up my Dropbox folder every night.

svn setup 04
Backup repository

So as you can see, once everything is set up, I simply hop on a device of my choice, update my working copy, make changes then commit back to the repository. Done. No headaches.

Cache Woes in Internet Explorer

I just finished troubleshooting one of my websites that was acting abnormally in Internet Explorer, and I have emerged from the battle, heavily scarred. Here is a snapshot of the files involved (the actual names of the files have been changed to protect the innocent):

File Diagram for IE Cache Issue
File Diagram for IE Cache Issue

It’s a simple setup. Index.php holds a form and is supported by a JavaScript file. The JavaScript file makes AJAX calls to serverSide.php, which in turn accesses a MySQL database. The JavaScript file then redirects the browser to secondPage.php and serves up the data.

The serverSide file is also accessed from secondPage through the JavaScript file. And therein lies the problem with Internet Explorer. Once index makes its call to serverSide, IE stores serverSide in its Temporary Internet Files folder. So when secondPage calls serverSide with new parameters, serverSide is retrieved from the cache folder instead of being called at the server and delivering fresh data to secondPage.

The solution was found in the php manual. There it gives the following information in the “header” article:

PHP scripts often generate dynamic content that must not be cached by the client browser or any proxy caches between the server and the client browser. Many proxies and clients can be forced to disable caching with:

<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
?>

I added this code to secondPage and sure enough, IE ignored the cached version of serverSide and served up fresh data.

I hope this information will save someone else from a massive headache.

Startup Weekend – Interface First

My last several posts have been following a personal project of mine, named Charity Tree, and how I am attempting to follow many of the guidelines laid out in Getting Real by 37Signals. This month I had the privilege to attend West Michigan Startup Weekend and was able to put a few of those gems of wisdom to practice, out in the field, as it were.

After the initial teams were formed on Friday night, we had time to get familiar with the project, the team members and the goals for the weekend. For my particular team, we had initially thought that we would be designing a website/web app over the weekend. So early Saturday morning, when we really got down to  business, I started thinking about the coding that was going to be needed: database backend, form controls, web service functions, etc. I started asking the team some basic questions about how things would work, started to feel a bit overwhelmed, and then said to myself, “Wait! Haven’t I learned anything? I’m diving into details way too quickly”.

I guess in the excitement, and the knowledge of the impending Sunday deadline, I wanted to start cutting code immediately. But where would that have gotten us? As I look back on the results of the weekend, we wouldn’t have gotten far. At the most, we would have had some functioning code that would now have to be abandoned due to changing ideas and requirements realized.

Luckily, I remembered what I had been blogging about for the past couple of weeks, and decided to put it into practice. So one of the first things I did was follow Getting Real’s Interface First concept (I blogged about it recently). Basically, I needed to start sketching out interfaces, rough-like, to start feeling out how the web app was going to work.

The team started to brainstorm again about how they envisioned different scenarios taking place. I wrote user stories to encapsulate these scenarios. We came up with several wireframes. One is pictured here:

Wireframe
Wireframe

Now, this wireframe may not look like much, but it was interface sketches like these that really made us start to think about how the application pieces as a whole fit together, and more importantly, how processes (both business and application) were going to be carried out.

These rough sketches brought many things to light and really helped us flesh out the project. What did we have by the end of the weekend? Wireframes and mockups. It would have been nice to have some functioning code, but we would have been way off base and throwing away a lot of work. Thinking “Interface First” saved us from going down the wrong road and helped the team narrow in on what was important. The weekend was over, but now we could hit the ground running.

Charity Tree – Interface First

So another new process for me is only thinking about the interface design at the beginning of the project — not how I’m going to code it. Usually, I’d be thinking database schema, class diagrams, coding frameworks, etc. from the get-go. This time however, as throughout this series, I’m using Getting Real from 37Signals as my guide.

Interface First
Interface First

If you’ve been following along (and if not, I have a list of articles at the bottom of this post), you’ve watched as I’ve attempted to sketch out ideas for some of the most important screens in this project. This is really quite a refreshing approach and it makes a lot of sense. As Getting Real explains, the interface is what the user sees — it IS your product. We can play around with how the app is going to look and feel right NOW and not just slap it on at the end of the project.

Sketching out interfaces and changing things around to see what feels right is a ton easier than rewriting code. We can sketch, create some loose mockups and repeat as many times as we want for minimal cost.

Articles in this series:

Charity Tree – From Idea to Implementation: Sketches – Part 2

From the previous post, you can see that I roughed out a couple of ideas for one of the most important tasks of this app: matching clients with donors. I want to revisit this task to determine what it is exactly that will need to be accomplished on this screen. Then we will rough out another interface.

Approaches

There are a few of different ways a user would want to approach the matching activity:

  1. Call up the clients waiting to be matched and find donors for them
  2. Call up the donors waiting to be matched and find clients for them
  3. Call up a specific client or donor and find available matches or remove assigned matches

Items 1 and 2 are just reciprocals. You either want to approach the matches from the clients’ or donors’ sides. Item 3 addresses organizations who are tracking possibly hundreds of clients and donors, who want to quickly locate a specific entity.

Screens Required

After a client or donor has been selected from a list or a search, the next screen would show possibly more detail about the selected entity with a list of possible entities to be matched with. At that point, a match can be made. So our screen list for this activity looks like this:

  1. Client list
  2. Donor list
  3. Search
  4. Match

Part of the goal of this phase is to answer the following question for each screen: “How do I know when it’s useful?” So for the matching activity, let’s take it one screen at a time.

Client List Screen

At this point, I’ve decided not to put the client and donor lists on the same screen. There is just too much information for both entities to be able to make informed matches from summary displays. (I’m not trying to think of too much detail here, but I know that according to the organization, some donors may specify things like, “I only want to give give gifts to children under 10”, and things like that. Details like those do not lend themselves to summary screens.)

So how will we know when this screen is useful?

  1. A list of all clients waiting to be matched can be navigated easily
  2. Enough information for each client is displayed for the user to make a decision on whether to proceed with that particular client. Generally speaking, the user will want to know the genders and ages of waiting clients.

Here is the sketch:

Interface concept for client list screen
Interface concept for client list screen

On the left side you can see the list of clients displaying basic information: the family name (since clients are grouped by family as per a typical application), and the gender and age of each individual. Also shown beneath each individual is an indication of their current gift status. Above the list is a filter bar, where the user can set the list to display only certain ages, genders, or other criteria. A scrollbar is also available to the right. So I think this interface could satisfy the two requirements: navigate the list easily and see enough information at a glance to proceed.

The right section of the screen displays detailed information about the selected client before proceeding to find a matching donor.

Donor List Screen

The donor list screen is similar to the client list in layout. However, the summary information displayed for a donor is slightly different. For each donor, described is any specifically requested criteria about who they wish to give to (teenagers, single moms, families of 4 or less, etc.) and how many openings they have left for each type.

So how will we know when this screen is useful?

  1. A list of donors waiting to be matched can be navigated easily
  2. Enough information for each donor is displayed for the user to make a decision on whether to proceed with that particular donor. Generally speaking, the user will want to know the types of clients the donor is looking for and how many.

Search Screen

I’m not sure if the search demands its own screen (a nice big and bold search box with some suggestions perhaps) or a search box will simply sit in the right section, at the top of both the client list and donor list screens.

Match Screen

After a client or donor is selected to proceed from one of their respective screens, it is time to match them up. Let’s look at a concept for the screen that would display after we’ve selected a client from the client list screen.

So how will we know when this screen is useful?

  1. A detailed view of the selected client is available
  2. A list of available donors is easily navigated
  3. A detailed view of a donor ready to be matched is available
  4. A match is able to be made

Here is the sketch:

Interface concept for a matching screen

The client is the main focal point of this screen with a view similar to that of the client list screen. Immediately to the right, however, is more information about the client. Below the main client view is a list of available donors. These donors all have openings for the entire client family. (I need to think about allowing the selection of one member of a client family at a time here, but that can wait). Each donor row displays summary information for the donor — mainly stats on what type of client they would like to donate too and how many openings they have left. Immediately to the right of the donors is a detailed view of the highlighted donor. If the user is satisfied with the pairing, the match button is clicked. (I’m also thinking of dragging individual client family members down to the openings in the donor rows to make the match).

So this was more sketching, like the previous post, but I put a little more thought behind it this time. “From Idea to Implementation”, from Getting Real by 37Signals, suggests answering questions like “What does this app need to do?” and “How will we know when it’s useful?” that I tried to address this time around.

Articles in this series:

Charity Tree – From Idea to Implementation: Sketches

As you may recall from the last post, we’ve done a little brainstorming, and now it’s time to sketch out our ideas for the interface. We don’t want to draw details. The goal here is to just get our brainstorms on paper. 37signals suggests using big writing utensils, like markers, to force yourself away from the details. We should just be sketching boxes and shapes to convey our rough interfaces to someone else.

Before I refreshed myself with Getting Real, this is what one of my interface sketches looked like:

The wrong way to roughly sketch an interface
The wrong way to roughly sketch an interface

Notice how many details I tried to think through here. I tried to plan the exact buttons that would be needed, how a user would navigate through a list, what data would populate a section, and the details of a pop-up box. This was getting way too far ahead of myself. I had the potential of locking myself into an interface before I knew everything I needed. Plus, I used color. I actually wrote another post a while ago where I declared the joy I found in brainstorming with colored pencils. I think that may still have its place, but it should be reserved for further along in this process.

So for this exercise, I stuck to a medium size drawing utensil, and only labeled something in the sketch when it would be hard to remember later what I was actually sketching.

One of the main activities of the charity tree app is to match clients with donors. This first sketch’s intention is to portray a move away from what may be normally thought of in a data matching scenario. The easy, but boring way to implement it would be to have two list boxes, side-by-side, and the user selects data from one box and moves it to the other. Here, I thought of a view of a donor who has openings for more clients. The clients are listed at the top of the screen along with some summary data. The icon for the family is perhaps dragged and dropped into one of the donor’s open spots. This would definitely make the data much more interesting to view and manipulate than dull list boxes or spreadsheet views.

Interface concept for matching clients with donors - idea 1
First interface concept for matching clients with donors

This next sketch explores a slightly different design on making the matches. Here I was thinking about interlocking clients and donors like snapping pieces of a puzzle together.

Interface concept for matching clients with donors - idea 2
Another idea on matching clients with donors

One of the other key tasks the app needs to accommodate is tracking gifts. This sketch shows an idea of looking at a specific donor, along with the clients that have been assigned to the donor, and a visual indication on the status of each gift (e.g. gifting tag sent, gift received, gift delivered). There could be a summary box at the bottom of the page displaying data such as total gifts assigned versus gifts received. Again, the details weren’t thought of too much at this point; I just wanted to portray a fun interface for manipulating the data.

Interface concept for tracking gifts
Concept for tracking gifts

Assuming we are satisfied with these sketches, we can move onto the mockups. But remember! We are not locked into the design at all. This process is about quick design iterations before we commit to the hardcore coding.

Articles in this series:

Charity Tree – From Idea to Implementation: Brainstorm

Continuing on with fleshing out my idea, we are going to look at “From Idea to Implementation” from Getting Real. This process will span several posts as we brainstorm, sketch, mockup and code.

From Idea to Implementation

Brainstorm

Brainstorming is about ignoring the details and looking at the product from a bird’s eye view. Let’s just think about what the app is going to do at a high level. Too many times we can get wrapped up in things like, “How am I going to accomplish this part?” and “Do I know how to do what I’m thinking?” Forget about that and just focus on the end user experience.

Here is what this app going to do:

  1. Accept applications from clients and donors
  2. Match clients with donors
  3. Create and send gifting cards
  4. Track gifts

I have more ideas and more details, but they can wait. If the app doesn’t accomplish these four things, it will not be useful. We will be using this list along with the points made in “What’s the Big Idea?” to make sure we stay on track.

Articles in this series:

Charity Tree – What’s the Big Idea?

As noted in the introduction to this series, I will be trying to follow the guidelines laid out by 37signals, in their fine book, Getting Real. Recently, I’ve begun to take notes in my Moleskine, on some of their essays, and will share them in these articles. These notes just scratch the surface, so I highly encourage you to read the book, that you may learn as much from them as possible.

The first guideline I will address is “What’s the Big Idea?”, where we push away all of the details until later and get to the heart of the matter. What is the purpose of this app?

What's the Big Idea?

Define the one point vision

Manage a charity tree program with ease.

Why does it exist?

Software that handles programs specifically of this type have not been found. Charity tree programs generate a lot of data which is typically tracked with paper and pencil or unorganized documents and spreadsheets.

What does this app stand for?

This app will give charity workers, typically volunteers, the tools necessary to easily manage their charity tree programs.

What makes it different?

Typical, boring, spreadsheet-like tools will not be present in this app. Users will be able to quickly view and manipulate the data that is important to them.

Stay true to the vision

During this project, any feature being considered will have to hold up to the answers given above.

Articles in this series: