tomhoppe.com

Racing, Web Development, Photography, and Beer...Stuff that matters.

Friday, September 5, 2008

Get Parameter from Querystring via Javascript (getParam)

A while back I posted a method to grab all the querystrings out of a URL and parse them into arrays. While that is very useful sometimes, its overkill for other situations, when you have 1 or 2 variables in the querystring and you know their names already. For those times, I like to use a function "getParam". It takes in the variable name and returns you its value from the querystring.

function getParam(name) {
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var tmpURL = window.location.href;
  var results = regex.exec( tmpURL );
  if( results == null )
    return "";
  else
    return results[1];
}

Labels: ,

Wednesday, August 27, 2008

2 ways of Javascript menu or navigation highlighting

The following two ways are the way I do client side javascript menu highlighting. These work well if you have a site navigation or menu and you want to dynamically highlight the page that you are currently on. I use Method 1 when I have only a few items in the nav, as the JS for it is super easy, or I need to have relative URLs in my menu. Method 2 is better when there are a lot of items, as it relies only on the href and url and doesn't need any extra stuff in the HTML. It does need absolute URLs in the menu href's though in order to match correctly with the url.

Method 1 - This method relies on the fact that you will put id's on each of the a elements with the value of the file name of that file. The HTML shows what I mean. The JS then just looks at the file name of the URL and makes that ID active. Super easy. There is also an "else" statement at the end of the JS so if the file name is blank because you are on "http://yourdomain.com/" it goes ahead and highlights the index menu item.

<div id="topMenu">
    <ul>
        <li><a id="index" href="">Blog</a></li>
        <li><a id="about" href="about.html">About</a></li>
        <li><a id="race_car" href="race_car.html">Race Car</a></li>
        <li><a id="contact" href="contact.html">Contact</a></li>            
    </ul>
</div>
<script type="text/javascript" language="javascript">
var fileName=location.href.toLowerCase().substring( location.href.lastIndexOf("/")+1 ).split('.')[0];
if (document.getElementById(fileName)) {document.getElementById(fileName).className = "active";}
else {if (fileName == '') {document.getElementById('index').className = "active";}}
</script>

Method 2 - This method does not need any id's in the a elements. What it does it look through the href statements in your menu and compares them to the URL. This method works better for larger menus.

<div id="topMenu">
    <ul>
        <li><a href="http://www.tomhoppe.com/test/index.html">Blog</a></li>
        <li><a href="http://www.tomhoppe.com/test/about.html">About</a></li>
        <li><a href="http://www.tomhoppe.com/test/race_car.html">Race Car</a></li>
        <li><a href="http://www.tomhoppe.com/test/contact.html">Contact</a></li>            
    </ul>
</div>
<script type="text/javascript" language="javascript">
var theUrl = location.href.toLowerCase();
var navLinks = document.getElementById('topMenu').getElementsByTagName('a');

if (theUrl == 'http://www.tomhoppe.com/test/') { navLinks[0].className = 'active'; }
else { 
    for (var i=0; i<navLinks.length; i++) {
        var NavLinkUrl = navLinks[i].getAttribute('href').toLowerCase();
        if (NavLinkUrl == theUrl) {navLinks[i].className = 'active';}
    }
}
</script>

Labels: , ,

Wednesday, August 20, 2008

Work work work work .......

I've noticed that after working a TON, as in 80+ hour weeks for a few weeks, when that stops and I go back to "normal", I have a real hard time adjusting to "normal" life. I get home and its as if my brain is used to still running at 100mph and not being able to just "sit still". Real wierd feeling. Almost as if I'm lost just relaxing, and always feeling like its wierd that I'm not "doing something".

Or maybe I just need a vacation ...... :)

Labels: , ,

First foray in PHP

So I've been a windows guy personally. Its just always what the companies where I worked used, and what I personally used. The web forum that I run has been using an antiquated ASP forum software for a while though, and it was time to move on. After evaluating some of the options, looks like vBulletin using PHP was the best one.

I have to say that I'm very impressed with my experience so far. PHP is installed and has been running like a champ on our IIS 6.0 server. The vBulletin and mySQL installs both went super smooth and I had the new forum up and running and data transferred in no time. I also made some custom php pages for redirects and the like, as well as a few edits to vBulletin's pages.

I'm happy with the speed in which I was able to sort of "pick up" php. I was a little worried at first about being able to jump into it, but its like an "easy" ASP with a little bit of asp and javascript syntax all thrown into one. All in all, easy to learn and because of the community support, there is all kinds of mySQL and php info out there on google.

Labels: , ,

Monday, August 11, 2008

