Lottery Post Journal

How to get rid of the dreaded pound sign

This is my next installment of technical blog entries dealing with technology-related techniques I've created during my re-architecting of Lottery Post.  Lottery Post is built from Microsoft technologies, including ASP.NET 2.0 (running on IIS 6.0), SQL Server 2005, and Microsoft's Atlas technologies, soon to be called the Microsoft AJAX Library, ASP.NET 2.0 AJAX Extensions, and ASP.NET AJAX Control Toolkit.

This entry deals with an issue that some people may not know about, others may not care about, and the rest know exactly what I'm talking about:  the dreaded pound sign (#) in a web page URL (link).

Normally when a new URL is entered into a web browser's Address line, the browser jumps to a new page.  However, when a pound sign (plus an identifier name) is added to the end of a web page's URL, the web browser jumps to a new location within the page.

For example, if you're scrolling down a long web page and need to go back to the top of the page quickly, some pages include a "TOP" link, which takes you to the top of the page.  The way MOST web sites do that is to include a "name" tag in the HTML code near the top of the page, like this:  <a id="top"></a>  (or it could be <a name="top"></a>).  You don't actually see the tag, but it is there as a bookmark in the page.  Then, the "TOP" link is coded like this:  <a href="https://www.lotterypost.com/#top">TOP</a>.

When you click on the TOP link, it adds "#top" to the URL in the browser's Address line, and the page jumps to the tag named "top", which is located at the top of the page.  So, to the user, they have a nice feature:  a way to quickly jump to the top of the page.

But, there are a couple of annoyances with this process that as web users and developers, we have learned to live with.  The annoyances, as I see them, are:

  1. When the link is clicked and the pound sign and tag name (like "#top") are added to the URL, the web browser has actually created a new page in its history chain.  The web page itself is not reloaded, but now when we click the Back button it essentially stays on the same page, and jumps back to where we were when we clicked the TOP link.  In my view, the purpose of the Back and Forward buttons are to move back and forward between pages, not positions on a page.  So, the pound sign wrecks the functionality of the Back and Forward buttons.
  2. The second annoyance affects web developers.  When a URL containing a pound sign is examined through program code on the server, the pound sign, and everything after it, is truncated.  There are techniques for obtaining everything after the pound sign, such as this one, but most developers don't know about the techniques, or would have a hard time implementing them.
  3. The third annoyance is most dear to my heart, as the developer of the Lottery Post forum software, and that is to be able to permanently identify a link to a piece of content (in this case a forum post), and if that content is in the middle of a page, jump directly to it.  Before coming up with the technique I'll describe below, the way I did that was to add the dreaded pound sign to the end of the URL, making the page jump directly to the content when the page loads.  But that meant that a post's PermaLink (permanent link), a link that is supposed to be valid forever, has a pound sign in it.  Yuck!  A PermaLink is supposed to identify a piece of content, not identify a bookmark location on a page.  What if the user can select other formats for viewing posts, and it is undesireable to have a pound sign (jump) in the URL?  For example, what if that post is the only thing on the page?  Obviously the pound sign is not ideal in that case.

So annoyance #3 prompted me to create a new technique.  I needed a way to create a PermaLink to every forum post, without having a pound sign in the PermaLink, and I needed to create a technique that would mimic the pound sign, and have the page jump down to the post after the page loads.

The solution was pretty straight-forward, and in front of my face for a long time, but just required putting a couple of pieces together.  The genesis of the solution came from a technique I had seen to jump to the top of a page using JavaScript, without using the pound sign.

In Lottery Post, I don't use the code <a href="https://www.lotterypost.com/#top">TOP</a> to jump to the top of a page, I use <a href="javascript:scrollTo(0,0)">TOP</a>.  That JavaScript function call scrolls the browser window to the coordinates specified, in this case "0, 0", which is the coordinates of the top-left corner.  (You can see an example of this technique in action on the Pick 6 Wheels page — check out the "Top" buttons along the right side of the page.)

