April 24, 2009

Code your JavaScript to play nice with others

Filed under: Uncategorized — chris @ 9:30 am

Generally speaking, the key to using JavaScript in a website is to do so in a way that keeps it unobtrusive. Not only should the page work at a basic level (if at all possible) without JavaScript, but your code should not conflict with another developers code if dropped into a page.

This means two things…

  1. Keep your code contained
  2. Place your code in one location

Lets see some examples. Note that I use YUI (Yahoo User Interface Library) to speed my development. However, the methods here will work with many libraries, or with no library at all.

Keep your code contained.

When you include your script into a page, you may do it via an external file or by placing your code inline in the page. If your not careful, your variables will be available to code in other places you did not mean for it to be, or you may overwrite a variables value that another developers code was used for somewhere else.

var current_value = "foo";
// do something with current value that should be foo....

//html code ... content... other stuff...

var current_value = "bar";
// do something with current value that should be bar

//html code ... content... other stuff...

// if we try to use the current_value down here, and expect it to be "foo" our code will break

How do we fix that leak? We can use an anonymous function to wrap the variables within, that way we don’t overwrite other peoples code later.

var current_value = "foo";
// do something with current value that should be foo....

//html code ... content... other stuff...

// wrap the code
(function(){
  // no when we set "current_value" it will not override the "current_value from above
  var current_value = "bar";
  // do something with current value that should be bar
})();

//html code ... content... other stuff...

// if we try to use the current_value down here, it should be the of value "foo"

This is important to understand when working with other peoples code, you’ll break something quick if you start merging code and leaving variables everywhere unwrapped.

Place your code in one location

Example, I need to build a function that lets me click a “Print” button and open a new window. I can create one object that will take an element and add all the functionality we need.


// this remains globally accessible
var AllMyStuff = {};

(function(){

  var Dom = YAHOO.util.Dom,
      Event = YAHOO.util.Event;

  var PrintPage = function(element)
  {
    this._print_element = element;
    this.init();
  };

  PrintPage.prototype = {

    _print_page_get_var: 'print_view=yes',
    _print_element: null,
    _window_name: 'PrintPage',
    _window_attributes: 'width=800,height=500,resizable=yes,scrollbars=yes,location=no',

    init: function()
    {
      // apply click event to the element
      Event.addListener(this._print_element, 'click', this.onPrintClick, null, this);
    },

    onPrintClick: function(event, args)
    {
      Event.preventDefault(event);
      var url = this.getUrlForNewWindow();
      window.open(url, this._window_name, this._window_attributes);
    }, 

    /**
     * Get the url. If there is a get variable in use, then append a new get variable after a & char
     * to indicate we want the print version. Otherwise, add the ? along with the get var.
     */
    getUrlForNewWindow: function()
    {
      var url = window.location;
      // do we have a search query (get variables)
      if(url.search.length) {
        url = url.pathname + url.search + '&' + this._print_page_get_var;
      } else {
        url = url.pathname + '?' + this._print_page_get_var;
      }
      return url;
    }

  }

// save our object in the global namespace so we can use it later
AllMyStuff.PrintPage = PrintPage;
})();

Notice how I’m using a global object to organize my code. This is one helpful habit that I ended up taking from YUI, they do this a lot and it’s helpful and keeps code organized.

The real reason for that though is that if I need to use that PrintPage object, I need to be able to do so later in the site. If I want to use this now, I just need to give the PrintPage object an element that will act as a button… for example…

< a href="printpage.html?thisPageTitle=something" id="printPageButton" > print < /a >

// given that link is on the page somewhere, I can do this to activate the print page button now...
var print_button_element = document.getElementById('printPageButton');
var print_button_object = new AllMyStuff.PrintPage( print_button_element );

If you go through the code above, you’ll notice that the object has an init function that will use that element, and automatically add any event functionality needed for that button to work.

January 16, 2009

Anti-aliasing in Illustrator vs. Photoshop

