Chomper Stomping jQuery/JavaScript/CSS 3/HTML 5, Java/PHP/Python/ActionScript, Git, Chrome/Firefox Extensions, Wordpress/Game/iPhone App Development and other random techie tidbits I've collected

28Dec/090

TOTW: Etherpad.com

This week's Tool of the Week is Etherpad.com.

What it does:

Allows you to edit a text file collaboratively in real time with others. Each person's changes are highlighted in a unique color. The file gets saved to their server at a unique URL that you can share and reference. You can view past versions of the file using a "Time Slider". It's kind of like Google Wave, but easier to use... There is even a chat feature on the side of the page for off-document conversation that persists from session to session.

When you need it:

  • When walking through or collaborating on some code with another developer
  • When collaborating on a text document (like a list or something)

How to use it:

In case you blinked at the end, I had Firefox and Chrome both open and was editing the same pad from within the two browsers. It kept the edits in sync live between the two browsers. This would have been more apparent had I actually had them both showing, which I should have done, but didn't think about it until just now...

17Dec/090

Exploring jQuery getScript, or “How I created the jQuery getScriptLite plugin”!

I set out to discover how the getScript function in jQuery works today. Here is what I found. This post sort of illustrates just how easy it is to dig into the jQuery source and really learn the library.

The first thing I did is hop over to github and pop open the source for the 1.3.2 release:

http://github.com/jquery/jquery/tree/1.3.2/src

Since getScript() is an AJAX function, I naturally clicked on "ajax.js". On line 109 I found:

Oh wow! It's just a convenience method! It doesn't do anything magical at ALL. It simply calls $.get().

Now, I could have stopped there, but for fun, let's go deeper. On line 93 I found the get() function:

Ok, so get() is really just a convenience method for ajax(), so let's look for that. Line 25, the ajax() function:

Wait, that's not the one! I don't really know how this works, but that can't be the one because it strips out the script tags. I find another one later on on line 170 that goes all the way to line 451. Way down on line 253 it seems to handle the actual script loading:

Aha! Clever. Creates a script tag and sets it's source to the one we specified and then on line 278 appends it to the head of the document, I'm assuming at that point running the script because two lines later it returns out of the function:

So, there you have it! It would almost seem that you could do the same thing by:

In fact, that seems to work just fine. Hrm... Fork me on github and/or get the plugin!

28Aug/092

Finding the number of hex tiles inside of a hex shaped grid…

EDIT: There is a mathematical formula that is much better than the method I illustrate below. It is: 3n^2 - 3n + 1

A huge thanks to Sam Hughes for very patiently helping me out with this formula. He's the best mathematician I know...

Here's the JavaScript code to execute this formula (just change maxTiles to be however wide your hex grid is):

	var maxTiles = 7;	
	var n = Math.ceil((maxTiles - 2) / 2);
	var numberTiles = 3 * Math.pow(n, 2) - 3 * n + 1;

Below is the original post:


This is kind of like finding the area of a hex grid, except that for some reason none of the formulas I found for doing that would work. Also, finding the area of a triangle made of hex grids won't work with the normal triangle area formula either.

What I am illustrating here is how to find out how many hex tiles are inside of a hex shaped grid of hex tiles.

Here is a picture of the grid:

What you have to do is:

1. Take the half the width of the hex grid rounded down. So, if the hex grid is 7 wide, you take half of seven, 3.5, and round it down to 3. This can also be called "flooring" the number.
2. Take that number and use it to seed a floor loop, which counts down from that number, adding the new number to a grand total each time.
3. Multiply that grand total by 7 and add one for the middle tile (which never got counted).

Here is the code:

	var triangleTotal = 0;
	for(var spaces = Math.ceil((maxTiles-1)/2); spaces > 0; spaces--){
		triangleTotal += spaces;
	}
	var triangles = triangleTotal * 6;
	var numberTiles = triangles + 1;
	return numberTiles;

You'll notice that I took the total minus 1 divided by 2 and "ceil"ed it, instead of taking the total divided by two and "floor"ing it. It doesn't matter which you do...

