My Blog

contains PHP and other web related content. (Sometimes there are some off topic things - don't freak out!)

Posts Tagged ‘javascript’

Using Google Charts to make QR Codes

Tuesday, July 13th, 2010

QR Code for this page

QR Code for this page

Google Charts is my hero yet again. This time, I happened to notice that they have a chart in their API for QR Codes. Considering I was just searching google for a PHP class to do this, I was pretty ecstatic.

To implement, I made a quick line of jQuery to generate my QR Codes. Of course, I did this after the page loaded :) My goal was to generate a QR code for the page that the user is currently viewing. Pretty simple:

1
$("#qrImage").attr('src', 'http://chart.apis.google.com/chart?chs=150x150&cht=qr&chl=' + escape(window.location.href) + '&choe=UTF-8');

You can find all of the details and other parameters here: http://code.google.com/apis/chart/docs/gallery/qr_codes.html

Use your own short domain while waiting for BitLy Pro

Tuesday, May 11th, 2010

If you’ve checked out BitLy Pro, you’re probably pretty excited like I am. I saw it and immediately registered saray.me for a short URL. When I went to sign up, I found it was still in a queue system where you had to wait to get an invite. In the mean time, I still want to start using my domain.

After reading some of the documentation, I found that once you sign up for a bit.ly pro account, your existing bit.ly links that were created when you were logged in will be accessible via your short URL. With this in mind, I decided to just continue to create my bit.ly links but redirect my domain to bit.ly for the time being.

Log In to Bit.Ly

Goto bit.ly and login. (or create an account if you want). This is necessary so that you can now create and track your links.

Modify your domain

I’m using GoDaddy. I decided to forward my domain.

First, select your domain in the domain manager. Then, choose the forward domain option at the top of the list.

On the popup, choose the advanced option link. Make sure to choose temporarily forward the domain. This is needed because at some point, we’ll be redirecting this domain’s nameservers to bit.ly again to natively do this URL forwarding. Enter “http://bit.ly” in the box and click ok.

Try it out

Now, goto bit.ly and shorten an URL. I’m shortening http://aaronsaray.com/blog. This is now: http://bit.ly/cZqq0e. When I enter http://saray.me/cZqq0e into the browser, it serves the short URL from bit.ly.

Yay!

Timesaving Feature

Since I do continue to get my bit.ly links with http://bit.ly instead of http://saray.me in the beginning, I decided to make a Firefox bookmarklet to replace this for me. It’s pretty simple. All it does is take bit.ly and replace with saray.me.

1
var x=prompt('Bit.ly URL');alert(x.replace('bit.ly','saray.me'));

Here, you can drag this to your toolbar if you want :)
Saray.Me the Bit.Ly

Branding your Tweets using @anywhere tweetbox

Tuesday, May 4th, 2010

With Twitter’s new @anywhere features, it’s now possible to brand your tweets from your own web page. While I still like using Tweetdeck or Seesmic for my actual interaction on twitter, I have started tweeting a bit from my own web page as well.

@anywhere features an interactive tweetbox that you can embed on your website. The javascript call allows you to add your own content to the box – just waiting for the user to hit TWEET. (Of course, they have to connect to your website.) In order to leverage this for my own website, and brand my tweets from AaronSaray.com, I decided that I could use this box in my browser sidebar. Here are the steps – in case you want to do it yourself!

Get Your “App” an API Key

This is pretty simple. First, log into the web interface for twitter. Then, visit the apps page at http://twitter.com/apps. Click on register a new application if you need to.

On this page, you can enter all the details of your application. For the application name, I entered AaronSaray.com to provide proper branding. Last, make sure that you check Read/Write access. Your application needs to be able to post!

After this is complete, you may want to view your page’s settings. (You can do this by clicking on the name of the application on the apps page.) The important thing to do here is to access the ‘Consumer Key’ and copy this down.

Create your webpage