Filed under: Illustrator, Photoshop — ben @ 9:38 am

I’ve read articles applauding the pixel preview functionality of AI, especially when it comes to designing icons. While it does a good job for higher resolutions, I wouldn’t use it for 32×32 and below. Compare these two icons:

illustratorphotoshop

Both are 16×16 pixel circles drawn with vectors, and snapped to a 1×1 pixel grid. You can hover over to see which was done in Illustrator and which in Photoshop, but first decide which one looks better-rounder, sharper, use whatever criteria you want.

IMHO, the Photoshop one is better. It’s not quite as crisp, but it seems rounder. The Illustrator one looks boxy and uneven.

Here’s a 1600% zoom in on both icons:

ai_closup

Illustrator, zoomed to 1600%

ps_closeup

Photoshop, zoomed to 1600%

Note how Illustrator adds grey pixels to the left and top of the icon. It’s got to be a bug in the software. I had been considering using Illustrator for low-res icons, but based on that finding, I’ll stick with Photoshop.

December 21, 2008

Symfony on Dreamhost

Filed under: Framework, PHP — chris @ 1:36 am

A few notes on getting Symfony 1.2 to run on a Dreamhost server. Dreamhost is perfectly capable of running Symfony, but you need to make sure of a few things.

You need PHP 5 to run Symfony. It is currently installed by default, but it’s only the default for the apache user. If you ssh into your server and try to run ’symfony cc’ or any other command, it bombs or errors out. This is because in the command line under your ssh user for some reason they default to PHP 4. (go ahead, ssh in and run ‘php -v’. you’ll see.)

I fixed this by doing the following…

1. edit your ~/.bash_profile and add the line ‘alias php=/usr/local/php5/bin/php’
That will make PHP 5 the default when typing ‘php -v’ or any other php command into the terminal.

2. change how you use the ./symfony command. If your like me, you just type ./symfony cc or whatever when typing. You need to type ‘php ./symfony cc’ instead, to make sure you use your alias to run symfony under PHP 5

References
http://wiki.dreamhost.com/Installing_PHP5#Using_DreamHost.27s_PHP_5

June 20, 2008

YUI - getElementsBy TagName

Filed under: Javascript — chris @ 9:27 am

Similar to jQuery, MooTools and other Javascript libraries, Yahoo!’s YUI DOM utility offers upgraded element searches. finding an element by class name is nice, but what if you want to find an element by tag name?

YUI does not have a function named getElementsByTagName, but the getElementsBy will do just that.

getElementsBy(method, tag, root, apply)

The method attribute is the important one here. The tag, and root are mainly there to offer optimization by reducing the possible scope of items the method is ran against.

If all you need is elements by a certain tag name, just pass in a function into the first argument that always returns true, and make sure to pass in a tag name for argument 2 that your looking for.

For example,
var forms = yDom.getElementsBy(function(el){return true;},'form'); should return an array of form elements that can be accessed further.

If you need a more specific filter (e.g. only ‘a‘ tags with class=’selected’) you could interact with the el item in the function. If you return true, the item will be added to the list. Otherwise return false and it won’t be in the array.

A good resource for more YUI Dom fun can be found at klauskomenda.com

Developer cheat sheets

Filed under: CSS, Javascript, PHP, SQL, XHTML — chris @ 9:19 am

This is just a link to a great little list of cheat sheets that will probably come in handy. It has a hand full of sheets for Design (CSS / HTML), Programming (PHP, ASP, ROR, JavaScript…), Database (MySQL, PostgreSQL, SQL Server…), and others (Vi, htaccess, Regular Expressions).

If you’ve ever found yourself looking for that exact command on Google, one of these might be worth pinning to your workspace wall.

The Best Developer Cheat Sheets Around (from Webmasters by Design)

January 31, 2008

Tips to optimize your SQL and PHP

Filed under: PHP, SQL — chris @ 12:48 am

These tips will work for most SQL based server, including but not limited to PostgreSQL and MySQL.