Here's a visualization proving this out:

I only took one math class in college, otherwise this would have probably been very obvious to me as it may seem to you. There is probably even a really fancy easy little formula for this, but I don't know it and couldn't find it...

Here's a page where you can test this formula out in action. Note that a hex is always going to be an odd number of hexes wide, so if you enter an even number and get a funny shaped hex, this formula isn't going to work...

27Aug/092

JavaScript Haxagon Game Board with Hexagon tiles

I'm working on a JavaScript version of The Settlers of Catan. The first problem I decided to tackle was constructing (visually and array-structure wise) the game board using nothing but loops (didn't want to hard code it).

This ended up being much more difficult than I thought it would be.

I am going to split this up into two parts:

1. Setting up the game board visually
2. Setting up the array structure

Creating a Hexagonal game board with hexagonal spaces in JavaScript with for loops:

For this to work properly, you must have an even number of columns and rows. I chose seven since that is what makes up the Settlers of Catan game-board.

You have to split the building of the board into three stages:

1. The expanding stage
2. The apex or middle of the board
3. The contracting stage

I placed everything in one large for loop that counted off the "rows".

I figured out that while the rows are less than half the max rows divided by two (and rounded down) the board would be contracting. The number of tiles you would start with would be equal to the maximum number of tiles divided by two, rounded up, plus the current row number.

Once the number of rows equals exactly half the number of maximum tiles (rounded down) you are on the middle row. In this case the number of tiles is the max number of tiles, no math required.

Otherwise, you are in the contracting stage and the number of tiles you need is equal to the maximum number of tiles, minus the current row, minus half of the maximum rounded down.

Sound complicated? That's because it is. This took me about 30 minutes to get straight in my head after studying the game-board shape, tiles, and making several diagrams and sudo-coding and then writing the actual code and fixing bugs (and deciding if I had to round up or down at certain places).

Here is the actual code:

<html>
<head>
<style>
img{
	margin-top: -18px;
}
#board{
	padding: 50px 25px;
	background-color: #000;
}
</style>
</head>
<body>
<div id="board">error loading</div>
</body>
<script>
function boardSetup(){
	var max = 7;
	var html = "";

	for(var row = 0; row < max; row++){
		if(row < Math.floor(max/2)){
			//place spacer tiles
			for(var space = 0; space < (Math.floor(max/2) - row); space++){
				html += '<img src="spacerTile.png" />';
			}

			//place game tiles
			for(var cols = 0; cols < (Math.ceil(max/2) + row); cols++){
				html += '<img src="tile.png" />';
			}
			html += "<br />";
		}else if(row == Math.floor(max/2)){
			for(var cols = 0; cols < max; cols++){
				html += '<img src="tile.png" />';
			}
			html += "<br />";
		}else{
			for(var space = 0; space < (row - Math.floor(max/2)); space++){
				html += '<img src="spacerTile.png" />';
			}
			for(var cols = 0; cols < (max - (row - Math.floor(max/2))); cols++){
				html += '<img src="tile.png" />';
			}
			html += "<br />";
		}
	}

	document.getElementById("board").innerHTML = html;
}

boardSetup();
</script>
</html>

Here are the images that go with it:

Here is the tile:tile
Here is the spacer. This one is completely invisible: start->spacerTile<-end

Here is the code running on my site.

6Aug/0914

iPhone 0S 3.0.1 not supported for development with Xcode SDK 3.0

I recently updated my iPhone from iPhone OS Version 3.0 (7A341) to iPhone OS Version 3.0.1 (7A400). When I plugged it into my Mac, I was informed that:

The version of iPhone OS on "Christopher's iPhone" does not match any of the versions of iPhone OS supported for development with this copy of Xcode. Please restore the device to a version of the OS listed below. If necessary, the latest version of Xcode is available here.

Gee... Thanks... I did a little Googling and found that after a recent security update to the iPhone OS Apple, you could no longer build/install development apps on the iPhone. Apparently Apple posted an "advisory" (in PDF format for some reason) outlining a fix for this.

Here is the fix in plain text instead of PDF (why they put this in a PDF is beyond me...):

