Andrew Burke - Digital Construction since 1994

On Twitter

On Facebook


andrewburke.ca - Analgesic Code: Backtrack

 

Posted on: 2007-04-09 11:56:22

Previous: Baby Steps With EMACS Next: Disclaimer

Over the years I've found snippets of code that make my life easier and, like Aspirin (a name still trademarked in Canada so I guess I can't use it), get rid of the headaches.

The Back button in browsers can be a headache for web developers. If you're not careful it can cause things like duplicated information, old pages showing inaccurate information, and other badness. I've found it handy to build a 'back' button directly into my applications - that way users are more tempted to use that rather than the browser's button.

This can be implemented in Java, PHP, or whatever - but I've done it mostly in Ruby on Rails applications, so that's what the examples will show. First, set up a class called PageTrack - I'm lazy and I put it in my 'models' directory, although I guess it should be in 'lib'. This is code I wrote a while ago while I was still getting the hang of Ruby, so it's not as elegant as it could be - but I've learned not to 'fix' small code that already works unless there's a really good reason.
class PageTrack
  def self.add(session, address)
    if session && address
      session[:page_track] = Array.new if !(session[:page_track])

      # check top element - if the same as current page don't add
      previous_address = session[:page_track][-1]
      if previous_address != address
        session[:page_track].push(address)
      end
    end
  end

  def self.prev(session)
    if session && session[:page_track]
      dummy_result = session[:page_track].pop
      result = session[:page_track].pop
    else
      result = nil
    end
    result
  end
end

Nothing too complicated here - just a stack that holds all of the pages that have been visited in the current session, while skipping duplicates.

Then set up a controller action - I often have a 'redirect' controller that handles general navigation things like 'not allowed' and 'not found' pages, or figuring out what 'go home' means to different kinds of users, and since this is a redirect, it's good to go in here too:
   
# uses the PageTrack object to go back to the previous page
   def go_back
    prev_address = PageTrack.prev(session)
    if prev_address
      redirect_to prev_address
    else
      go_home
    end
  end

Next, put this onto your pages - the best place would be near the top of your application layout if you're using one:
<% PageTrack.add(session, @request.env['REQUEST_URI']) %>


This adds the current address to the top of the stack. Then, wherever you want to have a 'back' button, you can add a link like this:
<a href="/redirect/go_back">

Clicking on the link gets the previous url visited and sends you there.

I generally work on web-based business applications, where I can actually train my users, so I put the go_back link on the application logo in the top left of the screen - and they've learned that clicking on that logo goes back to the previous page, in a correct, up-to-date, and not-resubmitting-the-order-and-duplicating-the-Packing-Slip manner. Public-facing sites might want to have a more clearly labelled 'Back' link on them. Regardless, it makes a handy addition to the set of interactivity and navigation tools.

This is also handy for navigation within the system. Say you have a Packing Slip screen that can be accessed from several different places: a job overview, a listing of packing slips, a shipment report, or whatever - and you want the system to return the user to where they were once they hit 'Approve' or 'Ship' or whatever. You can't just redirect to the listing, say, since the users may have come to the slip from the shipment report or the job overview, and users like returning to where they were before. Simply calling go_back makes sure the user ends up in the expected place.

The other handy thing is if you have set up automatic mail messages that get sent to you when there's an error in your code. If you include a snapshot of the session contents, you'll get the entire PageTrack stack, which shows all of the pages that user accessed during their session - which is great for figuring out how errors are happening.

Previous: Baby Steps With EMACS Next: Disclaimer