Next, I created a web page on my domain. It has the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head>
        <title>Twitter</title>
        <style type="text/css">
            body {
                background-color: #f3f3f3;
            }
        </style>
        <script src="http://platform.twitter.com/anywhere.js?id=CONSUMER_KEY&v=1" type="text/javascript"></script>
    </head>
    <body>
        <div id="custom-tweetbox"></div>
        <script type="text/javascript">
        twttr.anywhere(onAnywhereLoad);
        function onAnywhereLoad(twitter) {
            twitter("#custom-tweetbox").tweetBox({
                label: "<span style='color: #aaa'>Tweet this:</span>",
                height: 90,
                width: 200
            });
        };
    </script>
    </body>
</html>

First off, make sure to change CONSUMER_KEY to the actual key from your applications settings page. Next, you can change the CSS in this page to match your theme if you want. Since I’m loading this in the side bar, this is the simple layout I chose.

Finally, include the javascript and configure the tweetbox. I chose not to prepopulate my tweetbox with content. However, you could if you wish…

Add Book Mark

Add the bookmark to your browser. I added mine to my firefox bookmark toolbar. Then, I right clicked and chose properties. I checked the ‘load this in the sidebar’ option.

Use It!

The first time you use the tweet box, it will prompt you to connect to your website. After this is done, you can use this easily. My branded tweets show that its from AaronSaray.com nicely. See?

Fixing c:\fakepath in filestyle jquery plugin

Friday, March 26th, 2010

The other day I ran across an issue with the FileStyle jquery plugin. Whenever a new file was chosen, windows and Internet Explorer would put c:\fakepath\ before the filename. Turns out its not FileStyle’s issue – but a security feature of Internet Explorer.

As a quick fix, however, I made the following changes to FileStyle:

BEFORE

1
2
3
4
5
6
//snip
            $(self).bind("change", function() {
                filename.val($(self).val());
            });
 
//snip

AFTER

1
2
3
4
            $(self).bind("change", function() {
            	var s = $(self).val().replace(/(c:\\)*fakepath/i, '');
                filename.val(s);
            });

Javascript and CSS Compression and Cache

Thursday, February 25th, 2010

I’ve been researching caching and compression techniques for my external resources for some time. My first design of JEMDiary was very greedy with HTTP connections. Couple that with having a less-than-perfect host (Dreamhost bleh…), users could feel the burn. I didn’t like it because it would even take ME forever to use my own website. I went on to discover many different key points I use when creating sites now – the Steps to Optimize Assets.

Steps to Optimize Assets

There are a few steps I live by when I design my websites now.

  • Use a subdomain for images, js and css. While I don’t go overkill with this (see: not 5 page brochure website), I do try to separate assets over multiple subdomains. The important thing is not to have too many – but none what so ever limit your user from loading your site as quick as possible. I generally use one for my assets and one for user submitted assets.
  • Use sprites. Whenever possible, reduce the amount of HTTP requests by combining images. It is faster to load an image that is 3x the size of the one you’re displaying than to open 2 more HTTP connections after you download the first image.
  • Cache non changing elements as long as possible. One of the biggest things I noticed on my dreamhost server was the misconfiguration of e-tags. After disabling them, I went and looked further into caching techniques. I found that most of my assets didn’t change – so I cached them up to a year.
  • Compress away white space. After you edit the source of your css, it doesn’t need to be pretty. In fact, things like comments and white space in css and javascript are just wasted bytes… bytes you could remove… but bytes you shouldn’t remove from your source. I deal with this by making a compressed copy on build.

These are my main rules. This article, however, is going to focus on how I deal with Javascript and CSS.

Disclaimer: The methods I’m going to describe here can be labor intensive. When you build your own system, you should strive to make some of these automated.

Preparing CSS for deployment

The first thing I do is create that subdomain. For my site example.com, users can visit http://example.com for the content. I create a subdomain called assets.example.com which is where I expect to get my content from. I generally create a server alias in the main config. This technically means that duplicate content could be served at both assets.example.com and example.com. I finish up by adding the following lines to the .htaccess file:

1
2
3
4
5
6
#make sure assets load properly
RewriteCond %{HTTP_HOST} ^assets.example.com
RewriteCond %{REQUEST_URI} !^/css
RewriteCond %{REQUEST_URI} !^/js
RewriteCond %{REQUEST_URI} !^/images
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

This make sure that if the host is assets.example.com and the content is not coming form the css, js or images folder, to redirect with a 301 to the main domain. This will stop duplicate content.

Enough about this, what about my CSS?

I actually hold my css in a different folder in my architecture – not some place that is world readable. I usually call it the public_source folder – which is at the same level in the source tree as say the www or html folder. In this example, I’m going to call my example file main.css. So it is actually located at /var/www/public_source/main.css.

Next, I’ll create a file called dev.php in the assets folder where I plan to test my css from. So, this file is located at /var/www/html/css/dev.php. It may contain this content:

1
2
header ('Content-type: text/css');
readfile('/var/www/public_source/main.css');

So, now when I load my website, I can do the following to load my source css:

1
<link rel="stylesheet" type="text/css" href="http://assets.example.com/css/dev.php" />

Of course, when the website is built and deployed, we will be using a different URL.

Next, lets talk about compression of the CSS. I use CSS Tidy to compress my code. The code to invoke this is pretty simple.

1
2
3
4
5
6
7
8
9
10
11
require 'csstidy-1.3/class.csstidy.php';
$cssSource = file_get_contents('/var/www/public_source/main.css');
 
$css = new csstidy();
$css->load_template('highest_compression');
$css->set_cfg('remove_last_;',TRUE);
$css->set_cfg('sort_properties', TRUE);
$css->parse($cssSource);
$cssFinished = $css->print->plain();
 
file_put_contents('/var/www/html/css/main.1.css', $cssFinished);

You’ll notice that I named the file main.1.css. The number will be explained later (its used for caching).

So, the CSS is read, compressed and cleaned, and outputted to a location that the webserver can serve it from. Now, instead of using dev.php as the source, we’ll use main.1.css. Congratulations – a smaller CSS file!

The final thing to do is adjust the caching of this script. Whenever we change the CSS on the development platform, we’re reading it in new using dev.php. However, when this is built and deployed, it should be a built version (or compressed) of the file. This means every code deploy requires this build system. And with release numbers on main software, we’re also going to increment our file name. So our second deployment of the software package (if the CSS source has changed) will now be built using main.2.css – and the link statement will be pointed towards that.

The caching then can make the assumption that this file will never change. The CSS may change but the file is a new name then. And since we can’t just load portions of a file whenever there is a change, even a small change in a non-cached file will make the entire file load. So with this in mind, I cache my CSS files for one year. I put the following in my config:

1
2
3
ExpiresActive On
#1 yr
ExpiresByType text/css A31536000