There are many benefits to using scrollTo() over the pound sign, including:

  • The performance is much quicker
  • In Internet Explorer you don't hear that "click" sound that indicates going to a new page
  • There is no pound sign inserted into the URL, so the Back button functionality is not wrecked
  • As a developer, there is no need to insert a <a id="top"> tag into the HTML.

The downside of using scrollTo() is that you need to know the pixel coordinates of where you want to jump to, which for a long time ruled out my usage of the function for anything other than going to the top-left (since it would always be coordinate 0, 0).

But after noodling on this for a while I came to realize it would not be such an enormous challenge to eliminate that pound sign after all.  I would need two things:

  1. A way to locate a specific element's y-coordinate on the page (since x will always be 0, the left side of the page) and jump to that coordinate, and,
  2. A way to kick off step 1 right after the page loads.

All of this would be created in JavaScript.  Since JavaScript is required in order to use Lottery Post (and most other forum web sites) anyway, this did not create any new requirements on the part of users.

So the first function I created was called ScrollToElement(), which finds the y-coordinate of the element passed to it, and jumps there.  Passing the object itself to the function is better than passing an ID and having the function lookup the element in the DOM, because (among other things) it allows constructs such as < ..... onclick="ScrollToElement(this)">.

function ScrollToElement(obj) {
   var posY = 0;

   while (obj != null) {
      posY += obj.offsetTop;
      obj = obj.offsetParent;
   }

   window.scrollTo(0,posY);
};

This is a pretty common technique.  It works by getting the y-coordinate of an object, relative to its containing element.  If the containing element is anything other than the whole page itself, it loops again, adding the coordinate of the containing element's containing element, and so on, until it reaches the whole page level, in which case the containing element is null.

Most HTML pages written will have containing elements, as they are used to create page layouts.  Unfortunately, there is no property of an element that gives its coordinates relative to the entire page, only to the containing element, so this jury-rig is necessary.

The best place to put this function is in the <head />.  Lottery Post uses its own library of common functions that is included on each page, and this function is a good one to include in there.

So now we need a way to kick it off.

First, we want to be sure that the entire page is loaded before attempting to jump to the element, because otherwise the function may run before that element is loaded, and no jump would occur.

So the first thing I did was to create a really good generic JavaScript function for adding tasks to the page's onload() event.  I can't assume that this will be the only thing kicked off when the page finishes loading.  So here it is:

function AddLoadEvent(func) {
  var oldonload = window.onload;

  if (typeof window.onload != 'function') {
      window.onload = func;
  }
  else {
      window.onload = function() {
        if (oldonload) {
            oldonload();
        }

        func();
      };
  }
};

Someone who is pretty familiar with JavaScript will be able to go through the code for this function and understand what's happening in there.  For those who aren't JavaScript hacks, it basically looks at what is currently setup for the page's onload event, and if there is currently an onload function setup, it dynamically creates and assigns a new function to onload, which calls the old function, and then calls what we added to it.  If there was nothing already assigned, it just assigns our function as the onload function.

The function can be added to the page in any of the normal methods, using the <script /> tag, preferably in the page's <head />.

Then, all that's needed is to write the AddLoadEvent() function (with ScrollToElement() as the argument) somewhere in the body of the page.  That can be accomplished using the ASP.NET RegisterClientScriptBlock method in either the page's Load or PreRender subroutine:

Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "ScrollToPost", "AddLoadEvent(function(){ScrollToElement(document.getElementById('ElementID'));});", True)

ElementID is substituted with the DOM element ID of the block tag containing the content we want to scroll to.  For example, many times <div /> tags are used to surround a post's content.  The div tag would be given an id attribute, and that id would be substituted for ElementID.

When those three pieces are put together on a page, the pound sign can finally be eliminated!

Using that technique, Lottery Post now has good PermaLinks to individual posts like this: https://www.lotterypost.com/thread/141544.htm?get=679422

