Skip to content

Social Media Badges in an OmniGraffle Stencil

September 29, 2011

When mocking up website designs, it’s empowering to work with graphics that do not have a finished look about them. It frees you up to experiment, and risk “getting it wrong”. I use apirak’s “Web Sketch Interface v2” OmniGraffle stencil from Graffletopia to plan my website look and feel. I’ve recently been trying to give back, by offering common elements in a similar style. Here’s my stencil for social media badges. It’s available for download from Graffletopia. It’s a short list, but one I’ll probably be expanding upon in the near future.

Preview of Web Sketch Social Media Badges stencil

Social Media badges in a "sketch" style, for mocking up web UX designs. Includes: Twitter, Facebook, StumbleUpon, Delicious, Digg, Reddit, Linkedin, MySpace, FriendFeed, RSS, Flickr, Technorati, YouTube, and Bebo.

CSS3 Compliant Cursors in an OmniGraffle Stencil

July 10, 2011

I use apirak’s “Web Sketch Interface v2” OmniGraffle stencil from Graffletopia to plan my website designs. It is my go-to stencil. However, I recently needed a group of CSS3 compliant cursors (like pointer, and crosshair), and couldn’t find anything for OmniGraffle that didn’t have a white background, or just not match my need. So, I spent a little time this Sunday whipping up just what I needed. It’s available for download from Graffletopia. I hope others find it useful.

Preview image of Web Sketch Cursors available from Graffletopia

CSS3 Compliant cursors in a "sketch" style, for mocking up web UX designs. Includes: default, crosshair, pointer, move, text, wait, help, progress, not allowed, vertical text, and several resize arrows.

Students, and the Courses They Never Started

April 27, 2011

I struggled with this SQL problem a bit longer than it probably should have taken. Hopefully this post prevents another from doing the same.

The table structure I was working with contained a ‘student-table’, ‘course-table’, and a ‘merge-table-with-extra-data’. A pretty basic many-to-many relationship between Students and Courses, along with a date for when each relationship started.