This means that the file will be cached one year from the first time it is accessed. So, if the source HTML continues to point at the same CSS file (say… main

Making Friendly Javascript Errors – Client and Server

Thursday, January 14th, 2010

The more I look at my code I wrote in my earlier posts about the unknown _popupControl() function and the Javascript Error Handler, I see opportunities to leverage these errors into useful user interactions.

Doing a service for your visitor

After your javascript is tried and tested and error free, there are still chances that errors can be logged using my utility. These usually are the result of Spyware that is left on the user’s machine. Sometimes some removal processes don’t capture all of it. The _popupControl() method was one such remnant.

I thought that instead of just ignoring these issues, I could gently alert the user to the issue. Perhaps, I could even get affiliate commissions for a product that I know for sure removes these threats.

There are two ways to go about handling these javascript errors: client side and server side.

Client Side

Client side javascript error handling requires a bit more front-end programming. It also shows a lot of your cards to the outside world. By looking at the code in the javascript portion of your page, visitors could see all types of errors that you’re trying to detect. While I don’t think this is a deterrent to using this method, you may feel otherwise.

First things first – if you can’t remember, check out my Javascript Error Handler and Logger entry to see the code I’ll be expanding on.

My new code is going to look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
            window.onerror = function (message, url, line) {
                /** log message **/
                var i = new Image();
                i.src = 'error.php?url=' + escape(url) + '&message=' + escape(message) + '&line=' + line;
 
                if (message.indexOf('spywareWindowGenerator')) {
                    var d = document.createElement('div');
                    d.innerHTML = 'Sounds like you got spyware';
                    document.body.appendChild(d);
                }
                else if (message.indexOf('otherbaddie')) {
                    var d = document.createElement('div');
                    d.innerHTML = 'Sounds like you got some other baddie';
                    document.body.appendChild(d);
                }
            }

I’ll break it down:

First, the standard logging service is initiated on error. The error.php file will log the javascript error for further research later.

Next, I evaluate the actual message that was sent to the error handler. In this example, I’m looking for two possible issues, a reference to the function _spywareWindowGenerator() and a reference to someOtherBaddie(). Both of these functions are not defined in my code and can be considered to be remnants of the spyware infestation.

The first ‘if’ statement checks for the existence of ‘spywareWindowGenerator’ in the message. If it exists, it creates a new DIV HTML element. Then, it populates it with a message regarding this error. (Note, you could also load an image, create link, etc.). Finally, just for demonstration purpose, that DIV is added to the end of the body and is displayed.

The second if statement is simply checking for the case of ‘otherBaddie’ – and will do a similar process.

Like I mentioned before, this lays all of your cards out on the table – could potentially make your page load longer (especially if you have a lot of spyware you’re tracking), but be most versatile.

Server Side

With server side, I’m going to rely on the image that the javascript error handler is loading. If this image is populated by my error.php file, then I’ll show it.

First, the modified javascript for our error handler now looks like this:

1
2
3
4
5
6
7
8
9
10
11
            window.onerror = function (message, url, line) {
                /** log message **/
                var i = new Image();
                i.src = 'error.php?url=' + escape(url) + '&message=' + escape(message) + '&line=' + line;
 
                /** now check to see if we have something to show **/
                if (i.height) {
                    /** add it to the page **/
                    document.body.appendChild(i);
                }
            }

The first part is the standard logging mechanism that we’re used to. However, after that, I check for a height of the image that was requested. If no image was generated by the PHP GET request, then the height will be 0. Otherwise, the image object will return a height. Then, just for demonstration, I append that image to the bottom of the body of the document.

This means that we put a little bit more of the responsibility for determining the message to display to the user on the back end. At first it seems like it could be a little less verbose – as it is just an image. However, we could expand the javascript error handler to detect what ‘link’ it could display based on the image dimensions, etc. (This is for a different entry if need be…)

Next, I had to edit my error.php file. It now contains this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$keys = array();
$keys['_spywareWindowGenerator'] = 'badSypware.png';
$keys['otherBadGuy'] = 'otherBadGuy.png';
 
/**
 * check for an image to show
 */
 
$imageToShow = '';
foreach ($keys as $substring=>$image) {
    if (stripos($_GET['message'], $substring) !== false) {
        $imageToShow = $image;
    }
}
 
if (!empty($imageToShow)) {
    header('Content-Type: image/png');
    readfile($imageToShow);
    die();
}
else {
    error_log("{$_GET['message']} occured on line {$_GET['line']} of URL {$_GET['url']}");
}

The first step is to determine all of the key words that could appear in javascript error messages. Then, associate them with an image that conveys our message.

The next bit of code looks through and searches the message for any of the possibilities. If it finds one, it sets the image to be the associated value for that key.

Finally, the PHP code checks to see if there is an image to show. If so, it sends the proper header and reads the file to the output buffer. Otherwise, it assumes it is an error that we’re not familiar with and logs it.

In this example, I used the following two images just for testing.

Using Google Analytics Asynchronously

Monday, January 11th, 2010

I came across the following link on google’s code pages:
http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html

It basically details the asynchronous loading of google analytics. I found this to be a very cool addition to an already powerful package that I rely on.

However, one thing that I haven’t been able to successfully figure out. What happens when you want to load in two instances or two different accounts? On one of my sites, I use my own google analytics account plus the clients. This tracks the traffic fine with the non-asynchronous method. You simply make a new instance of the ga object and assign a new ID to it. However, can I do the same thing with this asynch method? I’m kind of wary to try it because I don’t want to lose any data.

Anyone have any experience or have any links to where I can find this detail?

document.URL vs document.location.href

Friday, December 18th, 2009

When reviewing some javascript security ideas, I came across the document.URL property. Turns out that my normal way of retrieving the location (document.location.href) is both a getter and a setter. The document.URL is just a getter.

Check it out with this code:

1
2
3
4
alert(document.URL);
alert(document.location.href);
document.URL = 'http://google.com';
document.location.href = 'http://yahoo.com';

The results are simple: you will get the current location twice – and then an error. If you comment out the document.URL line, it will redirect to yahoo.

Javascript Snow Fall with buildup

Sunday, December 6th, 2009

Mr. Skowron (his business) was working on a flash animation for a client that had a snow fall. What really irked me about the end result, was two things.
a) it was in flash
b) the snow didn’t build up