Regular Expression Cheat Sheet

I just wanted to give myself a reference for a regular expression cheat sheet. This is much easier then forgetting and having to google for what I need. Pretty much all you ever need to know to setup a regexp.

. Matches any single character (many applications exclude newlines, and exactly which characters are considered newlines is flavor, character encoding, and platform specific, but it is safe to assume that the line feed character is included). Within POSIX bracket expressions, the dot character matches a literal dot. For example, a.c matches "abc", etc., but [a.c] matches only "a", ".", or "c".
[ ] A bracket expression. Matches a single character that is contained within the brackets. For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", and "z", as does [a-cx-z].

The - character is treated as a literal character if it is the last or the first character within the brackets, or if it is escaped with a backslash: [abc-], [-abc], or [a\-bc].

[^ ] Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than "a", "b", or "c". [^a-z] matches any single character that is not a lowercase letter from "a" to "z". As above, literal characters and ranges can be mixed.
^ Matches the starting position within the string. In line-based tools, it matches the starting position of any line.
$ Matches the ending position of the string or the position just before a string-ending newline. In line-based tools, it matches the ending position of any line.
\( \) Defines a marked subexpression. The string matched within the parentheses can be recalled later (see the next entry, \n). A marked subexpression is also called a block or capturing group.
\n Matches what the nth marked subexpression matched, where n is a digit from 1 to 9. This construct is theoretically irregular and was not adopted in the POSIX ERE syntax. Some tools allow referencing more than nine capturing groups.
* Matches the preceding element zero or more times. For example, ab*c matches "ac", "abc", "abbbc", etc. [xyz]* matches "", "x", "y", "z", "zx", "zyx", "xyzzy", and so on. \(ab\)* matches "", "ab", "abab", "ababab", and so on.
\{m,n\} Matches the preceding element at least m and not more than n times. For example, a\{3,5\} matches only "aaa", "aaaa", and "aaaaa". This is not found in a few, older instances of regular expressions.

Labels: , ,

Monday, June 30, 2008

Better Firefox bookmarks toolbar

I hate having "toolbars" under my address bar as it takes away real estate from webpages. Having said that, there are pages that I want access to with one click and not having to go to "bookmarks" and searching for them. I found a cool little way to have your cake and eat it to by moving the bookmarks toolbar items to the main file toolbar. They fill out the otherwise unused space between "Help" and your window controls.

  • Enable your Bookmarks Toolbar under View, Toolbars.
  • Go to View, Toolbars, Customize
  • Drag the "Bookmarks Toolbar Items" from the Bookmarks toolbar to the top bar next to "Help"

Now you can change those items around to have shorter descriptions so they fit. I ended up removing the names and going by just the icons. When you bookmark something that you want in there, just add it to the bookmarks toolbar and it pops up there. Brilliant!

Labels: , ,

Monday, June 23, 2008

Google AJAX Libraries API

Kind of old news, but Google is now hosting the latest and greatest versions of the most popular JS libraries including jQuery, prototype, script_aculou_us, etc

Because of the gzip compression and fast response of google's servers, these files get to the users fast!

You can either use google's loader or just link to the permanent paths of the files.

The Ajaxian has a great article on this

Labels: , ,

Monday, June 9, 2008

iUI is awesome

It looks like I will be an official iPhone convert here shortly. I've been playing with some iPhone looking pages lately at work, and got to use the iUI JS library that Joe Hewitt created.

This library is awesome. It lets you code a page in standard, plain HTML and then converts the CSS/JS to an iPhone look and feel. Also, it sets up your links to enable the "slide in" navigation to work correctly between your links. Plain genius and its oh so easy to use.

With this work and the new "Corporate Friendly" 3G iPhone that is coming soon, I'm hoping to be able to get rid of this POS Palm 700w that I've been cursed with, and go to the iPhone for my phone/email device. I'm very excited. We'll see what happens!

Labels: , ,

Tuesday, April 15, 2008

Use it or lose it.....

Its amazing how fast you lose a skill if you don't use it for a few years

In my current day job of product development and client-side engineering, I haven't been messing much with ASP, other then the occasional support for some in-house apps

I recently took a side job to make a database driven website for a jewelry store. The front end was a piece of cake, and took less time then I estimated. The asp back-end/adming tool/shopping cart on the other hand, bleh. Having been working pretty much 100% with Javascript, I "lost" the ASP syntax, methods, etc. I had to look all that up on google. I knew "what" I wanted to do, but I just couldn't write it off the cuff like I can with JS these days.

In the end, it took certainly longer then planned, but I'm glad that I did it. I got the "asp mindset" back, and I haven't lost a step in my day job either. Guess I came out smarter overall :)