iPhone OS 3.0.1 Advisory
iPhone OS 3.0 SDK and iPhone OS 3.0.1 software release for
Mac OS X v10.5.7
To continue development with iPhone SDK 3.0 on your iPhone, iPhone 3G and
iPhone 3GS running iPhone OS 3.0.1 will need to perform the following:
1. Log into your Mac with an Admin account and launch the Terminal application
(/Applications/Utilities)
2. Copy and paste the following line into Terminal:
ln -s /Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.0\ \(7A341\) /Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.0.1
Note: If you installed iPhone SDK 3.0 somewhere other than the default /Developer
location, replace the "/Developer" directory as appropriate.
© 2009 Apple Inc. All rights reserved. Xcode, Apple, the Apple logo, Mac, Mac OS, and Macintosh are
trademarks of Apple Inc., registered in the U.S. and other countries.

For some reason, the wonderful person who created the PDF put a hard break after the "/" right before the word "Developer". So if you actually do copy and paste the line into the terminal as they instruct, it doesn't work. However, if you copy and paste the plain text version on this page, it SHOULD work (no guarantees). If you want to copy and paste from the PDF, you will have to type everything following that "/" by hand, THEN it will work... Thanks Apple!

Here is a link to the advisory.

***UPDATE:

Several people have had to use:

ln -s /Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.0 /Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.0.1


If you found this post helpful, it was supported in part by the amazon links around the site. If you're going to buy a book anyways, why not help support this blog's author by clicking one of the links on this site to do it? If you are looking for a book on iPhone development, this one is amazing: Beginning iPhone 3 Development: Exploring the iPhone SDK

1Jun/090

Print Media Alternate Style Sheet (CSS)


If you don't want to create an entirely new alternate style-sheet just for print media, there is an easier way to do it.

I had a small adjustment I needed to make for printing a page on my site, and rather than creating an entirely new (duplicate) alternate style-sheet just for print media, I discovered a neat little CSS method you could use to put the print style right in with the main style.

It's the @media print CSS method.

My original CSS code was as follows:

#dragLayer {
height:255px;
left:72px;
overflow:hidden;
position:absolute;
top:0px;
width:255px;
z-index:100;
}

For some reason the "Drag Layer" div was appearing over-top the image contained in a sub-div. I'm using scriptaculous to display a blown up version of an image when you hover over a smaller version of the image. But when you print, the smaller version of the image doesn't show up. Making the dragLayer div display equal to none didn't work for some reason. So instead I defined a print stylesheet with the dragLayer div's height and width equal to 0. I didn't want to have to make an entirely new duplicate stylesheet just for this one little CSS change for printing, so after some exploring I found the @media print css directive. Here is the style I ended up with:

#dragLayer {
height:255px;
left:72px;
overflow:hidden;
position:absolute;
top:0px;
width:255px;
z-index:100;
}

@media print{
#dragLayer{
height: 0px;
width: 0px;
}
}

This little trick was mentioned in passing in page 210 of Elizabeth Castro's
HTML, XHTML, and CSS, Sixth Edition (Visual Quickstart Guide), but Elizabeth claims it isn't as widely supported or well known as the other standard methods of doing this. In all of my testing so far, however, it looks like it works in all of the newest versions of three of the major browsers (FF, IE & Chrome).


20May/0812

How to ORDER BY before GROUP BY with MySQL

I've got a table that tracks inventory at multiple vendors for multiple products by timestamp. I want to only select the most recent inventory count per vendor by product.

One way to do this is with a bunch of while loops and hitting the DB over and over, or selecting a crap load of data and just dropping out everything but the most recent inventory count manually. Both of these are viable solutions with a lot of overhead, but what I really want is just a silver bullet SQL statement that does this for me. I think I have it.

What I initially envisioned was:

SELECT *
FROM INVENTORY
ORDER BY vendors_no,
timestamp DESC
GROUP BY vendors_no,
product_no

However, if you are familiar with MySQL, you will know that you cannot put ORDER BY before GROUP BY. You have to GROUP BY and then ORDER BY.