1. Don’t use the DELETE statement

Instead, use an UPDATE statement to mark a row to be deleted at a later time. Build your database so that the tables have a ‘deleted’ column. Then, run the DELETE at a later time on all rows marked to be deleted. Just use a small boolean value in the ‘deleted’ column, or you could even call it ’status’ and leave room for more status’s of a row by using an integer or small character value.

This can be big. Put simply, an UPDATE statement is cheeper than a DELETE statement because your DELETE statement will force the entire table to re-index the primary keys and the indexed.

2. Reduce IO’s by reducing SELECT calls

If you use UPDATES a certain way, and your database is also using UNIQUE fields correctly, you can reduce SELECT statements.

For example, if you have a table where you want to decide wether to INSERT or UPDATE, you might try running a SELECT to check for the data first. That will ALWAYS result in two calls.

<?php
// this code will always result in two calls !!
$count = functRunQuery("SELECT COUNT(*) FROM user_table WHERE username='john';");
if ($count > 0) // then run UPDATE
else // run INSERT
?>

Instead, run the UPDATE or INSERT first without using a SELECT call if you can…

<?php
// this code could result in one call
$affectedRowCount = functRunQuery("UPDATE user_table SET username='bob' WHERE username='john';");
if ($affectedRowCount > 0) // we're done, don't need to do anything
else // didn't find any rows so run the INSERT here
?>

OR, if your table would probably see more successful INSERTs than UPDATEs do it the other way around (PHP5 method here)…

<?php
// this code could result in one call
try {
// try inserting the user without checking possible unique conflicts...
functRunQuery("INSERT INTO user_table (a_unique_username) VALUES ('bob')");
} catch {
// catch the error here if 'bob' is already in the database, and run an UPDATE instead
}
?>

If scalability is a possible issue for your application, you should always be looking for ways to reduce database calls and cut down on re-indexing.

January 29, 2008

PHP abstract class (my first impressions)

Filed under: PHP — chris @ 11:35 pm

I’ve been using PHP for a while now, but I’ve never dug too deep into it’s programming strengths. I’ve recently been thrown into using abstract classes in PHP. This article is just a first impression of what they are, and how I see them being useful in a project.

First, what is an abstract class? In not-so-technical terms, they seem to be just like a normal class. You define methods, variables, use a construct function, and can declare items as private or public.

abstract class FormBuilder {

	public $method;
	public $action;
	public $name;

	function __construct($name,$action,$method) {
		$this->name = $name;
		$this->action = $action;
		$this->method = $method;
	}
}

(more…)

November 6, 2006

PHP and ASP Includes

Filed under: PHP — Mike @ 11:16 pm

PHP and ASP are both very powerful server side scripting languages (SSL) that can add a lot of versatility and functionality to a website. You don’t have to understand much programming, however, to make use of one of their most handy components, include statements. Which language you use depends on what type of server your site is hosted on.

(more…)

October 2, 2006

Accessibility Basics

Filed under: CSS, XHTML — Mike @ 2:33 pm

Most people generally agree that websites should be made usable to the widest audience possible. Web designers are constantly trying to accommodate users with various browsers, but we must also consider a host of other possibilities.

It is likely an impossible task to make a decent website that is usable by everyone, but it is a noble effort to try. The major users we need to consider (in addition to those that we consider as “standard” users) include those using old browsers, screen readers, and text browsers, those with poor vision, those who are colorblind, users without Javascript, those using cell phones or other mobile device. (more…)

September 7, 2006

Javascript Cookies

Filed under: Javascript — chris @ 9:21 pm

Using a cookie with JavaScript is easy. With the cookie, you can save small bits of information that will allow you to create a customized experience for the user. Remember though, you should never save personal information in a cookie, like a social security number, a password, or a credit card number. Cookies are not a very secure way of transferring information. Also, don’t rely too heavily on JavaScript cookies since a viewer can turn them off. If you need to track viewer information or pass personal information, use server-side session variables. (more…)

Next Page »