Labels: , , ,

Tuesday, March 18, 2008

addDomLoadEvent

Using window.onload for Javascript creates a crappy UI, as it waits for the entire page, including all CSS, JS, and images to load. I avoided as much as possible, but for some things in the day job, we needed to use it. The best example being that we only had access to JS in the head of the page, but needed to immediately client side add some code to the bottom of the page.

For this, we used addLoadEvent and waited till everything was done. Having been fed up with this, I did some a big of searching and found a solution from The Future of the Web, by Jesse Skinner. Jesse's script puts together a cross-browser way to wait for just the DOM to load, instead of all the images and text

This is easy for FF, Safari 3 Beta, and Opera, but a pain for IE and Safari 2. I changed his script slightly to be compatible with https and came up with the below code. Thanks Jesse!

.
addDOMLoadEvent = (function(){
    // create event function stack
    var load_events = [],safari_timer,done,exec,script;
 
 var init = function () {
            done = true;

            // kill the timer
            clearInterval(safari_timer);

            // execute each function in the stack in the order they were added
            while (exec = load_events.shift())
                exec();

            if (script) script.onreadystatechange = '';
        }

    return function (func) {
        // if the init function was already ran, just run this function now and stop
        if (done) return func();

        if (!load_events[0]) {
            // for Mozilla/Opera9
            if (document.addEventListener)
                document.addEventListener("DOMContentLoaded", init, false);
    
   /*@cc_on @*/
   /*@if (@_win32)
   var proto = "src='javascript:void(0)'";
   if (location.protocol == "https:") proto = "src=//0";
   document.write("<scr"+"ipt id=__ie_onload defer " + proto + "><\/scr"+"ipt>");
   var script = document.getElementById("__ie_onload");
   script.onreadystatechange = function() {
    if (this.readyState == "complete") {
     init()
    }
   };
   /*@end @*/

            if (/WebKit/i.test(navigator.userAgent)) { // sniff
                safari_timer = setInterval(function() {
                    if (/loaded|complete/.test(document.readyState))
                        init(); // call the onload handler
                }, 10);
            }

            old_onload = window.onload;
            window.onload = function() {
                init();
                if (old_onload) old_onload();
            };
        }

        load_events.push(func);
    }
})();

Labels: ,

Drag and drop Javascript

I found a great overview of drag and drop by Quirksmode today, and I wanted to make sure I didn't lose it or forget about it. Its a great explanation of drag and drop through JS with code examples, demos, and exactly how it does what. I only had a few minutes to look through it but it looks awesome.

Labels: ,

Dynamically adding CSS through Javascript

I found this little tip by accident while surfing the web to solve a different problem. Thanks to the Yahoo User Interface Blog for the solution!

When adding in a piece of HTML dynamically, what do you do with the styles for it? In the past, I usually included the styles in a global or page specific stylesheet where I knew the HTML would show up. The current snippet I was writing through, was going to add some code in random places throughout a 4000+ page website as well as some partner sites, so it needed to come with its own CSS. FF allows you nicely to just embed a <style> tag anywhere in a page with your styles and be done with it. IE and Safari, not so much.

What I found on the YUI Blog was the cssText property of the stylesheet property. This allows for a cross browser way for us to insert a string of css into a style element in the head. Beautiful! Just create your css as a string and pass it into the addCSS function below.

function addCss(cssCode) {
var styleElement = document.createElement("style");
  styleElement.type = "text/css";
  if (styleElement.styleSheet) {
    styleElement.styleSheet.cssText = cssCode;
  } else {
    styleElement.appendChild(document.createTextNode(cssCode));
  }
  document.getElementsByTagName("head")[0].appendChild(styleElement);
}

Labels: , ,

Monday, March 10, 2008

Cross Sub Domain Javascript (Ajax, Iframe, etc)

So we've been dealing with an issue at work with cross sub domain JS. Basically, JS believes that even a subdomain such as img.yourdomain.com is a different domain from www.yourdomain.com. Because of that, AJAX across pages from those two subdomains will not work. Also if you have an iframe from one to another, you will not be able to refence JS vars or functions back and forth.

After a good bit of digging, I discovered a way around this. This involves setting up an iframe html on one domain and then calling that iframe from the page on the other subdomain. You have to set the document.domain to the same thing on both the parent page and its iframe, in order for them to talk to each other.

document.domain = "yourdomain.com"

Once that is set, the two pages now think they are on the same domain.