It appears that the way that GROUP BY works is that it takes the first row of each "group" and just drops the rest. So whichever row happens to be first in the DB when the SQL is executing will get grabbed and the rest will get dropped. If I had wanted to get the first inventory count for each vendor/product, this would have been ok, since those would have been the first row, but it's going to be the last row each time. So what to do? If only I could flip the whole table on it's head or something...

Actually, I kind of can! This is what I came up with:

SELECT *
FROM(
SELECT *
FROM INVENTORY
ORDER BY vendors_no,
timestamp DESC
) as inv
GROUP BY vendors_no,
product_no

If I understand GROUP BY correctly and ORDER BY correctly (which I very well may not) the sub-query will first basically create a temporary table with the results in reverse timestamp order. Then when GROUP BY is going through and finding the first vendor_no and dropping the rest it will be keeping the most recent one.

If anyone knows any reason why this is stupid or wrong, please let me know. It's the best solution I've been able to find so far.

***UPDATED: In response to Brian's suggestion***

Dang. I really wanted that to work, but it didn't.

Here is the original SQL:

Here is the SQL you suggested:

Did I do something wrong?

Here is the total data being queried:

Thanks for the suggestion!

19Mar/080

Stylesheets and Alternate Stylesheets, how including external CSS works

It really helps to read the documentation. Way back when I started designing websites using external stylsheets, I found a little trick. If you had IE specific styles and Firefox specific styles, you could extract them both out, and include them both like this:

<link href="ffStyles.css" rel="stylesheet" type="text/css" title="Firefox Styles" />

<link href="ieStyles.css" rel="stylesheet" type="text/css" title="IE Styles" />

Since you are (in this case) telling the browser that you have two styles, and both are different (you used a title attribute), but both should be default (you used the "stylesheet" parameter for the "rel" attribute) the browser doesn't know what to do. You've told it only to use one, but that both are the default, and thus, have contradicted yourself.

At this point, IE and FF both make very different (but helpfully so) decisions. I'm betting that IE said, "well, these are cascading, so in cascades you always take whatever the last thing is and use that" and therefore IE used the last style as the default and ignored the first. Firefox either said "IE uses the last one, so I'll use the first one so people can use the trick Chris is talking about above" or they said "Ok, looking for stylesheet... found it! Use it! Oh, another one... um, we don't need anymore because we already have one, so ignore it" either way it doesn't really matter, because the point is, it works out nicely for the developer.

I always thought this was a "bug" that I was exploiting, and that my dual stylesheet was an exploit/hack. Then I read the documentation today for the first time and learned how stylesheets are supposed to work and be included. The major thing I found out was that the title attribute is purely optional, and serves a double purpose:

It clearly states in the documentation not to put a title attribute if you want it to be “persistent” (universal) but if you want it to be “preferred” (default) to set the title attribute and set the rel type as "stylesheet". It doesn’t say anything about being able to have two stylesheets both with the rel attribute set to “stylesheet", but it does make it appear as if you are not supposed to have more than one with the rel type of “stylesheet” (at least that’s what I’m inferring from the fact that they are giving you a way to make “alternate” stylesheets). This actually makes sense, because if they give you a way to have “preferred” and “alternate” stylesheets, why would you make two preferred? What would that even mean? I’m guessing the way they intended was something like this:

<link href=”basicStuff.css” rel=”stylesheet” type=”text/css” />

<link href=”blueStuff.css” rel=”stylesheet” type=”text/css” title=”blue theme” />

<link href=”redStuff.css” rel=”alternate stylesheet” type=”text/css” title=”red theme” />

This way, all of the stuff that is universal to both themes just goes in without a title tag, because the only purpose of the title tag is so you can switch between them, and why would you want to switch the universal stuff (you wouldn’t)? So, by putting a title, you are implying that the user should be able to see and choose between your titled styles, and by putting “stylesheet” instead of “alternate stylesheet” you are stating that “this one is the one you should see by default”. So in this example, the blueStuff.css style would be used by default (for both IE and FF) and the redStuff.css style would be an available alternate.