Notice that there is no pound sign at the end, yet if you click the link it behaves exactly like it was there.  After the page finishes loading, the web browser jumps down the page to the post referenced in the "get=xxxxxx" portion of the URL.

This technique has great application for forum owners, but it can also be used by anyone who wants to avoid the annoyances of the dreaded pound sign.

Over 600,000 posts (and counting)

Lottery Post hit yet another milestone, with more than 600,000 posts on the forums.

It has been a challenge to keep the technology running smoothly as the number of posts ramps up, but I think it's been pretty good.  There aren't too many forums out there with 600,000 posts in the active portion of the database.

Once a certain quantity of posts is achieved, most forums only keep a small percentage of the posts in the active part of the database, and archive the rest.  That's done in order to keep the performance of the forums running snappy.

Lottery Post is different, in that every post made over the past 6½ years is available online, and completely searchable, together with all the current posts.  (Minus a few spam posts here and there that had to be removed. Wink)  I look at it as a large-scale database challenge.

Think about it: you can go to the Lottery Discussion forum (the one with the longest history), select the option to display "ALL" posts, and instantly jump to any of hundreds of pages of topics.  It goes to whatever page you choose with about 1 second.  Then you click in to any of those posts -- maybe a post that's five years old -- and you're looking at the post contents within 3 hundreths of a second.

That was my vision for this site a long time ago, and it's neat to see it come to pass.  I wanted to run the forum with a deep, searchable history, to create an extensive and valueable resource for any lottery player.

Also notable is that Lottery Post is approaching 20 million predictions posted.  Like the forum posts, those 20 million predictions posted by the membership are all available online.  Another technology challenge, especially in trying to calculate and re-calculate individual member statistics in real-time.

New version of ieSpell available

My people probably aren't aware that a new version of ieSpell is available for free download (version 2.4.0, released August 3, 2006).

ieSpell is the spell checker that Lottery Post uses in the Rich Text editor, and is accessed with the Check Spelling button .

ieSpell is an all-around awesome application which, once installed, allows you to check your spelling on any web page on any site.  You just right-click the text entry space, and choose "Check Spelling". 

If you haven't installed it, I highly recommend it.  ieSpell is free software, and completely ad-free and nag-free.

Here's the download link:

http://www.iespell.com/download.php

There have been a couple of versions released this summer, and they include the following enhancements to the software (copied from the ieSpell web site):

  • 2.4.0 (build 428) (released 3rd August 2006)

NEW - "Look up meaning" feature via right click menu for ANY word/phrase on the page.
NEW - Added more info about ieSpell in the "Add or Remove Programs" applet.
FIX - Clean up resource IDs (removing duplicates) paving way for the resource DLLs.
FIX - Bug that cause the caption of the Options dialog not to display properly.
FIX - Registration info displays in localized text after changing language.

  • 2.3.0 (build 264) (released 28th July 2006)

NEW - Allow user to change the location of the custom dictionary (either copy or move) in the "Edit Custom Dictionary" dialog.
NEW - Added persistent window placement (survive shutdown) with a user override option (default is on).
NEW - add installer switch to set a custom user dictionary location during installation.
FIX - Make Default button is no longer enabled when a selected custom dictionary is READ-ONLY.
FIX - Bug that cause ieSpell to think that a non-existent custom dictionary is read-only.
FIX - Memory leak in spell checker - options object not freed at shutdown.
FIX - Improved support for optional language packs.

  • 2.2.0 (build 647) (released 27th March 2006)