The client was happy. So that’s all good. But, I like a challenge… So I decided to make my own version.

The Snowfall Script

I didn’t want to reinvent the wheel – so I grabbed a pre-made script (by Scott Schiller). It simply adds the snowfall to the body.

Creating a snow line

The next thing I wanted to do was make a snow line that would slowly creep up. My first thought was just to have a standard white swoosh move up. This wouldn’t work because I wanted to have it scale the entire size of the monitor. Plus it wouldn’t look that natural.

I decided to make three images with various swoosh type marks about 500px wide. Then, I used photoshop to offset them by half. (Filter -> Other ->offset -> set horizontal to 1/2 the width of the image). This made the image tile-able. (It may be necessary to smooth out the new overlap you just created). All three were created, 500px wide and 50px tall.

Creating the HTML

The HTML would be pretty simple. I had to have three snow lines – oh and I wanted a tree. Let’s take a look:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head>
        <title>Snow!</title>
    </head>
    <body>
        <div id="tree"></div>
        <div id="snow1" class="snowblock"><div></div></div>
        <div id="snow2" class="snowblock"><div></div></div>
        <div id="snow3" class="snowblock"><div></div></div>
    </body>
</html>

We’ll be referring to these elements a little bit later.

Use CSS to Position Everything

The next thing to do was to give my div’s some dimension and some background images. I thought I’d start out each snow line 50px from the bottom and tile the image. Since they have transparent edges, you should be able to see varying lines of ‘horizon’ on the snow. I also placed the tree image near the right edge to give it that look I was looking for.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
            body {
                height: 100%;
                padding: 0px;
                margin: 0px;
                background: #000;
            }
            #tree {
                background: url('treeback.jpg') no-repeat;
                position: absolute;
                bottom: 10px;
                right: 20px;
                height: 396px;
                width: 530px;
            }
            .snowblock {
                position: absolute;
                bottom: 0px;
                width: 100%;
                background-repeat: repeat-x;
                height: 40px;
            }
            .snowblock div {
                background-color: #fff;
                margin-top: 40px;
                height: 0px;
            }            
            #snow1 {
                background-image: url('snow1.png');
            }
            #snow2 {
                background-image: url('snow2.png');
            }
            #snow3 {
                background-image: url('snow3.png');
            }

First, give the body some background color, get rid of paddings and set a height of 100%. The next section is the tree placement. This is pretty simple.