CREATE TABLE `Students` (
`student_id` int(11) NOT NULL AUTO_INCREMENT,
`student_name` varchar(128) DEFAULT NULL,
PRIMARY KEY (`student_id `),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `StudentCourses` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) DEFAULT NULL,
`course_id` int(11) DEFAULT NULL,
`date_started` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `Courses` (
`course_id` int(11) NOT NULL AUTO_INCREMENT,
`lesson_name` varchar(128) DEFAULT NULL,
PRIMARY KEY (`course_id `),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

What I needed from this was a list of students, and the courses they did not start between two given dates. This was a seemingly easy problem, until I actually tried to accomplish the task.

student_name lesson_name
Doug Burchard Bull Frog Mating Rituals
Doug Burchard Worm Tunneling and Moles
John Green Nest Building for Birds
Susan Archer Swimming with Sharks
Travis Dodge Swimming with Sharks

The solution: First, I created a sub-select of every possible student/course combination; then I created a second sub-select of every existing row in StudentCourses created between the two given dates; finally, I left outer joined the first sub-select to the second by both the student_id and course_id, and retained every row where this join had failed.


SELECT m.`student_name`, m.`lesson_name`

FROM (SELECT s.`student_id`, s.`student_name`, c.`course_id, c.`lesson_name`
FROM `Courses` AS c
LEFT JOIN `Students` AS s ON 1 = 1) AS m

LEFT OUTER JOIN (SELECT `id`, `course_id`, `student_id`
FROM `StudentCourses`
WHERE `date_started `>'2010-7-1 AND `date_started `<'2010-8-1') AS sc ON m.`course_id` = sc.`course_id` AND m.`student_id` = sc.`student_id`

WHERE sc.`id` IS NULL

OS Upgrade Haunted by Ghost-account?

October 23, 2009
tags:

I just got done wiping my drive, loading Snow Leopard, and restoring my files from a cloned backup. Almost everything worked as expected. The Lasso-user refused to be restored — it never finished calculating the directory size, and I had to deselect it to continue the restoration process. Once I was back up and running, I reinstalled iTools9, Tenon’s PHP and MySQL add-ons, and Lasso 8.5.6. I had to copy and paste from the old virtual host config file to the new one, but that brought everything up except MySQL.

As hard as I tried, I couldn’t get the MySQL Server to launch. I messed around with it for hours. I read log files, re-re-installed applications. I re-restarted the machine. I manually launched and re-launched executables. Nothing seemed to work. The only other symptom remotely associated was that in the iTools9 Admin site, the System Status pane took an enormous amount of time to load, sometimes never loading.

Finally I thought to just wipe everything associated with webserving, and re-install again. I thought I’d start by removing the extra users on the system. So, I swapped over to my admin-account, brought up System Preferences, selected the MySQL-user, and clicked the delete key. Something strange happened, the MySQL-user didn’t dissapear, but it did change names from “MySQL” to “MySQL Server”.

I thought that perhaps there were two MySQL-user accounts, and one had been masking the other. So before I did anything else, I jumped back to my client-account, brought up the iTools Admin site, and opened the System Status pane. It opened up immediately — no long delay like before. Then I clicked the “restart” button for MySQL Server, and MySQL started right up.

I don’t know if my assumption, of there being two MySQL-user accounts, is exactly correct. But, everything’s working now, and I’m just hoping this helps someone else. When I upgrade the operating system in the future, I’ll not restore the MySQL-user in the first place, instead just let the iTools instal create a new user, and manually import the data-files from the cloned backup.

Is CSS Enabled?

October 1, 2009

I’ve seen this question posed many times on different forums.

How can one tell if CSS is enabled/disabled using Javascript?

Well, there is a method of doing this, sort of. If CSS is disabled, an @import directive will never get followed. Simply import a CSS file with a un-noticeable styling to an element. Then, use Javascript (I like the jQuery framework) to test whether this style is true of false. For example, use this structure to style a <div>-container that’s on every page to have a white background-color. Then test for this later.

Example CSS (csscheck.css)

#body {
background-color:white;
}

Example HTML

<!DOCTYPE HTML>
<html lang="en-us">
<head>
<style type="text/css"> @import "csscheck.css" </style>
</head>
<body>
<div id="page">
... your content here ...
</div>
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
<!--
$(document).ready(function(){
var bodyBackground = $('#body').css("background-color");
if (bodyBackground == "rgb(255, 255, 255)") {
... script steps if CSS is enabled ...
} else {
... script steps if CSS is disabled ...
}
});
//-->
</script>
</body>
</html>

The downsides of this method are that older browsers — for the most part v4 browsers and below — don’t understand the @import directive in the first place, but do understand some CSS. And, of course, this adds just one more file to be downloaded, no matter how small. So, code defensively, and test on several browsers, including older versions.

Focus group disses ThickBox

September 30, 2009

I’ve used the ThickBox jQuery-plugin on several projects now. It’s easy to integrate, and flexible in it uses. For example, the first time I used it was to provide a FCKEditor-window that wouldn’t fit in the limited space of that website’s form-area. I definitely recommend ThickBox, if you need a lighbox-effect.

When MyLocalPark.com launched earlier this week, each park-page used ThickBox to display a slideshow of that park’s photos. This feature went together easily, and was something I’ve built in the past for clients. However, my focus-group didn’t appreciate the feature quite as much as I did. They got confused when they clicked into the lightbox-effect, and naturally used their browser’s back-button to try to get back to the park-screen. Since ThickBox doesn’t change the actual location (meaning the URL), only the appearance of the screen, the focus-group’s respective back-buttons returned them to the browse-page, found-parks-page, or home-page, depending on where they were before they navigated to the park-page.

To fix this problem I replaced the lightbox-effect with a seperate purpose-built page for scrolling through a park’s photos. While I could have easily told myself the focus-group “just didn’t understand technology” (actually, I did tell myself this for a couple of hours), in the end I knew I had to trust what they were telling me. The final slideshow-page took it’s inspiration from Flickr, and who knows more than them about displaying photo-sets on the web?

Debugging Google Maps with an Offset Center

September 29, 2009

MyLocalPark.com has an embedded Google Map showing each park’s location. On the park-screen, this embedded map is hidden until the visitor clicks on a tab. To eliminate any momentary display of this map during the drawing of the page, the entire DOM element is created with javascript (jQuery).

A strange thing happened when I first built this functionality. When the map was displayed through the visitor clicking the tab, the map’s center was offset (south and east), and the south-most and east-most map-tiles were blank. After significant debugging, I found this only happened when the map was drawn within a hidden element. To solve the problem, I just adjusted the order of the javascript so that Google’s initialization code occurred immediately before the code that hides the container.

Incidentally, since embedded Google Maps don’t work so well with javascript disabled, the embedded map’s dynamically created container/placeholder, replaces a <noscript>…</noscript> container that holds a link to the full map on maps.google.com. This way, if no script runs, the visitor still has access to the map, and the page continues to be readable. And, if javascript is enabled, the noscript-link does not display momentarily, or flicker, before the javascript completes.

Generating a Universal Unique Identifier

September 28, 2009
tags:

A Universally Unique Identifier (UUID) is a formatted string used to identify something with reasonable confidence that the identifier will never be unintentionally repeated by anyone for anything else. This is useful for example in creating table-entries with unique IDs, which you might need to merge with another table and not have conflicting ID’s or need to generate new ID’s.

B_UUID is the second installment in my B-Suite of custom types, and is a pure-Lasso method of generating a version 4 (random) Universally Unique Identifier (UUID). The usage is very simple, you simply call the prototype, and the call is replaced by a new UUID.

B_UUID

=> 12c9ca38-ef23-42f2-951b-f6dad1ced320

For the most up-to-date version of this code, I recommend checking the source out from my Google Code account linked to above. As an alternate, you can also view/copy the source from TagSwap.net.

Other methods of creating a UUID in Lasso

  1. On most operating systems, using Jason Huck’s Shell tag, or the built in OS_Process tag, the `uuidgen` command can be used to return a version 4 UUID.
  2. Steffan Cline has recently posted a cross-platform LJAPI module, GetUUID, that is most likely faster than any solution written in Lasso Script, or certainly any solution that needs to open a shell.
  3. My understanding is that when LassoSoft releases Lasso 9 (most likely October, 2009) that the built in Lasso_UniqueID will generate a version 4 UUID, similar to B_UUID.

Making a page too dynamic

September 25, 2009

MyLocalPark.com has a feature where a visitor can choose to jump to a randomly selected park. The way this initially worked was the “random”-link simply selected a park at random, and build the park-screen. The “random”-link’s URL looked like this:

http://www.mylocalpark.com/random

The problem with this design was that if the visitor navigated to another screen, and then used their browser’s back-button, they were presented with an entirely new park each time they returned. This effectively broke the browser’s back-button, and my focus group displayed quite a bit of confusion (yes I did, and continue to, use a focus group. They’re a small group of friends and family who agreed to help unpaid, and to whom I am very grateful).

In any case, I knew we had to change this functionality, and did so first thing. The change was simple, the code now does an HTTP-redirect to the actual park-screen of the randomly selected park. That URL looks like something this:

http://www.mylocalpark.com/park/spiritbrook+neighborhood+park+redmond

I did worry over this change before implementation. Redirects, especially temporary redirects, are considered bad form by some pundits of “good web design”. But I finally decided that this was a proper use of the functionality.

My focus group appreciated the change. They’re happy, I’m happy, and now I just hope the general public will be happy.

Celebrating a Launch: MyLocalPark.com

September 24, 2009

I’ve been quiet recently, I know. I spent the last 4-weeks working on a personal project; a small tech. start-up named MyLocalPark.com. As businesses go, it’s not huge. But, I believe it has some potential for traffic.

The genesis of the website was a morning in which my wife asked me to find a park to take our two-year-old to that evening. On her way out the door to work, she said she wanted the park to have a great play area, and not be one he had been to before. This should have been easy to find on the web, but surprisingly wasn’t. The easiest to find content, off of the various city-websites local to us, showed a single small picture of each park’s sign, and an anemic blurb of little help. If you dug enough, you could find user reviews, which are always helpful, but they were on third-party websites not specializing in parks, and had no pictures.

My wife and I actually love the Amazon shopping experience. Mostly it’s the user reviews, unbiased reviews of any product from a multitude of sources. So the idea behind MyLocalPark.com is to pair the Amazon-like user experience, with a catalog of parks. Of course, Amazon isn’t the only website out their with a great user experience, so they’re not our sole inspiration.

Being a web developer, of course I’m using this project to try out some new ideas of my own. I’ll be blogging about these experiences as I encounter them, and hopefully you’ll benefit from this as much as I’m sure I will.

In any case, MyLocalPark.com was just launched yesterday as a beta. Please check it out. I’ve already made some changes to the UX since launch (more about that is another post). As developers, you might be especially interested in the Development Roadmap.

Follow

Get every new post delivered to your Inbox.