For example, for pulling in text, setup your page on www.yourdomain.com and set document.domain to yourdomain.com. If you are trying to pull in an html page using Ajax from img.yourdomain.com, setup a page that, will become the iframe, to do the ajax pull. After that pull is complete set the document.domain to yourdomain.com. In your page on www. create an iframe which has the src set to your page on img. Since document.domain is set, any functions on the parent page are available to be called via the iframe. Lets say you want to put your newly "ajaxed" html into a div on the parent page, you can do that via "parent.getElementById('yourDivName').innerHTML = Response.Text".

If you are pulling in XML, you can setup the page/iframe relationship the same as above. That iframe will make the ajax call to the XML on img.yourdomain.com and do something with it, lets say turn it into an array. Once that is completed, set the document.domain on the iframe page. At this point, the parent page can access that array on its iframe via "iframeName.arrayName". Alternatively you can have an array read on the parent page for this information and pass it to the parent from the iframe via "parent.arrayName = iframeArray".

Labels: ,

Friday, March 7, 2008

Cross browser, self closing popup window

If you want to a cross browser way to have your popup self close

onsomething="window.opener=self;window.close();"

This works in most browsers, but doesn't work in FF 2.0 unless the window was in fact popped up. The window.opener=self fools most browsers, but FF is smarter :-)

I know its bad usability, but the context I used it in, was that a window was popping up a poll. On submitting that poll, the poll popup would close itself and the results on the opener were updated. The code for that is below. I put that code on the submit button onclick. I had to name the opener window in order for it to work. This way if there is an opener, it will try to target "jjCalendar" as the forms target. If that name doesn't exist, it will just open a new window.

onclick="if (window.opener){form.target='jjCalendar';}"

Labels: ,

Monday, February 11, 2008

Add class name to div id

Here is a script to add an extra class name to a div with an id regardless of what is there now.

function addClassName (id, classname) {
   var e;
   if (typeof(id) == 'string') {e = this.getElementById(id);} 
   else {e = id;}

   if (!e || typeof e.className != 'string') {
      throw "Cannot add class to element " + id;
   }

   /* Check if the class is already there */
   if (!e.className.match(new RegExp('\\b' + classname + '\\b'))) {
      e.className += ' ' + classname;
   }
}

Labels: ,

Grab filename from window location

Here is a snippet I use to grab the filename from the full window location of page.

var filename = location.pathname.substr(location.pathname.lastIndexOf("/")+1,
location.pathname.length);

Labels: ,

Tuesday, July 17, 2007

Assign the child's href to the parent's onclick

This is a cool little snippet for making realistic CSS buttons. It will do an onclick location on the element to the href of its first a element.

Makes it nice when you have a "fake button" done through CSS and you want the whole thing to be clickable.

What I usually try to do is CSS the A tag display:block and assign it a width, height and padding, but when you can't do that, this little snippet is a life saver

onclick="if (this.getElementsByTagName('a')[0])
location=this.getElementsByTagName('a')[0].href;"

Labels: , ,

Querystring parsing

Here is a snippet that will pull out and parse out the query string using JS. It separates the query string into two arrays. One with the variable names and the other with the values. You can then loop through the arrays to get your information. This script is useful if you have lots of variables in your querystring, or are not sure what is going to be coming in. I also have another snippet which just grabs the value of one variable instead.

function QueryString(key){
  var value = null;
  for (var i=0;i<QueryString.keys.length;i++) {
    if (QueryString.keys[i]==key)  {
      value = QueryString.values[i];
      break;
    }
  }
  return value;
}

QueryString.keys = new Array();
QueryString.values = new Array();

function QueryString_Parse(){
  var query = window.location.search.substring(1);
  var pairs = query.split("&");
 
  for (var i=0;i<pairs.length;i++) {
    var pos = pairs[i].indexOf('=');
    if (pos >= 0)  {
      var argname = pairs[i].substring(0,pos);
      var value = pairs[i].substring(pos+1);
      QueryString.keys[QueryString.keys.length] = argname;
      QueryString.values[QueryString.values.length] = value;  
    }
  }
}

QueryString_Parse();

Labels: ,

Find something in a string

Here is a quick snippet that sets a variable to the location of a certain string inside another string. The example I'm using is searching for "asdf" in the URL. You can use this to tell if you are on a certain page.

var theUrl= location.href;
var is_asdf = (theUrl.indexOf("asdf") != -1);

Labels: ,

Font sizer for a content well

We are using this font sizer where I work. It change the font size on all tags inside of div "textArea" that do not have a specifc font size defined. That way, your regular p tags and headers will font size, but if you must keep something the same, you can override. All it does it set a class on the content container div, defining the font size within. Its too long to include as a snippet, so you can get it here.

Labels: ,