NEW - Multi-language support! The core application has been revamped to support localization. i.e. Not only will you be able to spell check in other languages, the UI itself will displayed in that language. We will be releasing language packs for the various European languages shortly. (starting with French)
NEW - Users now have the option to choose their preferred online reference dictionary to check the meaning of an unknown word.
NEW - Users can add on their own online reference dictionaries to the list provided.
NEW - Users can choose to show or hide the ieSpell items in the browser's right click context menu. (This feature is especially useful for users with multiple logon accounts on a PC as the default install only sets up the right click options for the windows account that performed the install.)
NEW - Users now have the option to remove all the custom dictionaries during the uninstall process.
NEW - Check write permissions on custom dictionaries, if its READONLY, disable the add/delete function in the edit custom dic dialog.
FIX - Checkdocumentnode does not work for INPUT type=text elements.
FIX - IE7 beta2 does not show the word highlighted until the doc is forced to redraw. This is considered a temporary fix as contents in a DIV tag are still not refreshed by this fix. We are monitoring the developments over at the Microsoft camp and will provide a more comprehensive fix closer to the IE7 launch date.
FIX - If user click on OPTIONS in the validator dialog and return to the check, they will lose the initial context (e.g. using CheckDocumentNode).

Browzar: Simple, Privacy-Oriented Web Browser

I came across a new web browser today that is something I'd recommend everyone get a copy of.

It is quite unique, and rather than give a long description, I'll bullet the highlights:

  • It never saves browser history, typed URLs, search history, passwords, auto-completes, or cached web pages to your hard drive.  Cookies are immediately and automatically deleted when you exit the browser.  Even if it crashes, the next time you load it, it figures out that it crashed last time, and cleans up.
  • The browser is VERY lightweight, so it does not consume a lot of memory, and can be used on just about any PC.
  • It uses the Internet Explorer rendering engine (behind the scenes), so it is compatible with just about every web site out there.  For example, Lottery Post works perfectly, and looks just like it does in IE, with semi-transparent menus, shadows, etc.
  • It does not require any installation at all.  You just save the file to your hard disk and run it.  If you want to uninstall it, just delete the file.  NOTHING else is stored on your hard drive.  No registry entries, no temp files, nothing.
  • There are versions for Windows, Macintosh, and Linux, so anyone can use it.

What are some advantages to using this web browser?

This is from their web site, and it makes sense to me:

  • You're at a friend's house and you want to check your email, download Browzar in seconds and protect your privacy.
  • You have one family computer at home that everyone shares, download Browzar in seconds and protect your privacy.
  • You are on holiday and you need to check your email from an Internet café, download Browzar in seconds and protect your privacy.
  • You're at work and looking for another job, download Browzar in seconds and protect your privacy.
  • You are at work and need to check your online bank account, download Browzar in seconds and protect your privacy.

Keep in mind that there are other ways an employer or ISP can track your computer usage, but using this browser will not leave any tracks on the PC it is used on.  So it is perfect to use from a public PC or friend's house, or any shared computer.

The fact that you can quickly download it, and that it does not need to be installed makes it perfect for the task.

What are the bad things about it?

The browser is far from perfect, even though it does many things well.  Here are some BAD things I immediately found.  There may be more, I just haven't come across them yet.

  • You can't access your Favorites (bookmarks)
  • You cannot adjust any options, other than the pop-up blocker (on/off).  So it is NOT a good everyday browser, because you can't be sure exactly what its settings are.
  • It is impossible to change its Home page, so you are stuck going to the Browzar home page every time it starts.
  • The Browzar search engine (its Home page) is a thinly-disguised advertisement network, so any searches using it are useless.  When you load the browser, the first thing you should do is get away form the Home page that comes up.
  • The Forward/Back buttons on your mouse won't work.
  • Using any multi-line text editor (including the Lottery Post editor) is strange, because nothing happens when you press the Enter key.  It does not go to the next line.  You need to press Ctrl-M to do a line break.  (The company says they are aware of the problem, and are in the process of fixing it.)
  • This web browser really has no features to speak of, so again, it is not a good everyday web browser, unless you never use any features.

OK, so here's the link to their home page:

http://www.browzar.com/

You'll find the download page very easily.  Give it a try.

By the way, this blog entry was written using Browzar.