Other Blog Posts:
- Nova Scotia and Auld Scotland
- Edinburgh: Stratigraphic Culture
- Edinburgh Without Expectations
- EasyJet: Discount Class Conflict
- Berlin: World Cup
- World of Donairs
- Berliner Ensemble
- Berlin: Museums
- Berlin: Ghosts of the Past, Visions of the Future
- Flâneur in Berlin
- Berlin: Finding the Best Wurst
- Istanbul: Overwhelmed by History in the Hippodrome
- Istanbul: That dolphin-torn, that gong-tormented sea
- Istanbul: The Topkapi Palace and Harem
- Istanbul: Mosques
- Istanbul's Basilica Cistern: Gorgeous, Creepy, Nerdy
- Istanbul: Hagia Sophia
- The Streets of Istanbul - II
- The Streets of Istanbul - I
- Munich Airport: Legoland mit Bier und NapCab
- Heathrow Airport: You Are In A Maze Of Twisty Little Passages, All Different
- Getting Ready to Travel
- Quick Advice on Canadian Indie Music
- My Favourite Roadside Sign
- Well That Explains a Lot...
- Poland: Gear from the Army Museum
- Poland: Warsaw's Palace of Culture and the University Library
- Poland: Warsaw
- Poland: Winged Hussars
- Poland
- What's awesome about Toronto
- Possibly the best sentence in the English language
- QUOTE: We Shouldn't Have Music Anxiety
- Now *that's* Santa Cruz
- Small Town Newspaper Headline Dada
- Great Quote from Seth Godin
- McSweeney's: My Pet Peeves
- Shindig!
- Dresden Dolls / Die Mannequin / Friendly Rich at the Phoenix
- In Store for 2008: Wailing and Gnashing of Teeth?!
- Coffee Updates: Urbana and Far Coast
- Canadian: Walking to Tim Horton's Through a Blizzard
- Lighting as language
- TSOT Ruby/Rails Project Night
- IE is pants, pure and simple
- Passport Canada's Secure Enterprise Software
- DemoCampToronto16
- Faulty By Design
- Buynlarge.com - brilliant!
- Joey Starts at TSOT and Jeff goes 37Signals
- How To Doom Your Own Industry
- It's Sigmoidal, Stupid!
- Quick Update on Secured OS X Mail
- Alpha Geeks and Jedi Hooligans
- Now Fake Steve is Getting Close To Home
- Nice Rant on the Sanctity of Farming
- They Must Have Been Reading This Blog
- Well, so much for Reddit
- Zipcar: My Other Car is a Mini Convertible Named Munster
- XKCD Job Interview
- John C. Dvorak Misses It
- Protecting Your OS X Mail With Encrypted Volumes
- Fake Steve Jobs hits it
- My Favorite Bit From Herodotus
- Enterprise Software - like on the spaceship, right?
- So why, again, are you taking so long?
- That sounds about right for Oberlin
- Music, With Occasional City
- How to do Google Maps-Style Scrolling Windows with JavaScript and DHTML
- The Young Gods Play Kurt Weill
- Want a Rails Job?
- Quote of the Day
- Witty and Vibrant, Sensitive and Cranky
- Facebook, already - geez
- The Bolivarian Republic of Wednesday and Pudge
- Here are the real links for the previous post
- Venezuela: How To Have A Good Party
- It's a PHONE that runs UNIX!
- Congratulations Pat & Chris!
- About Venezuela: Traffic
- Venezuela Stuff Coming Later - But While I'm Recovering...
- My most popular posts are un-published!
- ... that creepy ass botox-phenomenon
- Prototype Library and JavaScript
- Godin LG Hmb - my new guitar
- Safari For Windows - What Apple Missed
- Joel Corrects Himself In Mid-Post
- Yorkville's Summer of Love with Gucci
- Update: Coffee
- RJS / AJAX Highlight Colouring in Rails
- Looking Real Good!
- Post-something Post on Big Bags
- Disclaimer
- Analgesic Code: Backtrack
- Baby Steps With EMACS
- Back in Santa Cruz
- You know, I agree that we should worry about Global Warming...
- Life Tip: Digitize Your Documents
- Nifty OS X Finder Enhancement With Little AppleScripts
- Toronto DemoCamp 12

All Blog Entries

RSS Feed


Back