For each class of snowblock, they are absolutely positioned at the bottom with 100% width. I gave them each 40px height. Each image is 50px tall, but I wanted an acceptable gutter just in case.

As each image moves up, they will start to reveal the background color again. To solve this, the interior divs are given a background color of white. Their top margin is 40px – to offset them enough from the image (so as to not bleed their own background color upwards into the transparent snowline). They start out with no height.

Finally, each image div is given a background image of snow.

The magical javascript

First off, I put the following javascript include tags in the HTML

1
2
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript" src="snowstorm.js"></script>

After loading jquery and the premade script, the following javascript is executed:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        function upSnow()
        {
            var id = 'snow' + (Math.floor(Math.random()*3) + 1);
            var snow = $("#"+id);
            var filler = $("#" + id + " div");
            snow.height(snow.height() + 1);
            filler.height(filler.height() + 1);
        }
 
        $(function(){
            snowStorm.flakesMax = 250;
            snowStorm.flakesMaxActive = 100;
            snowStorm.animationInterval = 33;
            snowStorm.snowStick = false;
            setTimeout(function(){setInterval('upSnow()', 2000)}, 5000);
        });

First, the upSnow() function is generated. This will randomly pick an ID between snow1 and snow3 and inch it up 1px. The child div’s height is also increased by 1 pixel.

When the javascript fires, a few options are set for the snowStorm js library.

Finally, a timeout and an interval are set. The first timeout is used to set the interval. I don’t want the interval to start until the first flakes start hitting the ground. this takes approximately 5 seconds, so that delay is set.

After 5 seconds, the anonymous function fires off the setInterval request to run the upSnow() function every two seconds.

See it in Action

Seems to me, people like to SEE this stuff in action. Weird. Anyway, here ya go:
http://demo.aaronsaray.com/demo/snow/

Auto Failover for CDN based Javascript

Monday, November 30th, 2009

Using my javascript error reporter code helps me get a better understanding of what my clients are experiencing when visiting my website. One thing I did notice was the failures from time to time of Google’s CDN based Jquery.

To solve this issue, I decided to keep a local copy as well. For the most part, Google’s version is going to be faster and have a better cache method. However, I’d rather have an uncached version of it loaded into the user’s browser than nothing at all! So, in the very rare case that the user’s browser fails to load the Google javascript, I load a local copy of it.

First Step: Load JQuery From Google

The very first thing I do is to include jQuery from google’s code base using the following tag:

1
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

This will retrieve the latest version (1.3.2) from Google with the proper compression and cache response I like.

However, this sometimes was failing – well according to my error reporting script. What to do?

Test for a successful load of jQuery

Since the SCRIPT tag does not have an ‘onerror’ standard notifier like our image, the next best thing to do is test for the jQuery object right after the page loads. Since we’re using inline javascript, the first request to the external javascript will block while loading. When it completes, this small snippet will then execute.

I’ll jump ahead one more step though before code.

If no jQuery found, load it dynamically

If the jQuery object is not found, a new script element is created dynamically. The source is pointed to my local version of the script. Finally, it is appended to the head. Hopefully this will load the jquery. If it fails here, well then – the client has some issues!

This is the full inline javascript after the external javascript reference:

1
2
3
4
5
6
if (typeof jQuery == 'undefined') {
	var e = document.createElement('script');
	e.src = '/js/noncdn-jquery-1.3.2.js';
	e.type='text/javascript';
	document.getElementsByTagName("head")[0].appendChild(e);
}

In this case, the path http://mydomain.com/js/noncdn-jquery-1.3.2.js contains my local javascript.

The results?

Before this fix, I saw a failed jQuery load about once a day. I have not seen a single one yet. I have yet to see this error reported. If anyone finds a better way to do this, please let me know!

  • twitter loader

Follow me on twitter: @aaronsaray

The views on this website are my own and do not reflect the opinions of my employer or clients.
Creative Commons License Home | Open Source | Book | Music | Art | Bio | Resume | Contact
My Baby