Renaissance Nerd

  • Random
  • Archive
  • RSS
  • Ask me anything

A Thought Experiment: Pixel Art

We know we can draw a 45-pixel × 45-pixel square using an empty div and some CSS.

.square {
    background-color: #fff;
    border: 1px solid #ccc;
    height: 45px;
    width: 45px;
}

And we know that we can make the square’s background color red using jQuery.

$('.square').css('background-color', 'red');

If we take this snippet a bit further, we can alter the square’s background color when it’s clicked.

$('.square').click(function() {
  $(this).css('background-color', 'red');
});

But what if we want to turn it off again—that is, what if we want the background of the square to be white if it’s clicked while the background is red?

$('.square').click(function() {
  var newBackground = ($(this).css('background-color') == 'rgb(255,255,255)') ? 'white' : 'red';
  $(this).css('background-color', newBackground);
});

Now we can toggle the square’s color like a switch. Which is utterly useless. Unless you float the square, duplicate it 15 times, wrap all 16 in a row, then duplicate the row 11 times. Now we have a 16 × 12 grid of squares that can be toggled on an off. We’ve created a pixel art canvas.

In this demo, I’ve taken the idea beyond just the basic grid of squares that can be toggled and added a rudimentary color palette. Each palette box uses an HTML5 data attribute—in this case, data-color—to hold the color of the box, which is set via JavaScript. Finally, using a conditional to check for the presence of on-touch handlers, I optimized the whole thing for use on the iPad, which was the ultimate goal of this experiment.

if ('ontouchstart' in document.documentElement) {
  // Handle touch events
  ...
}

When I started out, I didn’t know that onClick events suffer from a delay of a couple hundred milliseconds on touchscreen devices, which causes interactions to feel very sluggish if you rely on jQuery’s click listeners. You can see here how I wired up touch events in favor of click events when the page is loaded on a touch-enabled device. The JavaScript isn’t pretty, but it’ll suffice for a project that I spent about an hour on.

There was no real purpose to this, no ultimate goal. I just had the idea in the shower and wondered if I could do a quick prototype.

    • #html
    • #css
    • #javascript
  • 2 weeks ago
  • 5
  • Comments
  • Permalink
  • Share

Mapping JSON Object Arrays With CoffeeScript

This might be a well-known technique for some of you, but it was new to me when I stumbled onto it last week.

I have a Rails app that’s grabbing some JSON data via AJAX and using the resulting data to display a chart using Highcharts. If you haven’t seen it, Highcharts is a JavaScript library for displaying gorgeous, interactive graphs and charts.

Without getting into the full implementation, when you create a line graph, you have to pass an array of numbers to Highcharts, like this:

series: [{
  name: 'Tokyo',
  data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}

Suppose you get a JSON object back that contains an array of numbers called data. You could just pass it in to Highcharts, right?

series: [{
  name: 'Tokyo',
  data: json['data']
}

Nope. The gotcha is that the values returned in the data array are actually strings, not numbers, so Highcharts will choke if you don’t convert the data from strings to numbers. This is pretty easy. Iterate over the array, typecast the values, store them in a new array, right?

var numerical_data = []
$.each(json['data'], function(k, v) {
  numerical_data[k] = (Number) v;
}

It works, but that’s an ugly approach. Suppose you’re drawing multiple lines, each of which requires its own array of numbers. Doing the conversion via iteration ends up looking really, really gross, and you’ll likely end up duplicating a lot of code.

CoffeeScript’s .map function to the rescue:

series: [
  name: "Cu"
  data: json['data'].map (s) -> (Number) s
,

The map function handles the processing of each item in the array for you and returns a new array with the modified values. If you’re familiar with Ruby, this should look pretty familiar. It’s super-clean, it sticks with the DRY principle, and it’s very easy to read.

    • #coffeescript
    • #JavaScript
    • #json
  • 2 months ago
  • Comments
  • Permalink
  • Share

Using Rake, Pow, and TextExpander for Project Templates

TL;DR: I made a Rakefile to automate the creation of a project template that pulls fresh copies of either Twitter Bootstrap or the HTML5 Boilerplate from GitHub. I serve the template’s HTML with Pow, and I use TextExpander fills to generate boilerplate snippets.


Over the years, I’ve put together a number of project templates, each containing its own set of default HTML, CSS, and JavaScript that I would—invariably—abandon. Each would start off with the best intentions, but I’d fail to routinely update them. They’d grow stale, my workflow would change, and I’d start again.

This cycle repeated itself again recently as I started to move back to Web development in my spare time. Wanting to try out some responsive design techniques, I grabbed a copy of the HTML5 Boilerplate project, tweaked it, added some media queries, and posted it to GitHub. I deleted the repository yesterday because I realized that keeping my template in sync with the HTML5 Boilerplate’s releases would be tedious. Thinking about the problem differently, I turned to Rake, and I’m pretty happy with the results.

Workflow

These days, when I start a project, shortly after some sketching but before I even think about what back-end technology will be powering the site, I focus on building the interface using plain old HTML. My default directory structure looks like this:

I like to use CoffeeScript with Jitter, so I include directories named /coffee and /js. Everything else is pretty straight-forward: /css for CSS, /images for images, and a /resources directory for storing things like PSD files, icon sets, and other project-specific clutter. Finally, the /docs directory is for annotated CoffeeScript documentation that’s generated with Docco.

I create an empty file called application.coffee in the /coffee directory, which ends up compiled to application.js in the /js directory. I also include an empty application.css file in the /css directory. Finally, I toss in an empty index.html file.

If I use a framework like the HTML5 Boilerplate project or Twitter Bootstrap, I download the package and place the project’s various assets into the appropriate directories. The HTML5 Boilerplate’s index.html becomes the default index file when I use that project.

With all of the files in place, I initialize an empty Git repository and start cranking out code. But there’s an easier way.

Rake

This file handles all of the above for me by providing three command-line options.

$> rake newblank

This creates the blank project directory structure and a handful of empty files as outlined in the Workflow section above (complete with a Git repository).

$> rake newhtml5

This clones a copy of the HTML5 Boilerplate project, places its files in the proper directories, and creates a new Git repository.

$> rake newtwitter

This clones a copy of the Twitter Bootstrap project, moves the JavaScript and image assets into the proper directories, compiles the .less files into a single CSS file, runs a quick find-and-replace on the compiled CSS to change references to ../img into ../images because I’m tightly wound and like to name my images directory /images, and creates a new Git repository.

To use it, create a directory for your project and place the contents of this Gist into a file in that directory. Name the file Rakefile. Then, cd into your project’s directory and run one of the above commands.

Advantages

I don’t have to keep my template in sync with changes to projects I use (e.g., the HTML5 Boilerplate project). I don’t have to keep a blank project template full of empty files and directories lying around that will grow stale and require maintenance. I always get the latest HTML5 Boilerplate and Bootstrap code when starting a new project. Everything’s boiled down to one file that’s far easier to maintain and tweak as my needs change. And if a new set of fancy boilerplate comes out, all I have to do is write a new Rake task to add it to my arsenal.

Pow

You can use Pow to serve the flat HTML files you create using any of the templates that are generated by this Rakefile.

Create a directory for your project, and then create a public directory inside your new project’s directory. Place a copy of the Rakefile in the public directory. It should look like this:

cd into the public directory, and run one of the commands to generate the template structure. Then—just like you would with any other Pow-based project—create a link to your project’s directory (not the public directory, but the root project directory) in ~/.pow. For more info on using Pow, see the user’s manual.

Yes, you could just open your plain old HTML files in a browser without having Pow serve them, but using Pow lets you avoid addressing your assets (images, JS, CSS) with relative paths. You won’t have to go through your code and change all the relative paths to full paths once you’re ready to turn your templates into production code.

TextExpander

I love TextExpander, and I use it to fill a gap that’s left by generating blank files with no template code in them. For example, I like my default application.coffee file to include the following header:

#      Project Name v1.0
#      (c) 2012 Company Name
#      http://projecturl.com

# Load the application once the DOM is ready using a `jQuery.ready` shortcut.
$ ->

This block turns into a very pretty header when I run Docco to create my documentation, and it sets the application up to work with jQuery. I created a TextExpander fill to generate this header. The fill, which is triggered when I type coffeehead, prompts me to enter the project name, version, company name, and project URL. For more info on how fills work, see this video by the venerable Merlin Mann.

I have a similar fill that creates the header for my CSS files, which looks like this:

/*
      Project Name v1.0
      (c) 2012 Company Name
      http://projecturl.com
*/


/*  Header
--------------------------------------------- */

This one’s triggered when I type csshead. It’s very similar to the CoffeeScript header. Another fill creates CSS section breaks by prompting me for the name of the section when I type csssec:

/*  Section
--------------------------------------------- */

If you have TextExpander and want to try these snippets for yourself, you can download a copy of them here.

Bonus: Docco

Don’t delete the Rakefile when you’re done generating a new project! It provides a task for creating annotated documentation for your CoffeeScript:

$> rake doc

Run that command, and then check the contents of the /docs directory.

Requirements

I’ll be honest; I lost track of all of the software that’s required to make this work. You’ll need Ruby and Rake and Git to get started. To compile the .less files that come with the Twitter Bootstrap project, you’ll need Node.js and NPM. Once you have NPM installed, you’ll need to install the less package. You can also install CoffeeScript and Docco with NPM; Docco also recommends installing Pygments for syntax highlighting. If I missed any other requirements, please let me know in the comments.

    • #git
    • #coffeescript
    • #javascript
    • #css
    • #html
    • #rake
    • #docco
    • #html5boilerplate
    • #twitterbootstrap
  • 3 months ago
  • 12
  • Comments
  • Permalink
  • Share

Standard CoffeeScript Procedure

Here’s a quick one that I’ve really started to like. I’ve taken to setting up new projects with js and coffee directories in the root of the project. Then, I use Jitter to watch the coffee directory for changes. It automatically recompiles the JavaScript files every time I save my changes.

Jitter takes two arguments: your CoffeeScript directory, and your compiled JavaScript directory, like this:

$> jitter coffee js

So, when I start working, I run that command in the root directory of the project, and Jitter goes to work.

You can make it even simpler by setting up a Bash alias. Add this to your .bashrc or .bash_profile:

alias jjitter='jitter coffee js'

Now, when you start working, just enter jjitter, and you’re off to the races.

    • #bash
    • #coffeescript
    • #JavaScript
  • 4 months ago
  • 17
  • Comments
  • Permalink
  • Share

Using dotjs

Chris Wanstrath, one of the co-founders of GitHub, has good ideas. The latest is dotjs.

Using Chris’ own words:

dotjs is a Google Chrome extension that executes JavaScript files in ~/.js based on their filename.

If you navigate to http://www.google.com/, dotjs will execute ~/.js/google.com.js.

I spent some time playing with it today, and oh boy is it fun. I thought I’d share a few of the site hacks I threw together. These are very basic, and you can do a lot more than what these examples offer. Hopefully these snippets will get your imagination working.

google.com.js

The most popular thing I’ve written is an article on how to remove the +1 buttons from your Google search results using AdBlock Plus. Here’s how to do it with dotjs:

$('head').append('<style type="text/css">.esw.eswd { display: none; }</style>');

This won’t remove the +1 buttons from Google+, which is good if you dig Google+.

But why use this instead of setting the CSS of the +1 buttons directly, like this:

$('.esw.eswd').css('display', 'none');

The +1 buttons, like Twitter’s Who to Follow and Trending boxes, are loaded dynamically, so jQuery doesn’t see them. Instead, we have to inject some CSS into the head tag.

twitter.com.js

Ever wanted to get rid of the Who to Follow and Trending boxes? I have. This will do that:

$('head').append('<style type="text/css">.user-rec-inner, .trends-inner, .user-rec-inner + .component-spacer, .trends-inner + .component-spacer { display: none !important; }</style>');

youtube.com.js

Remove the comments? Don’t mind if I do!

$('head').append('<style type="text/css">#watch-discussion { display: none !important; }</style>')

flickr.com.js

I wrote this one for Mike Monteiro. This moves the photo titles back where they belong: above the photos.

var replacement_title = $('.photo-title').clone();
$('.photo-title').remove();
$('#meta').css('margin', '10px 0');
$(replacement_title).insertAfter('#nav');

You can download a copy of all of these .js files at GitHub.

    • #JavaScript
  • 10 months ago
  • 2
  • Comments
  • Permalink
  • Share

CoffeeScript Tutorial Round-Up

CoffeeScript has been making waves. DHH’s announcement that it will ship with Rails 3.1 (enabled by default!) has generated a glut of tutorials and opinions. Love it or hate it, integration with Rails 3.1 will give it enough traction to ensure that it sticks around for a while. With that in mind, here are a handful of resources to get you started:

  • Rocking Out With CoffeeScript
    A reference-style introduction to the language that covers conditionals, loops, and more.
  • How CoffeeScript makes jQuery more fun than ever
    A quick look at jQuery + CoffeeScript.
  • Rails 3.1: Understanding Sprockets and CoffeeScript
    A great follow-up to Peter Cooper’s How to Play with Rails 3.1, CoffeeScript and All That Jazz Right Now
  • Creating TwitterChimes
    See how to build an entire app with CoffeeScript, Node.js, and a few other new-ish technologies.
  • Using CoffeeScript in Rails and even on Heroku
    A very thorough overview from the venerable Dr Nic that’ll be useful for those of you who want to host on Heroku.
  • CoffeeScript Basics
    TeachMeToCode’s introductory screencast.
  • Meet CoffeeScript
    Peepcode’s new introductory screencast ($12).
  • CoffeeScript: Accelerated JavaScript Development
    Not so much a tutorial as it is a book. $36 for Print + eBook, or $18 for the eBook.

I’ve linked to enough text and video here to fill your entire weekend and then some, so if you haven’t learned CoffeeScript by 5/16, um…try harder?

    • #coffeescript
    • #JavaScript
  • 1 year ago
  • 10
  • Comments
  • Permalink
  • Share

Eloquent JavaScript: A Modern Introduction to Programming

I found this today while having a look at Felix Geisendörfer’s Node.js Beginner’s Guide. It’s a free online book for learning JavaScript, it’s thorough, and it’s recommended by a core contributor to Node.js.

    • #javascript
  • 1 year ago
  • 1
  • Comments
  • Permalink
  • Share

Late-Binding With jQuery and AJAX

Suppose you’re working on a site that, among other things, lists files owned by a particular user. Because this is the Internet, and people on the Internet love JavaScript, we’re going to assume this theoretical page uses a bunch of AJAX via jQuery.

The files are displayed in a list, and each file has its own delete button.1 When the user uploads a new file, it appears in the list automatically without refreshing the entire page. This theoretical interface might look something like this:

Whenever a file is uploaded, the upload script returns a snippet of HTML that includes an updated collection of list items that replaces the contents of ul#files.

When the user clicks one of the delete buttons, a confirmation dialog appears, and when the user clicks OK, another script fires that deletes the selected file and returns—wait for it—an updated collection of list items that replaces the contents of ul#files.

Great! We’re done, right? No.

Don’t Forget to Test It

You’ve finished coding the page and asked another dev on the team to have a look at it, kick the tires. He uploads a file. Great! The file list updates properly to show the new file. Then he clicks the new file’s Delete button.

Nothing happens. Two, three, four clicks—nothing.

You refresh the page and click the new file’s Delete button. Presto; it works. What happened here?

Welcome to Late-Binding

The problem—and solution—is really kinda simple, but the mechanics behind it are a bit tricky. Since you’re writing jQuery, the code you wrote for this page probably resides in a document.ready statement that looks something like this:

$(document).ready(function() {
    // Your code here
});

The document.ready statement translates to, “When this page has completely finished loading, execute this code.” So, suppose our theoretical delete buttons are built like this:

$(document).ready(function() {

  .
  .
  .

  $('a.file_delete').click(function(e) {
    e.preventDefault();
    var answer = confirm('Are you sure?')

    if (answer) {

      // A bunch of code

      $.ajax({
        type: 'GET',
        url: 'delete_file.php',
        data: data,
        success: function(html) {
          $('#files').html(html);
        }
      });
    }
  });

});

When the page finishes loading, jQuery wires up—or binds—the delete buttons to this block of code. Then, in effect, jQuery goes blind. It can’t see any changes to the document that take place as the user interacts with the page. So when the user uploads a new file, what jQuery once saw as this:

…it now sees as this:

Because we haven’t told jQuery to pay attention to changes on the page, it’s lost track of the list items that were removed as the result of our Add File script being called. Removed? Yup. Our script includes this line:

$('#files').html(html);

This says to replace the existing HTML inside of ul#files with whatever data is returned by delete_file.php. When this happens, the original list item nodes are deleted from the DOM. jQuery never sees the creation of the new nodes after our script fires, so ul#files is completely empty in the eyes of jQuery.

The question is: how do we tell jQuery to watch the DOM for new snippets of HTML that include more anchor tags with the file_delete class assigned to them?

Change this:

$('a.file_delete').click(function(e) {

to this:

$('a.file_delete').live('click', function(e) {

This tells jQuery to pay attention to changes in the document and, if it encounters an anchor with the class file_delete, bind that anchor to our block of file-deleting code. Binding a page element to a block of code after your page has loaded is known as late binding.

jQuery’s .live method is really handy. You can read more about it in the jQuery developer docs.


  1. I know, “Bad UI designer!” This is just an example; don’t get your undies in a bunch. ↩

    • #javascript
    • #jquery
  • 1 year ago
  • Comments
  • Permalink
  • Share

Learning JavaScript

This week’s primer article will be super-short. There are some things you should know before starting out, so, here goes.

JavaScript != jQuery

JavaScript is a language. jQuery is a library written in JavaScript that makes writing cross-browser-compatible JavaScript easier, especially asynchronous JavaScript functionality (known as AJAX). jQuery is the most popular JavaScript library available, but—strictly speaking—being familiar with jQuery does not mean you know how to write JavaScript. It’s a (very, very) good idea to have some familiarity with the underlying language in addition to learning how to use jQuery.

Most JavaScript Is Poorly Written

Maybe my evidence is anecdotal, but I’ve been using the Web to learn programming languages for about fifteen years. During that time, I’ve come across some really poor examples of code. Bad Ruby, bad PHP, bad C. But by far, some of the worst code examples I’ve found were snippets of JavaScript.

As a novice, you can’t tell the good stuff from the utter crap, which is why I suggest limiting your searches for help and example code to Stack Overflow. There’s still a chance you’ll find some code that isn’t as good as it could be, but the folks there are smart. Most of the JavaScript and jQuery snippets I’ve seen there were trustworthy, and if they weren’t, someone from the community usually posted a refactored version. This is doubly helpful; you get to see how bad code can be made good.

On to the Learning

If you want to get up-to-speed with JavaScript, have a look at these tutorials from Web Monkey:

  • JavaScript Tutorial
  • Advanced JavaScript Tutorial

Once you feel comfortable with JavaScript, move on to jQuery. There’s another great tutorial at Web Monkey that provides a solid introduction to the library.

    • #javascript
    • #jquery
    • #primer
  • 1 year ago
  • Comments
  • Permalink
  • Share

Using jQuery with Rails

Want to spin up a new Rails application, but you don’t want to use Prototype as your default JavaScript library? No worries; this one’s easy.

$> rails new app_name -J

This tells rails to create a new app without the standard Prototype libraries. If you also want to omit TestUnit from your new app, use this:

$> rails new app_name -JT

Next, you’ll want to download a copy of jQuery and place it in your app’s public/javascripts directory. Mikel Lindsaar recommends putting it in a separate jquery directory in your javascripts directory, which makes sense.

Finally, you’ll want to download the Rails jQuery driver (save it to public/javascripts/rails.js) and set up jQuery in the head of your layout files.

<%= javascript_include_tag 'jquery/jquery-1.4.2.min' %>
<%= javascript_include_tag :all, :cache => true %>

As Mikel points out, you’ll want to include jQuery before the :all tag so that it gets loaded before any other scripts that might reference it.

    • #rails
    • #jquery
    • #javascript
  • 1 year ago
  • Comments
  • Permalink
  • Share
Renaissance Nerd is a collection of links and articles cobbled together (and sometimes written) by Jeff Mueller.

Pages

  • About

Elsewhere

  • @jeffmueller on Twitter
  • jeffmueller on Pinboard
  • jeffmueller on github
Clockpunch: Log time. Track Stats. Stay On Budget

I made an iOS app called Clockpunch. It's for tracking your work. Sales go toward making Renaissance Nerd possible.

  • RSS
  • Random
  • Archive
  • Ask me anything
  • Mobile
Powered by Tumblr

Renaissance Nerd is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. Effector Theme by Carlo Franco.