<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Null is Love</title>
	<atom:link href="http://www.nullislove.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nullislove.com</link>
	<description>Code for Coders</description>
	<pubDate>Fri, 22 Aug 2008 15:04:21 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>My Tools of the Trade</title>
		<link>http://www.nullislove.com/2008/08/07/my-tools-of-the-trade/</link>
		<comments>http://www.nullislove.com/2008/08/07/my-tools-of-the-trade/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 17:31:38 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=277</guid>
		<description><![CDATA[Whenever I learn a new set of skills&#8212;such as photography or cooking&#8212;I want to learn as much as I can about the tools that the pros use.
Sure, to learn photography you need to understand exposure and depth of field, but that&#8217;s only part of what it takes to be a real photographer, to be a [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever I learn a new set of skills&mdash;such as photography or cooking&mdash;I want to learn as much as I can about the tools that the pros use.</p>
<p>Sure, to learn photography you need to understand exposure and depth of field, but that&#8217;s only part of what it takes to be a <em>real</em> photographer, to be a <em>good</em> photographer.  What camera and lenses should you buy?  What brand of film?  I even pay attention to borderline ridiculous details like what kind of camera bag the pros use.  Learning first-rate cooking skills won&#8217;t do you much good if you don&#8217;t have a good set of pans.  Any chef will tell you that having quality, sharp knives make a world of difference in the <em>experience</em> of cooking, even though it may not change the flavor. And, as I love to watch Gordon Ramsay scold, keeping a clean kitchen is an essential (and too often overlooked) step in producing quality food.</p>
<p>The point is that there is more to learn than just the fundamentals.  It makes sense to learn from the trial-and-error experience of people who are already working with these tools everyday.  I may decide I disagree with their preferences, but knowledgeably making a different choice is much better than stumbling around on my own. Plus in the process, I know I will discover some of the intricacies and pitfalls that come with working in the field.</p>
<p>In that spirit, here are the tools that help me as a web developer.</p>
<p><span id="more-277"></span></p>
<h3><a href="http://www.apple.com/macbookpro/" target="_blank">MacBook Pro (15&#8243; Intel)</a></h3>
<p>I have always been an Apple user so that is where I am the most comfortable.  It has been a great choice for web development because I can develop on OS X&#8217;s Unix and deploy on Linux.  I like having a laptop because everything travels with me.  If I need to fly to a meeting in California or teach a course in Texas, I have all my web development files with me.  I can work on the plane.  I can answer client emails from the hotel.  I can upload bug fixes as soon as I find out about them.  I prefer the 15&#8243; because the 17&#8243; is harder to lug around and I don&#8217;t need the extra width (screen height is more important for programming than width).</p>
<h3><a href="http://www.apple.com/displays/" target="_blank">Apple Cinema Display</a></h3>
<p>In order to have more screen real estate, I attach an additional monitor to my laptop.  When I&#8217;m developing, I usually keep my code and any server connections (FTP, SSH) in front of me and use my external monitor for my web browser(s).  Fix code over here, view the changes over there.</p>
<h3><a href="http://www.apple.com/macosx/features/spaces.html" target="_blank">Spaces</a></h3>
<p>Recently, I&#8217;ve also started using OS X&#8217;s Spaces to good effect.  Spaces let&#8217;s you create several virtual screens that you can quickly switch between.  It works well for me when I&#8217;m multi-tasking.  I can put email and personal web browsing in one space and then put work for three different clients in three separate spaces.  If I have a brainstorm of if a phone call comes in from a client, it only takes a second to switch spaces and start taking notes or making changes.</p>
<h3>External Hard Drive / <a href="http://www.apple.com/macosx/features/timemachine.html" target="_blank">Time Machine</a> &#038; <a href="http://www.apple.com/timecapsule/" target="_blank">Time Capsule</a></h3>
<p>Backup, backup, backup.  If cleanliness is essential to a career in the kitchen, then backing up your computer is essential to a career in programming.  It may not make your code any better but it will make the experience better.  An external hard drive is a tiny investment for a huge data insurance policy.  Of course you have to remember to use it!  At a minimum, backup once a month and/or before any trip.  For key files, I recommend keeping two versions.  You can safely throw out the oldest version when you make a new backup because you know there is another full backup. Be sure not to forget about non-obvious files like MySQL databases.</p>
<p>You can also get software to run backups for you.  I&#8217;ve tried different programs and techniques with mixed results.  The best so far is Apple&#8217;s Time Machine when pair with their Time Capsule.  Every hour, my computer boots up the Time Capsule hard drive and records any file changes.  I don&#8217;t have to remember to make the backup.  I always know I&#8217;m covered.  One of the added benefits of Time Machine is that you can also see the old versions of the files, even deleted files, in case you made a revision or deletion you didn&#8217;t mean to make.</p>
<h3><a href="http://macromates.com" target="_blank">TextMate</a></h3>
<p>Don&#8217;t attempt coding without a good text editor, especially one that has code coloring.  While I know that a lot of developers prefer a full Integrated Development Environment (IDE) over a simple text editor, I do not.  I prefer the simplicity of a tool that does one job really well.  I don&#8217;t want to have to learn the ins-and-outs of the IDE.  I don&#8217;t want to spend time wrestling with its peculiarities and bugs.  If I were working with a compiled language like C++ or Java maybe I would find an IDE more useful, but for web programming it&#8217;s easy enough to host my own development environment (whose peculiarities I already know).</p>
<p>For many years, <a href="http://www.barebones.com/products/bbedit/" target="_blank">BBEdit</a> was my favorite editor, but about three years ago I switched to TextMate and I&#8217;ve never looked back. TextMate lets me open up a whole project at once with a file drawer and tabs that make it easy to move around.  It will fold up (collapse) sections of code to get them out of my way when I&#8217;m not using them.  It lets me bookmark code to make it easy to locate later.  It has great search and replace features (searching using regular expressions is a feature I insist on).  It has customizable code coloring/formatting, a long list of language specific helpers (bundles), and many useful hot keys and shortcuts. The only feature I miss from BBEdit, is the ability to run diff on two folders.  You can manage it in TextMate but not as easily.  I still have BBEdit around for those rare times when I need it.</p>
<h3><a href="http://www.panic.com/transmit/" target="_blank">Transmit</a></h3>
<p>The best FTP software I&#8217;ve used.  Simple and reliable.</p>
<h3><a href="http://www.magnetk.com/expandrive" target="_blank">ExpanDrive</a></h3>
<p>I have recently started using ExpanDrive and I can&#8217;t say enough good things about it.  It is SFTP software that mounts a remote server as if it were a local drive.  You can drag/drop and open files using the Finder, just like they were on your Mac.  The only reason that this software won&#8217;t replace Transmit for all my FTP needs is that it is for SFTP only right now.  (Half of the servers I use use FTP and half use SFTP.)</p>
<p>One note, if you want to use ExpanDrive to open files as a project in TextMate, TextMate will slow to a crawl while it refreshes the list of files in the project every time you switch to it from another program.  There is a plugin called Remate that removes the wait and gives you a manual &#8220;Refresh Project Files&#8221; link instead.</p>
<h3><a href="http://www.phpmyadmin.net" target="_blank">phpMyAdmin</a></h3>
<p>The standard for working with MySQL databases in a simple user-friendly web interface.  I love the fact that it exposes most of the SQL requests it makes so that beginners can learn from it and pros can tweak and edit it.  I still use MySQL from the command line too, but for a quick answer, for working out complex queries, or for importing and exporting records, phpMyAdmin gets me there faster.</p>
<h3><a href="http://wordpress.org/download/" target="_blank">WordPress</a></h3>
<p>This blog uses it.  It&#8217;s easy to install for clients (or friends) who need a simple, free blog or content management system.  I also find it instructive to watch the development of WordPress, both from the code and business perspective.  The WP team is doing a lot of things right.</p>
<h3><a href="http://quickbooks.intuit.com/" target="_blank">QuickBooks</a></h3>
<p>I use QuickBooks for all my business accounting.  I use it to record deposits, write checks, and keep track of projects.  I can run a report and know which projects brought in the most revenue and which were the most profitable (not the same thing).  Four times a year I send the file off to my accountant who figures out how much I own in taxes.  Because it is designed for users with an accounting background, I&#8217;m not sure how easy it would be for a beginner to pick up on their own.  I had an accountant teach me.</p>
<h3>Dictionary &#038; Thesaurus</h3>
<p>It may sound strange, but the dictionary and thesaurus have been frequently useful to me.  Not just for writing client proposals, but for when I am <em>actually programming</em>.  Suppose you are working on a site where you need a database for &#8220;types&#8221; or &#8220;classes&#8221;.  But &#8220;type&#8221; and &#8220;class&#8221; are reserved words in most programming languages.  Just open up the thesaurus and find a synonym&#8211;maybe &#8220;brands&#8221;, &#8220;groups&#8221;, &#8220;vintages&#8221;, or &#8220;flavors&#8221;.  They can also be a great help when trying to think of new domain names, project names, or company names.</p>
<h3>Hosts: <a href="http://www.pair.com" target="_blank">Pair</a>, <a href="http://www.slicehost.com" target="_blank">Slicehost</a> and <a href="http://www.rackspace.com" target="_blank">Rackspace</a></h3>
<p>I have been a long time client of Pair.  I love them for their stability, domain management tools, and email management.  They are a great place to host an HTML or PHP site, but Ruby on Rails hosting is not one of their strengths.</p>
<p>For Rails hosting (or any hosting really), I can&#8217;t say enough good things about Slicehost. They are inexpensive, it is fast and easy to sign up or modify your account, and their online documentation is good.</p>
<p>The only downside to Slicehost is that you have to be server savvy.  When you sign up it&#8217;s literally like taking a brand new Linux server out of the box with only the base software installed.  You have to do the rest.  Beginners will do better to go with shared hosting environment where much of it is pre-configured for you.  But experts will love the freedom.</p>
<p>Rackspace is the Mercedes Benz of web hosts. I can&#8217;t afford them but some of my clients can. If a client wants reliability and top-notch customer service, and will spend the money to get it, then I refer them to Rackspace.</p>
<p>And even though I use them less frequently, I can also report good experiences with MediaTemple and LiquidWeb.</p>
<h3>Other Tools</h3>
<p>And rounding out the list would be some more obvious choices: Firefox, Safari, Internet Explorer, Photoshop, Illustrator, iCal, Mail, Keynote and iTunes.</p>
<p>I&#8217;d love to hear what tools help you.  I still have plenty to learn from others!</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F08%2F07%2Fmy-tools-of-the-trade%2F';
  addthis_title  = 'My+Tools+of+the+Trade';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/08/07/my-tools-of-the-trade/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Attachment_fu Tip</title>
		<link>http://www.nullislove.com/2008/07/29/attachment_fu-tip/</link>
		<comments>http://www.nullislove.com/2008/07/29/attachment_fu-tip/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 15:18:17 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=276</guid>
		<description><![CDATA[I installed the latest version of attachment_fu for a project I&#8217;m working on.  I ran into a problem that I wanted to document here in case anyone else runs into the same thing.
The before_thumbnail_saved callback in attachment_fu is useful for tasks like giving thumbnail versions the same attributes that parent images have.  So [...]]]></description>
			<content:encoded><![CDATA[<p>I installed the latest version of <a href="http://github.com/technoweenie/attachment_fu/wikis" target="_blank">attachment_fu</a> for a project I&#8217;m working on.  I ran into a problem that I wanted to document here in case anyone else runs into the same thing.</p>
<p>The <tt>before_thumbnail_saved</tt> callback in attachment_fu is useful for tasks like giving thumbnail versions the same attributes that parent images have.  So if an image belongs to an artist, the callback can give the thumbnail the same artist_id as the parent.  The callback originally yielded two values to a block&mdash;record and thumbnail&mdash;like this:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">before_thumbnail_saved <span class="kw1">do</span> |record, thumbnail|<br />
&nbsp; &nbsp; thumbnail.<span class="me1">artist_id</span> = record.<span class="me1">artist_id</span><br />
&nbsp; &nbsp; thumbnail.<span class="me1">visible</span> = record.<span class="me1">visible</span><br />
&nbsp; <span class="kw1">end</span></div></div>
<p>But now it yields only one value: thumbnail.  To get the same functionality as before, you will need to add a line of code to first find the parent record.</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">before_thumbnail_saved <span class="kw1">do</span> |thumbnail|<br />
&nbsp; &nbsp; record = thumbnail.<span class="me1">parent</span><br />
&nbsp; &nbsp; thumbnail.<span class="me1">artist_id</span> = record.<span class="me1">artist_id</span><br />
&nbsp; &nbsp; thumbnail.<span class="me1">visible</span> = record.<span class="me1">visible</span><br />
&nbsp; <span class="kw1">end</span></div></div>
<p>If you haven&#8217;t tried attachment_fu yet, here are some links you may find helpful:</p>
<ul>
<li><a href="http://benr75.com/articles/2008/03/16/install-rmagick-on-mac-os-x-leopard-from-source" target="_blank">Install RMagick on Mac OS X Leopard from source</a></li>
<li><a href="http://clarkware.com/cgi/blosxom/2007/02/24" target="_blank">Mike Clark&#8217;s attachment_fu Tutorial</a></li>
</ul>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F07%2F29%2Fattachment_fu-tip%2F';
  addthis_title  = 'Attachment_fu+Tip';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/07/29/attachment_fu-tip/feed/</wfw:commentRss>
		</item>
		<item>
		<title>CRUD Scaffold Generator</title>
		<link>http://www.nullislove.com/2008/06/27/crud-scaffold-generator/</link>
		<comments>http://www.nullislove.com/2008/06/27/crud-scaffold-generator/#comments</comments>
		<pubDate>Fri, 27 Jun 2008 17:14:39 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=272</guid>
		<description><![CDATA[
Rails 2.1 removed the original scaffold generator and replaced it with a new RESTful scaffold generator.
Bummer.
I&#8217;m not talking about the dynamic scaffolding that comes from putting &#8220;scaffold :model&#8221; in a controller.  That &#8220;dynamic scaffolding&#8221; was removed in Rails 2.0 and few of us miss it.  I&#8217;m talking about when you type &#8220;ruby script/generate [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.nullislove.com/wp-content/uploads/2008/06/scaffold.gif" alt="Scaffold" title="scaffold" class="alignleft" /></p>
<p>Rails 2.1 removed the original scaffold generator and replaced it with a new RESTful scaffold generator.</p>
<p>Bummer.</p>
<p>I&#8217;m not talking about the dynamic scaffolding that comes from putting &#8220;scaffold :model&#8221; in a controller.  That &#8220;dynamic scaffolding&#8221; was removed in Rails 2.0 and few of us miss it.  I&#8217;m talking about when you type &#8220;ruby script/generate scaffold Model&#8221; from the command line and get generated model, controller and view files as a result.</p>
<p>While I understand that Rails is &#8220;opinionated software&#8221; and that they want to encourage everyone to get on the REST bandwagon, I think completely removing the old scaffold generator was a mistake for one simple reason:</p>
<p><strong>It unnecessarily raises a barrier to entry for beginners.</strong></p>
<p>When beginners first start on Rails there is a lot to digest.  Installation issues, Ruby language, MVC architecture, ActiveRecord, Rails syntax, routes, migrations and deployment&mdash;just to name a few.  In my opinion, asking someone eager to learn Rails&mdash;someone who may have a background in PHP but who still doesn&#8217;t understand code blocks or the basic Rails <tt>.find</tt> syntax&mdash;to also use REST from the start is only going to frustrate them and slow the growth of Rails adoption.  They need to walk before they can run.  We have added best practices for advanced users at the expense of the newbies.</p>
<p><span id="more-272"></span></p>
<h3>The Lesson of Microsoft Excel and Lotus 1-2-3</h3>
<p>I remember when Microsoft Excel won the spreadsheet market away from Lotus 1-2-3.  They did it in part by making an easy transition path so that Lotus 1-2-3 users could make the switch painlessly.  (Lotus was also slow to adopt Windows, and Microsoft pushed out frequent releases with new features. Two other important lessons.)  It was more work on Microsoft&#8217;s part to make Excel &#8220;Lotus-friendly&#8221; and meant supporting and living with code inside Excel that must have seemed extraneous and deviated from &#8220;best practices&#8221;.  But that extra code wasn&#8217;t actually extra, it served an important function: to bring users into the product.  Without those users, you could argue that the rest of the Excel code&mdash;the &#8220;essential parts&#8221;&mdash;would not matter.</p>
<p>If we want developers to transition from other technologies to Rails, it is important to keep the barriers to entry low and to make the upgrade path simple.  Every developer who gets curious about Rails and says &#8220;Hey, I picked this up fast&#8221; will grow the audience and probably evangelize to others.  That&#8217;s exactly how Rails got it&#8217;s amazing, viral beginning.  But every developer who gets curious about Rails and says &#8220;I just tried it but I couldn&#8217;t make sense of it&#8221; is a developer whose participation, enthusiasm and evangelism we lose.  For that reason I think the decision to remove the old-style scaffolding takes Rails in the wrong direction.</p>
<h3>The Utility of the Original Scaffold Generator</h3>
<p>The original scaffold generator made Rails easier for beginners by introducing the basics of CRUD (Create, Read, Update, Delete) and by giving them an opportunity to see how the Rails request/response cycle works, how routes work, how parameters are passed, and how instance variables and object instances do or don&#8217;t persist.  It was a friendly introduction to the framework and to world of object-oriented programming for the uninitiated.  It offered a smooth transition for anyone used to PHP, Perl, Python or Java.  The beauty of the original scaffold generator code was not so much that it was useful, but that it was instructive.</p>
<h3>The Solution: CRUD Scaffold Generator Plug-in</h3>
<p>Fortunately, one of the wonderful features of Rails is it&#8217;s extensibility through plug-ins.  So the original scaffolding doesn&#8217;t have to die just yet.  I put the original scaffold generator into a plug-in, updated it (for example view templates now end in &#8220;.html.erb&#8221;) and cleaned up the views and styles a bit.  I&#8217;ve called it CRUD Scaffold (&#8221;crud_scaffold&#8221;) so that it won&#8217;t interfere with the built-in &#8220;scaffold&#8221; generator&#8217;s RESTful scaffolding and to make clear that it generates the basic CRUD for a model.  (99% of the credit goes to the original coders.)</p>
<p>You can download the plug-in by going to the github page for <a href="http://github.com/kevinskoglund/crud-scaffold-generator/tree/master" target="_blank">CRUD Scaffold Generator</a> and then clicking the download button.  Unpack the file and put the entire <tt>crud_scaffold_generator</tt> folder into the <tt>/plugins</tt> folder of any Rails application.  Run it from the command line while inside the root of your Rails application:</p>
<div class="codecolorer-container bash" style="height:35px;"><div class="codecolorer" style="font-family: monospace;">ruby script/generate crud_scaffold Modelname</div></div>
<p>Where Modelname is the name of the model for which you want to create a model, controller and views. It works just like the old <tt>scaffold</tt> command use to work.</p>
<p>There is one big change in my version that is worth noting.  The old scaffold used to dynamically read the fields from your database table, this one does not.  I never found those dynamic fields useful and found they were confusing to beginners.  Instead, my version reads the fields from the database table when you generate the scaffold.  So it is a good idea to first create/migrate your database table, then generate the scaffold.  If you add fields to your table later, you&#8217;ll have to either re-generate the scaffold or add the new fields to the views by hand.</p>
<p>My hope is that the CRUD Scaffold generator will keep it easy for beginners to get started with Rails.  I know I&#8217;ll be using it in all of my Rails courses.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F06%2F27%2Fcrud-scaffold-generator%2F';
  addthis_title  = 'CRUD+Scaffold+Generator';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/06/27/crud-scaffold-generator/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Are There Steps to Writing Code?</title>
		<link>http://www.nullislove.com/2008/06/17/are-there-steps-to-writing-code/</link>
		<comments>http://www.nullislove.com/2008/06/17/are-there-steps-to-writing-code/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 16:12:47 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=271</guid>
		<description><![CDATA[A student sent me email to ask: &#8220;In a general sense, when writing code, is there a sequence of steps or a pattern to the logic when writing the code?&#8221;
It&#8217;s a good question.  Experienced computer programmers have learned these steps&#8212;either through intuition or experience&#8212;but beginning programmers are often mystified.  Once you learn the [...]]]></description>
			<content:encoded><![CDATA[<p>A student sent me email to ask: &#8220;In a general sense, when writing code, is there a sequence of steps or a pattern to the logic when writing the code?&#8221;</p>
<p>It&#8217;s a good question.  Experienced computer programmers have learned these steps&mdash;either through intuition or experience&mdash;but beginning programmers are often mystified.  Once you learn the language syntax, how exactly do you use it to approach a programming problem? Especially if you want to try to use good programming techniques and to solve the problem in a smart and efficient way.</p>
<p>The answer to the question &#8220;Are there steps to writing code?&#8221; is &#8220;Yes&#8221;.  After the jump, I&#8217;ll give three ways to develop the logic necessary to write good code.</p>
<p><span id="more-271"></span></p>
<h3>Outline</h3>
<p>When I have a complex bit of code to write, I start by writing comments to outline what I want the code to do.  For example, imagine I&#8217;m adding an item to a shopping cart:</p>
<div class="codecolorer-container php"><div class="codecolorer" style="font-family: monospace;"><span class="co2"># get the ID of the item</span><br />
<span class="co2"># find the item in the database</span><br />
<span class="co2"># check if the item was found or not</span><br />
<span class="co2"># if not, then give an error</span><br />
<span class="co2"># if so, make sure there is enough inventory</span><br />
<span class="co2">#...and so on...</span></div></div>
<p>Once you have an outline to work from, then you can go back and write code below each comment.  It allows you to get your thoughts organized&mdash;to say &#8220;Okay, what are we trying to do here?&#8221;  Breaking a large problem down into smaller parts will make it less overwhelming and let you tackle once piece at a time.  Outlining is also a good way to make sure that you don&#8217;t skip a step once your head is wrapped up in the code details.  And, as a bonus, you&#8217;re code will already have some comments in place so you and other developers will understand the thought process.</p>
<h3>Design Patterns</h3>
<p>Design patterns describe the high-level concepts or abstractions that are frequently used in software.  (<a href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)" target="_blank">Wikipedia: Design Patterns</a>)  There&#8217;s no sense in reinventing the wheel each time.  Design patterns will not tell you how to write your code, but rather they provide a conceptual structure that can help to guide you and inform your coding choices.  Design patterns is not a beginner subject (many of them will go right over your head), but even beginners can start to make use of them.  My advice is to digest what you can, don&#8217;t worry about the rest and revisit them again each year.  Wikipedia has some good information, but the best book to learn about design patterns is <em>Design Patterns: Elements of Reusable Object-Oriented Software</em> by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides.</p>
<h3>Refactoring</h3>
<p>First make it work, then make it work better without breaking it.  In the simplest sense, that is what refactoring is.  However, like design patterns, it is possible to describe those code improvements in high-level, abstract terms.  (<a href="http://en.wikipedia.org/wiki/Refactoring" target="_blank">Wikipedia: Refactoring</a>)  You can look for &#8220;refactoring patterns&#8221; or places where a common refactoring technique can be employed to make your code clearer, faster, reusable, and overall more maintainable.  The best resource to learn more about refactoring is the book <em>Refactoring: Improving the Design of Existing Code</em> by Martin Fowler.  Refactoring techniques make use of design patterns so it&#8217;s worth exploring both.  Also, since the goal of refactoring is to improve code <em>without</em> changing the results, code testing (such as unit testing and functional testing) becomes an important skill to develop to get reliable results from refactoring.</p>
<p style="margin-top: 3em;">In my own work, I use all three.  I try to recognize the design patterns I&#8217;ll need before I start.  Next I outline before I code.  Then I just try to make it work, writing very sloppy code I would never want anyone to see.  Finally, I try to make it work better by looking for refactoring opportunities.  (And often it isn&#8217;t so much looking for fancy refactoring patterns, but just for bone-headed choices and shortcuts that I made while getting it to work.)  As I gain more experience, problems that once required me to employ all three techniques now get solved with pretty decent code from the start; and I can use those same techniques to solve harder problems.  It is a bit like when you first learned to add and subtract using your fingers but then learned how to do those calculations in your head.</p>
<p>If you are an experienced programmer with additional advice for beginners on the steps to write good code, feel free to offer it in the comments.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F06%2F17%2Fare-there-steps-to-writing-code%2F';
  addthis_title  = 'Are+There+Steps+to+Writing+Code%3F';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/06/17/are-there-steps-to-writing-code/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Baby.new</title>
		<link>http://www.nullislove.com/2008/06/13/babynew/</link>
		<comments>http://www.nullislove.com/2008/06/13/babynew/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 15:17:05 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=269</guid>
		<description><![CDATA[piper = Baby.new&#40;:name =&#62; 'Piper',
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;:born =&#62; '2008-06-09 18:22:00 EDT', 
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;:weight =&#62; &#123;:lbs =&#62; 6, :oz =&#62; 8&#125;, 
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;:length =&#62; &#123;:inches =&#62; 21.25&#125;&#41;

skoglunds.children &#60;&#60; piper

piper.daily do &#124;p&#124;
&#160; 8.times do
&#160; &#160; p.eat
&#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">piper = Baby.<span class="me1">new</span><span class="br0">&#40;</span><span class="re3">:name</span> =&gt; <span class="st0">'Piper'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re3">:born</span> =&gt; <span class="st0">'2008-06-09 18:22:00 EDT'</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re3">:weight</span> =&gt; <span class="br0">&#123;</span>:lbs =&gt; <span class="nu0">6</span>, <span class="re3">:oz</span> =&gt; <span class="nu0">8</span><span class="br0">&#125;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re3">:length</span> =&gt; <span class="br0">&#123;</span>:inches =&gt; <span class="nu0">21.25</span><span class="br0">&#125;</span><span class="br0">&#41;</span><br />
<br />
skoglunds.<span class="me1">children</span> &lt;&lt; piper<br />
<br />
piper.<span class="me1">daily</span> <span class="kw1">do</span> |p|<br />
&nbsp; <span class="nu0">8</span>.<span class="me1">times</span> <span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="kw3">p</span>.<span class="me1">eat</span><br />
&nbsp; &nbsp; <span class="kw3">p</span>.<span class="me1">poop</span><br />
&nbsp; &nbsp; <span class="kw3">p</span>.<span class="kw3">sleep</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></div>
<p><img src="http://www.nullislove.com/wp-content/uploads/2008/06/img_1096.jpg" alt="Piper" title="img_1096" width="450" height="300" /></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F06%2F13%2Fbabynew%2F';
  addthis_title  = 'Baby.new';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/06/13/babynew/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Useful JavaScript: Expandable/Collapsable Divs</title>
		<link>http://www.nullislove.com/2008/05/30/useful-javascript-expandablecollapsable-divs/</link>
		<comments>http://www.nullislove.com/2008/05/30/useful-javascript-expandablecollapsable-divs/#comments</comments>
		<pubDate>Fri, 30 May 2008 15:08:02 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=266</guid>
		<description><![CDATA[Keeping with the theme of my recent JavaScript posts, here are a couple of simple JavaScript functions that are extremely useful for creating a clean user interface. The scripts themselves are simple, but together they allow you to create the effect of a div that expands and collapses to show or hide its contents.

&#60;script type=&#34;text/javascript&#34;&#62;
function [...]]]></description>
			<content:encoded><![CDATA[<p>Keeping with the theme of my recent JavaScript posts, here are a couple of simple JavaScript functions that are extremely useful for creating a clean user interface. The scripts themselves are simple, but together they allow you to create the effect of a div that expands and collapses to show or hide its contents.</p>
<p><span id="more-266"></span></p>
<div class="codecolorer-container html"><div class="codecolorer" style="font-family: monospace;"><span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span><span class="kw2">&gt;</span></span><br />
function findElement(element_id) {<br />
&nbsp; if (document.getElementById <span class="sc1">&amp;&amp; document.getElementById(element_id)) {</span><br />
<span class="sc1">&nbsp; &nbsp; return document.getElementById(element_id);</span><br />
&nbsp; } else {<br />
&nbsp; &nbsp; return false;<br />
&nbsp; }<br />
}<br />
<br />
function hideElement(element_id) {<br />
&nbsp; element = findElement(element_id)<br />
&nbsp; if (element) {<br />
&nbsp; &nbsp; element.style.display = 'none';<br />
&nbsp; &nbsp; return element;<br />
&nbsp; } else {<br />
&nbsp; &nbsp; return false;<br />
&nbsp; }<br />
}<br />
<br />
function showElement(element_id) {<br />
&nbsp; element = findElement(element_id)<br />
&nbsp; if (element) {<br />
&nbsp; &nbsp; element.style.display = '';<br />
&nbsp; &nbsp; return element;<br />
&nbsp; } else {<br />
&nbsp; &nbsp; return false;<br />
&nbsp; }<br />
}<br />
<span class="sc2"><span class="kw2">&lt;/script&gt;</span></span></div></div>
<p>The first function simply locates an element on a page.  For example, if you pass it an element_id like &#8220;sidebar&#8221; it will locate the element with that id, such as <tt>&lt;div id=&#8221;sidebar&#8221;&gt;</tt>.  The second two functions use findElement to locate the element and then either tell it to display on the page or not.  So a hidden element can be revealed or a visible element can be hidden.</p>
<p>Though simple, these functions allow us to perform a nice slight-of-hand. We can hide a large block of text but leave the title or a short summary visible.  Clicking on the title will reveal the full text in a larger div. Clicking it again will re-hide it.  The effect is made even better by adding arrow icons: right-facing (or left-facing) for the &#8220;collapsed&#8221; or hidden state, downward-facing for the &#8220;expanded&#8221; or visible state.</p>
<p>Here is an example:</p>
<div class="codecolorer-container text" style="height:140px;"><script type="text/javascript">
function findElement(element_id) {
  if (document.getElementById && document.getElementById(element_id)) {
    return document.getElementById(element_id);
  } else {
    return false;
  }
}

function hideElement(element_id) {
  element = findElement(element_id)
  if (element) {
    element.style.display = 'none';
    return element;
  } else {
    return false;
  }
}

function showElement(element_id) {
  element = findElement(element_id)
  if (element) {
    element.style.display = '';
    return element;
  } else {
    return false;
  }
}
</script>
<div id="demo_off" style="border: 1px solid #666666; padding: 5px; margin: 2px 0;">
  <a href="#" onclick="showElement('demo'); hideElement('demo_off'); return false;" style="text-decoration: none;">
<img src="http://www.nullislove.com/wp-content/uploads/2008/05/icon_arrow_right.gif" /> First Section</a>
</div>

<div id="demo" style="display: none; border: 1px solid #666666; padding: 5px; margin: 2px 0;">
  <a href="#" onclick="showElement('demo_off'); hideElement('demo'); return false;" style="text-decoration: none;">
<img src="http://www.nullislove.com/wp-content/uploads/2008/05/icon_arrow_down.gif" /> First Section</a><br />
  <p>Longer text goes here.</p>
  <p>Click the title again to collapse the view.</p>
</div>

<div id="demo2_off" style="border: 1px solid #666666; padding: 5px; margin: 2px 0;">
  <a href="#" onclick="showElement('demo2'); hideElement('demo2_off'); return false;" style="text-decoration: none;">
<img src="http://www.nullislove.com/wp-content/uploads/2008/05/icon_arrow_right.gif" /> Second Section</a>
</div>
<div id="demo2" style="display: none; border: 1px solid #666666; padding: 5px; margin: 2px 0;">
  <a href="#" onclick="showElement('demo2_off'); hideElement('demo2'); return false;" style="text-decoration: none;">
<img src="http://www.nullislove.com/wp-content/uploads/2008/05/icon_arrow_down.gif" /> Second Section</a><br />
  <p>Text for the second section.</p>
</div></div>
<p>Here&#8217;s how you can do it yourself. Put the above JavaScript on a page.  Next, create two div elements.  In the first, put the collapsed or summary view.  In the second, put the expanded view with the full text <strong>and</strong> give the div a style attribute of &#8220;display: none;&#8221; to hide it when the page first loads.  Now you need to two links.  In the first div put a link that shows the second div and hides itself.  In the second div, put a link that shows the first div (remember: when this link is visible, the first div won&#8217;t be anymore) and hides itself.</p>
<div class="codecolorer-container html"><div class="codecolorer" style="font-family: monospace;"><span class="sc2"><span class="kw2">&lt;div</span> <span class="kw3">id</span>=<span class="st0">&quot;text_off&quot;</span><span class="kw2">&gt;</span></span><br />
&nbsp; <span class="sc2"><span class="kw2">&lt;a</span> <span class="kw3">href</span>=<span class="st0">&quot;#&quot;</span> <span class="kw3">onclick</span>=<span class="st0">&quot;showElement('text'); hideElement('text_off'); return false;&quot;</span><span class="kw2">&gt;</span></span><br />
<span class="sc2"><span class="kw2">&lt;img</span> <span class="kw3">src</span>=<span class="st0">&quot;icon_arrow_right.gif&quot;</span> /<span class="kw2">&gt;</span></span> Text Title<span class="sc2"><span class="kw2">&lt;/a&gt;</span></span><br />
<span class="sc2"><span class="kw2">&lt;/div&gt;</span></span><br />
<br />
<span class="sc2"><span class="kw2">&lt;div</span> <span class="kw3">id</span>=<span class="st0">&quot;text&quot;</span> <span class="kw3">style</span>=<span class="st0">&quot;display: none;&quot;</span><span class="kw2">&gt;</span></span><br />
&nbsp; <span class="sc2"><span class="kw2">&lt;a</span> <span class="kw3">href</span>=<span class="st0">&quot;#&quot;</span> <span class="kw3">onclick</span>=<span class="st0">&quot;showElement('text_off'); hideElement('text'); return false;&quot;</span><span class="kw2">&gt;</span></span><br />
<span class="sc2"><span class="kw2">&lt;img</span> <span class="kw3">src</span>=<span class="st0">&quot;icon_arrow_down.gif&quot;</span> /<span class="kw2">&gt;</span></span> Text Title<span class="sc2"><span class="kw2">&lt;/a&gt;</span></span><span class="sc2"><span class="kw2">&lt;br</span> /<span class="kw2">&gt;</span></span><br />
&nbsp; <span class="sc2"><span class="kw2">&lt;p&gt;</span></span>Longer text goes here.<span class="sc2"><span class="kw2">&lt;/p&gt;</span></span><br />
&nbsp; <span class="sc2"><span class="kw2">&lt;p&gt;</span></span>Click the title again to collapse the view.<span class="sc2"><span class="kw2">&lt;/p&gt;</span></span><br />
<span class="sc2"><span class="kw2">&lt;/div&gt;</span></span></div></div>
<p>Because one div hides at the same time as the next one displays, and because all the other page elements shift up or down, the effect is that the original div has simply &#8220;opened up&#8221; to reveal its contents.  You could also reverse the effect&mdash;start with an expanded div that can be folded out of the way&mdash;by simply moving &#8220;display: none;&#8221; to the other div.  You can add more expandable divs to the page and, provided you give them unique ids, they will all work.</p>
<p>It is a simple way to put a lot of information at the user&#8217;s fingertips without overloading the page all at once.  It also could save you additional page loads or MySQL calls that would result from putting the same data on a different page.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F05%2F30%2Fuseful-javascript-expandablecollapsable-divs%2F';
  addthis_title  = 'Useful+JavaScript%3A+Expandable%2FCollapsable+Divs';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/05/30/useful-javascript-expandablecollapsable-divs/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Useful JavaScript: textCounter</title>
		<link>http://www.nullislove.com/2008/05/23/useful-javascript-textcounter/</link>
		<comments>http://www.nullislove.com/2008/05/23/useful-javascript-textcounter/#comments</comments>
		<pubDate>Fri, 23 May 2008 13:46:34 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=265</guid>
		<description><![CDATA[Writing about JavaScript the other day got me thinking about some of the other JavaScript code that has helped me solve design problems in the past. Below is a script that limits the number of characters in a text area to a maximum value and also displays the number of characters that can still be [...]]]></description>
			<content:encoded><![CDATA[<p>Writing about JavaScript the other day got me thinking about some of the other JavaScript code that has helped me solve design problems in the past. Below is a script that limits the number of characters in a text area to a maximum value and also displays the number of characters that can still be added to the text area. This is useful when text area data will be stored in a database VARCHAR field which has a 255 character maximum. It allows the user to craft their response to match the allowable length <em>before</em> the form is submitted.</p>
<div class="codecolorer-container html"><div class="codecolorer" style="font-family: monospace;"><span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span><span class="kw2">&gt;</span></span><br />
var current_count = 0;<br />
var max_count = 255;<br />
<br />
function textCounter(field, target) {<br />
&nbsp; if (field.value.length &gt; max_count) {<br />
&nbsp; &nbsp; field.value = field.value.substring(0, max_count);<br />
&nbsp; } else {<br />
&nbsp; &nbsp; current_count = max_count - field.value.length;<br />
&nbsp; &nbsp; target.value = current_count;<br />
&nbsp; }<br />
}<br />
<span class="sc2"><span class="kw2">&lt;/script&gt;</span></span><br />
<br />
<span class="sc2"><span class="kw2">&lt;form&gt;</span></span><br />
&nbsp; <span class="sc2"><span class="kw2">&lt;p&gt;</span></span>255 character maximum, <br />
&nbsp; &nbsp; <span class="sc2"><span class="kw2">&lt;input</span> <span class="kw3">readonly</span> <span class="kw3">type</span>=<span class="st0">&quot;text&quot;</span> <span class="kw3">name</span>=<span class="st0">&quot;current_count&quot;</span> <span class="kw3">value</span>=<span class="st0">&quot;255&quot;</span> <span class="kw3">size</span>=<span class="st0">&quot;3&quot;</span> /<span class="kw2">&gt;</span></span> <br />
&nbsp; &nbsp; characters remaining.<span class="sc2"><span class="kw2">&lt;/p&gt;</span></span><br />
<br />
&nbsp; <span class="sc2"><span class="kw2">&lt;textarea</span> <span class="kw3">name</span>=<span class="st0">&quot;fieldname&quot;</span> <span class="kw3">cols</span>=<span class="st0">&quot;60&quot;</span> <span class="kw3">rows</span>=<span class="st0">&quot;4&quot;</span> <br />
&nbsp; &nbsp; <span class="kw3">onkeyup</span>=<span class="st0">&quot;textCounter(this, this.form.current_count);&quot;</span><span class="kw2">&gt;</span></span><span class="sc2"><span class="kw2">&lt;/textarea&gt;</span></span><br />
<span class="sc2"><span class="kw2">&lt;/form&gt;</span></span></div></div>
<p>The textCounter script runs once after each key stroke is complete (&#8221;key up&#8221;) and takes two arguments.  The first is the field being monitored, the second is the target field that will be updated with the &#8220;characters remaining&#8221; value.</p>
<p>Note that we don&#8217;t add 1 and subtract 1 for each keystroke.  Instead we use the current field length because it is possible to paste text into the field or to select and remove more than one character with a single delete keystroke.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F05%2F23%2Fuseful-javascript-textcounter%2F';
  addthis_title  = 'Useful+JavaScript%3A+textCounter';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/05/23/useful-javascript-textcounter/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Useful JavaScript: maxCheckbox</title>
		<link>http://www.nullislove.com/2008/05/20/useful-javascript-maxcheckbox/</link>
		<comments>http://www.nullislove.com/2008/05/20/useful-javascript-maxcheckbox/#comments</comments>
		<pubDate>Tue, 20 May 2008 11:09:14 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=264</guid>
		<description><![CDATA[I don&#8217;t write a lot of JavaScript.  Every now and then I need it to use it solve a design problem.  Recently, I needed JavaScript that would make sure that only three checkboxes could be checked at once. Here&#8217;s what I came up with in case it&#8217;s helpful to someone else.
&#60;script type=&#34;text/javascript&#34; language=&#34;javascript&#34;&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t write a lot of JavaScript.  Every now and then I need it to use it solve a design problem.  Recently, I needed JavaScript that would make sure that only three checkboxes could be checked at once. Here&#8217;s what I came up with in case it&#8217;s helpful to someone else.</p>
<div class="codecolorer-container html"><div class="codecolorer" style="font-family: monospace;"><span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span> <span class="kw3">language</span>=<span class="st0">&quot;javascript&quot;</span><span class="kw2">&gt;</span></span> <br />
var current_count = 0;<br />
var max_count = 3;<br />
<br />
function maxCheckbox(item) { <br />
&nbsp; if(item.checked) {<br />
&nbsp; &nbsp; if(current_count &gt;= max_count) {<br />
&nbsp; &nbsp; &nbsp; item.checked=false;<br />
&nbsp; &nbsp; &nbsp; alert('You may only choose '+max_count+' checkboxes.');<br />
&nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; current_count += 1;<br />
&nbsp; &nbsp; }<br />
&nbsp; } else {<br />
&nbsp; &nbsp; current_count -= 1;<br />
&nbsp; }<br />
}<br />
<span class="sc2"><span class="kw2">&lt;/script&gt;</span></span><br />
<br />
<span class="sc2"><span class="kw2">&lt;input</span> <span class="kw3">name</span>=<span class="st0">&quot;checkbox1&quot;</span> <span class="kw3">onclick</span>=<span class="st0">&quot;maxCheckbox(this)&quot;</span> <span class="kw3">type</span>=<span class="st0">&quot;checkbox&quot;</span> <span class="kw3">value</span>=<span class="st0">&quot;1&quot;</span> /<span class="kw2">&gt;</span></span> One<br />
<span class="sc2"><span class="kw2">&lt;input</span> <span class="kw3">name</span>=<span class="st0">&quot;checkbox2&quot;</span> <span class="kw3">onclick</span>=<span class="st0">&quot;maxCheckbox(this)&quot;</span> <span class="kw3">type</span>=<span class="st0">&quot;checkbox&quot;</span> <span class="kw3">value</span>=<span class="st0">&quot;1&quot;</span> /<span class="kw2">&gt;</span></span> Two<br />
<span class="sc2"><span class="kw2">&lt;input</span> <span class="kw3">name</span>=<span class="st0">&quot;checkbox3&quot;</span> <span class="kw3">onclick</span>=<span class="st0">&quot;maxCheckbox(this)&quot;</span> <span class="kw3">type</span>=<span class="st0">&quot;checkbox&quot;</span> <span class="kw3">value</span>=<span class="st0">&quot;1&quot;</span> /<span class="kw2">&gt;</span></span> Three<br />
<span class="sc2"><span class="kw2">&lt;input</span> <span class="kw3">name</span>=<span class="st0">&quot;checkbox4&quot;</span> <span class="kw3">onclick</span>=<span class="st0">&quot;maxCheckbox(this)&quot;</span> <span class="kw3">type</span>=<span class="st0">&quot;checkbox&quot;</span> <span class="kw3">value</span>=<span class="st0">&quot;1&quot;</span> /<span class="kw2">&gt;</span></span> Four<br />
<span class="sc2"><span class="kw2">&lt;input</span> <span class="kw3">name</span>=<span class="st0">&quot;checkbox5&quot;</span> <span class="kw3">onclick</span>=<span class="st0">&quot;maxCheckbox(this)&quot;</span> <span class="kw3">type</span>=<span class="st0">&quot;checkbox&quot;</span> <span class="kw3">value</span>=<span class="st0">&quot;1&quot;</span> /<span class="kw2">&gt;</span></span> Five</div></div>
<p>Each time a box is clicked the script runs.  If a check mark is being added then the script tests to see if the running total (current_count) is larger than the defined maximum (max_count).  If so, then it undoes the checkmark and displays an alert, but if not, then it allows the check and adds one to the current tally.  When a box is unchecked, the tally simply decreases by one.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F05%2F20%2Fuseful-javascript-maxcheckbox%2F';
  addthis_title  = 'Useful+JavaScript%3A+maxCheckbox';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/05/20/useful-javascript-maxcheckbox/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Save the Developers!</title>
		<link>http://www.nullislove.com/2008/04/30/save-the-developers/</link>
		<comments>http://www.nullislove.com/2008/04/30/save-the-developers/#comments</comments>
		<pubDate>Wed, 30 Apr 2008 11:58:16 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[CSS]]></category>

		<category><![CDATA[HTML]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=262</guid>
		<description><![CDATA[
Save the Developers! is hoping to make the lives of web developers easier, while also improving the experience for web users.  Their current campaign is Say No To IE 6! which is an attempt to rid the world of Internet Explorer 6.
How?  By getting developers to put a bit of JavaScript on their [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.savethedevelopers.org" target="_blank"><img src="http://www.nullislove.com/wp-content/uploads/2008/04/savethedevelopers.gif" alt="Save the Developers!" /></a></p>
<p><a href="http://www.savethedevelopers.org" target="_blank">Save the Developers!</a> is hoping to make the lives of web developers easier, while also improving the experience for web users.  Their current campaign is <strong>Say No To IE 6!</strong> which is an attempt to rid the world of Internet Explorer 6.</p>
<p>How?  By getting developers to put a bit of JavaScript on their website.  Developers can either link to their external JavaScript file or download the script and host it themselves. (I added it to this site.)</p>
<p>If the JavaScript detects the the user&#8217;s browser is IE 6, then a small window appears suggesting that they upgrade.  Clicking takes the user to their website which contains links to the latest versions of IE 7, Firefox, Safari and Opera.</p>
<p>They acknowledge that it may take awhile, maybe even a few years, but their goal is <em>to reduce</em> IE 6 usage as much as possible to help usher it into permanent retirement.  I think that&#8217;s a goal all web developers share.</p>
<p>It is simple, effective and&mdash;best of all&mdash;won&#8217;t bother most users because they won&#8217;t see it.  Their website will let you preview the effect, even if you don&#8217;t have IE 6.  If you don&#8217;t like the look, just modify the JavaScript to fit your site design.  If you don&#8217;t want users leaving your site, you can adapt the JavaScript so that the window links to an upgrade page on your own site.</p>
<p><strong>Remember: <em>Every time you upgrade a browser, a developer gets his wings.</em></strong></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F04%2F30%2Fsave-the-developers%2F';
  addthis_title  = 'Save+the+Developers%21';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/04/30/save-the-developers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A List Apart #257</title>
		<link>http://www.nullislove.com/2008/04/22/a-list-apart-257/</link>
		<comments>http://www.nullislove.com/2008/04/22/a-list-apart-257/#comments</comments>
		<pubDate>Tue, 22 Apr 2008 15:31:21 +0000</pubDate>
		<dc:creator>Kevin Skoglund</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.nullislove.com/?p=258</guid>
		<description><![CDATA[
A List Apart, Issue #257, has two articles on Ruby on Rails. Both articles are targeted toward Rails beginners and curious designers who may have heard the buzz but few details.
The information may be old news for many developers, but both articles are up-to-date, well-written introductions that are still worth bookmarking.  Save them for [...]]]></description>
			<content:encoded><![CDATA[<p><img src='http://www.nullislove.com/wp-content/uploads/2007/06/alistapart.png' alt='A List Apart Logo' class="alignright" /></p>
<p>A List Apart, Issue #257, has two articles on Ruby on Rails. Both articles are targeted toward Rails beginners and curious designers who may have heard the buzz but few details.</p>
<p>The information may be old news for many developers, but both articles are up-to-date, well-written introductions that are still worth bookmarking.  Save them for the next time a beginner asks you for an explanation. Forward them to co-workers who don&#8217;t understand what you&#8217;ve been raving about.  Print them out and leave them laying around so your most earnest PHP/.NET/Java friends can sneak a peak at them when no one is looking.  Maybe they can even help explain to your parents/friends/significant-other what you do for a living.</p>
<ul>
<li><a href="http://www.alistapart.com/articles/creatingmoreusinglesseffortwithrubyonrails" target="_blank">Creating More Using Less Effort with Ruby on Rails</a> by Michael Slater</li>
<li><a href="http://www.alistapart.com/articles/gettingstartedwithrubyonrails" target="_blank">Getting Started with Ruby on Rails</a> by Dan Benjamin</li>
</ul>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fwww.nullislove.com%2F2008%2F04%2F22%2Fa-list-apart-257%2F';
  addthis_title  = 'A+List+Apart+%23257';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://www.nullislove.com/2008/04/22/a-list-apart-257/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
