Why is date() Returning 12/31/1969?

 In PHP, a good sign that something is wrong with your date data or logic is when you start seeing dates displayed as “12/31/1969” (or however you specified the format). Unfortunately, there’s not a one-fits-all solution to that, since it could be caused by any number of things, but ultimately, the root of the matter is that you’re passing an invalid timestamp into date(). So while I can’t answer what’s wrong in your specific code, I can tell you why it is happening.

All about date()

In PHP, the date function takes in a Unix timestamp, then formats it according to the format mask you provide. To display today’s date, you only need to provide a mask, no timestamp, as the timestamp argument will default to the value of time() (as in, right that moment).

In code:

<?php echo date("m/d/Y"); ?>

Which evaluated as [date format="m/d/Y"] when this page loaded.

But when you want to display a date in the past or future, you have to provide a timestamp. A Unix timestamp to be exact.

The Unix timestamp

The Unix timestamp is defined in seconds since the Unix Epoch, otherwise known as January 1, 1970 at 0:00:00 UTC.

In PHP, you can retrieve the timestamp using the time function. In code:

<?php echo time() ?>

Which evaluated as [time] when this page loaded.

In order to get a timestamp value from a time string, such as "2009-09-09", you can use strtotime(), which will try to parse many different types of date strings. Learn more about the strtotime function at in the PHP manual. So if I wanted to use PHP to format that date as something different, say to insert into a MySQL database, I would use code that looks something like:

<?php $date = date("Y-m-d H:i:s",strtotime("09/09/2009")); ?>

Which sets date equal to "2009-09-09 00:00:00".

But when you pass a string to strtotime() that the function can’t parse, or try passing a date string directly to date() instead of a timestamp, date() can’t do anything with the invalid value.

Demystifying 12/31/1969 (or 1/1/1970 for Eastern Hemisphere folk)

Since the Unix timestamp is based off the Unix Epoch, an invalid timestamp defaults to to the Epoch (Thu, 01 Jan 1970 00:00:00 +0000).

But, date() displays the formatted time taking into account the timezone of the server or a timezone set with date_default_timezone_set(), so if your timezone is set to something like America/New_York (-0500), the date will be adjusted, resulting in a time that falls during 31 Dec 1969.

So if your server or script timezone is set to a timezone in the Western Hemisphere, any invalid timestamps will end up displayed as some incarnation of 31 Dec 1969. Likewise, in the Eastern Hemisphere, the date falls on or after the Epoch, resulting in a returned value of 1 Jan 1970.

Like Y2K except worse…

The concept of the Unix Epoch as the basis for time is causing some issues as we get deeper into the new millennium. For 32-bit systems, such as this server and hundreds of thousands (likely millions) of other computerized devices out there, time is finite. The systems will not be able to handle the large integer required to store the date based on the Epoch. When Tue, 19 Jan 2038 03:14:07 UTC rolls around, timestamps will rollover—to a value that equates to Fri, 13 Dec 1901 20:45:54 GMT.

As much as I’d like to travel back in time and see the last few days of Queen Victoria’s reign (oh the fashion!), that rollover will likely bring software systems crashing down. In fact, some systems have already started showing issues if they deal with dates farther than 27 years in the future. Luckily, electronics have been on a steady move toward 64-bit systems that can handle dates up to over 200 billion years in the future, but it’s not unlikely that some 32-bit systems will still be in use when 2038 rolls around even if their manufacture has slowed (or likely stopped).

If you’re trying to pass a perfectly valid date that falls before 13 Dec 1901 or later than 19 Jan 2038 to your PHP script, chances are you’ll see this Epoch error, because the server can’t handle that timestamp.

What’s your favorite 12/31/1969 story? Are you worried about the year 2038?

The Many Faces of the Hyperlink

The World Wide Web is built on links. It thrives because links are everywhere. There are links to the various pages on individual sites. There are links from one site to another. There are links in e-mails to websites. There are links in PDFs and documents and presentations to Web pages. Chances are, you used a link to get to this article. Yet, when it comes to setting up a website, styling and consideration of links is often overlooked. Or worse, specific choices for links are made that end up hurting the usability and interaction of your website.

Link states and their selectors

A link isn’t just an element with one look. It has five different states that can be styled with CSS (and to some degree basic HTML, but you should be separating your styling from your content). Here are the different link states and their associated CSS selectors.

a:link
The link state is the basic state for a link. It’s the blue, underlined text default. A link that hasn’t had and isn’t currently having any action on it should look like this.
a:hover
The hover state is what happens when you move your mouse over a link. Typically, this involves a change in color or decoration. The mouse cursor also changes.
a:focus
Perhaps the most often overlooked state, the focus state is to keyboard navigability what the hover state is to mouse users. When a link is focused on using the keyboard, or after being clicked, it will use the definitions of this state to style it. Default styling generally puts a dotted outline around the element.

You can change the color, style and width of dotted outline (or remove it altogether, although that’s not recommended) in CSS with the outline property (ex. outline: #f00 solid thick;). In newer browsers, other elements can have outlines as well (allowing for double borders), although IE will only display an outline on links only.

a:active
The active state controls how the link appears right after being clicked (while the action is taking place, such as requesting a new page). This gives feedback to the user that their click was registered by the browser, and that something is happening, even if it isn’t readily apparent. The default for this is typically a red text color.
a:visited
If a user has viewed the destination page, the link is considered visited. This is important feedback for the user so that they can know which pages on your or external sites they’ve already seen, thus not needing to click on the link. Default styling of visited links usually colors the link an eggplant or dark purple color.

Each one of these selectors should have a different style. Why? It’s all about usability.

Usability

The Internet as we know it—that is, the one available to the public—was born right around 1992. That was 18 years ago. (Think about it, the majority of students in this years incoming college freshman class were born that same year.) In that time, visitors have come to expect certain things on the Web. For instance, what is the first thing that comes to mind when you see blue, underlined text? You said “a link,” didn’t you. Blue, underlined text has become synonymous with a hyperlink. People see it, instantly recognize “ooh, a link!”, then click on it if they think it looks interesting to them. They die a little inside if it doesn’t do anything. They rejoice if it takes them to another page. That is usability.

Usability: the ease with which a visitor can accomplish basic tasks on your site. Navigation is the most basic task on the web, after reading content.

If you’re only willing to put a minimum amount of consideration into link styling in your design or development, the best thing you can do is dont do anything to the browser defaults. Ok, so maybe those colors would be a little difficult to read on say, a black background, but at least users would understand that they’re links.

Users need to know four basic things:

  1. Specific text is actionable (that is, it is a link)
  2. They are hovering or focusing on it (taking action will do something and they’re clicking on what they intend to)
  3. Something is happening once they’ve clicked on it
  4. Whether they’ve already seen the destination

If your link looks like plain text, no one is going to try to click on it. They don’t have any cues to know that they can take action.

If your link doesn’t change when the visitor is hovering or focusing (via keyboard), they can’t be sure that when they click (or hit enter) something is going to happen. What if they do click but cause something else to happen? That’s bad usability. These two states (hover and focus) are perhaps the only two that I can consider ok to have the exact same styling. Both states indicate that pressing a button (on the mouse or keyboard) will activate the link. If you remove the default outline for the focus state, make sure to do something else that makes it very obvious to a keyboard user that the link is being focused on. Some browsers, like older versions of Opera don’t do anything with the focus state, and others, like IE6, end up meshing focus and active together, so having slight differences between hover and focus might be best for browsers that get confused.

If nothing immediately happens when a user clicks, they might think they missed the link or it is broken. They need feedback to know something is happening in the background, especially if it takes a noticeable amount of time to request the new page.

If they’ve seen a page on the site already, they might not want to visit it again right now. Or, if they’re clicking on various links to read after they’ve finished scanning your content, they might want to know if two links go to the same location. If your visited links look exactly the same as unvisited links, users have no indication of this. Give them some.

Consistency

I’m sure plenty of Web designers are cursing at me right now about stifling their creativity, saying “that color scheme looks like total dog-poo with my design.” And I totally understand that sentiment. You can style your links differently than the browser defaults. I do it. But if you do, at least keep it consistent.

If links on your website are say, bold orange text with no underline, people will probably pick up on the fact that bold orange text with no underline are the links on your site. But if you also use bold orange text for some other type of emphasis, people will be confused when they try to click and nothing happens. Or if another link is suddenly italic red text with an underline, they might think they’ve visited the link, or it’s not a link, or who knows what. It’s unlikely that they’ll click on it. Consistency is key. If you want your users to memorize a new paradigm, make sure you always use your new paradigm.

And please, for the sake of all things holy and unholy, don’t use blue, underlined text unless it is a link. (Or if you are a sadistic developer who takes pleasure in frustrating and confusing your users.)

Exceptions to the rule

There are always exceptions to the rule. The major one here has to do with in-site navigation. Obvious site navigation, like menus and footer links can be styled differently than normal hyperlinks. If users expected your navigation to be blue underlined text, the Internet would be a far more homogeneous place, and that would be boring. When you have obvious menus, your users are going to understand that those are links to other pages in your site. But when you have links within your content, they need to know immediately that they are looking at a link.

A side rule to this: don’t link to external sites from your site navigation without clear indication of what is happening. That is really jarring, and a good way to get people away from your website so that they don’t come back. Site nav links should almost never open in a new page, either.

What link styling strategies have you found work best for you?

The TITLE element and jQuery’s text() function

You’re doing it wrong. In a day of zero fun, a coworker and I ended up tasked with debugging a jQuery-based script that seemed to be perfectly fine, except of course, the part where it wasn’t working as expected in IE. After some tracing, it turns out the issue had everything to do with one line of code not returning a value: $("title").text();. To translate, the author of the code had been trying to retrieve the text of the title element using jQuery’s text function. But, turns out that doesn’t work in IE.

The solution

If you want to retrieve the value of the page title, use document.title. If you want to set the value of the page title—the title displayed at the top of the browser—use document.title.

It doesn’t matter if you’re working with straight JavaScript or a library like jQuery, the correct way to interact with the page title is through document.title.

Here’s a full code example:

var foo = document.title;
alert("The title was "+foo);
// on this site, the above alert would read
// "The title was The TITLE element and jQuery’s text() function"
document.title = "Now it’s been changed.";
alert(document.title);
// this alert = "Now it’s been changed"
// the display at the top of the browser changes too

The explanation

Don’t worry, I’m not going to leave you high and dry without explaining why the original approach didn’t work.

The problem exists in IE because IE doesn’t consider the title element to have child nodes. By W3C specs, the title element contains one, and only one child node: a text node. It can not have any child elements. Just the one text node.  But according to IE, that text exists in some strange nebulous state outside of a normal text node. Here’s a code example.

var titles = document.getElementsByTagName("title");
var kids = titles[0].childNodes;
alert(kids.length);

If you run that code in IE, the alert will be 0. In FireFox, Chrome, Safari, Opera, etc, it will return 1, the expected amount.

Breaking down jQuery.text()

So, the reason $("title").text() doesn’t work in IE is because of jQuery.text()’s reliance on children nodes. Let’s take a look at the function (jQuery version 1.4.2, line 3418):

function getText( elems ) {
	var ret = "", elem;
	for ( var i = 0; elems[i]; i++ ) {
		elem = elems[i];
		// Get the text from text nodes and CDATA nodes
		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
			ret += elem.nodeValue;
		// Traverse everything else, except comment nodes
		} else if ( elem.nodeType !== 8 ) {
			ret += getText( elem.childNodes );
		}
	}
	return ret;
}

A quick translation of the code is as follows. The first line of the function sets up a variable ret as an empty string. This variable is the return variable for the function. Then we jump into a loop that goes through each object in the array that was passed in (remember, $("title") will return an array with a single element). For each of these elements it checks whether it is a text node. If it is, it appends the node’s value to the return value (ret). If it is an element, it recursively calls itself on that element, appending the result of the recursive call to the return value. At the end, ret is returned.

But, remember, in IE, the title element has no text node, because there are no child nodes. So what does ret equal? An empty string. The entire for loop is skipped, because elems is empty. It essentially goes straight from declaring ret="" to returning that initial value.

The code continues to work in other browsers because they rightly treat the element as having a single child node—a text node— and that node’s value—the text—is added to ret.

innerText doesn’t work either

Even if you’re using plain JavaScript without a a library, document.title is the way to do this. Typically, to set the text of an element in IE you would use the innerText property, but you shouldn’t do that in this situation. There are a couple reasons for this:

  1. It doesn’t work in IE. In fact, it’s a documented issue dating back to IE 5, maybe earlier. At this point, we have to assume Microsoft has it working as they intend it to.
  2. The innerText property doesn’t work cross browser. In FireFox, you have to use the textContent property. Why bother writing extra code to be cross-browser compatible when document.title will work without issue?

Wrapping it up

Here’s that first script again, showing the correct way to do it:

var foo = document.title;
alert("The title was "+foo);
document.title = "Now it’s been changed.";
alert(document.title);

So now you know why you can’t use jQuery.text() to retrieve the page title. But that’s ok, because doing so would be inefficient anyway when you can just call document.title. Good luck with your dev.

You Are Not a Web Developer

Yes, I’m talking to you, Dreamweaver user. You. Are. Not. A. Web. Developer. You’re just the person that is screwing up the nice, pretty, semantic, standards-based Internet for the rest of us. The one that devalues our hard work with your naive undercutting. The one who makes our life hell when our project managers quote maintenance or design-tweaking projects not realizing that we can’t just reuse your code and keep our dignity intact. You. I really hate you, you MM_preloader using, nested-tables employing you.

But it’s not because you use Dreamweaver. It’s the fact that you use it as a crutch. Yes, you call it a tool.  A great tool that lets you create these awesome sites without knowing how to do any coding. That, my enemy, is a crutch, not a tool. And p.s. your sites aren’t awesome; they’re bloated, inefficient and have nasty, nasty code under the hood because you don’t know the two types of markup that a developer uses daily: CSS and HTML.

Why is it so wrong?

Don’t worry, I’m not going to just berate you and not try to back myself up a bit.

You can’t fix it when it doesn’t work right

So, you tell Dreamweaver to lay something out in a specific way, but then it doesn’t look right in a certain browser. But, you don’t know how to fix the code and make it work right, do you? Yeah, didn’t think so. Don’t get me wrong, developers spend time debugging and don’t always know how to fix it, but we do know what we’re looking at when we take a gander at the code, and can understand what the code is doing when we find a fix from some other resource.

You’re ignoring SEO

Sure, you might be using header tags, and may even have the right meta tags in there. But you’re not coding for search-based optimization. First, your code is bloated. Search engines sometimes parse the first hundred or fewer lines of code, and your bloated code might not have anything of interest until far later in the code. Second, if you are using rollovers or drop-down menus, you’re using code that search engines can’t do anything with. Much of Dreamweaver’s built in code for things like drop-down menus and rollover images is based on JavaScript, even though it’s not generally needed to do either of those things. Both can be accomplished with CSS.

You’re letting your users get bored

Have I mentioned that your code is inefficient and bloated? Yes? Well, I don’t mind saying it again and again and again. Because all that inefficient, bloated code is extra bytes for your users to download. Extra bytes that really increase loading time. People get bored waiting for a site to load. Then they leave. Without seeing your content. In this new world of 2010, where it seems like everyone has mobile Web access, small, efficient sites are back in vogue. Who wants to pull down three different JavaScript libraries and hundreds of extra lines of code on 3G? (Gods forbid a user is still on EDGE) Slow sites mean fewer visitors willing to stick around long enough for the chance to visit. Svelte code is sexy. Your overweight code is as bad as the obesity epidemic plaguing America.

And this point isn’t just true of Dreamweaver-based sites. iLife, Frontpage, Microsoft Word, whatever other WYSIWYG editor du jour you can name… they all create truly horrendous code that is terribly bloated.

Hey Kettle, you’re black!

Yeah, Pot, that’s right, I do use Dreamweaver. Eight hours a day, more or less. But you know, for a while there, I actually forgot it had something called design view, until my preferences got all screwed up and reset themselves, causing a project to load up in design view. That was a shocker. See, I use it because it’s a decent text editor and code completion speeds up development time. It has a built in project system with an FTP tool that keeps me from having to run two or three programs at a time. But ultimately, I use it because it is what is on my system at work.

Curtis McHale said it well in an article reprimanding hiring managers for saying “Dreamweaver users need not apply”:

At my fulltime job it simply comes down to cost. I use Dreamweaver because it is in CS3. There is no real break through feature that I could find to justify to my boss so that they would purchase Coda.

And Curtis is lucky. He posted that over a year ago and had CS3 at work. Here it is Aug. 2010 and I’m still stuck with CS2 at my 9-5. It’s a sore point for me. But hey, I’m employed, I’m not going to complain too awful much. But there’s probably a snowball’s chance in hell that my company is going to pony up cash for a different program.

I could write a site up in Text Edit or Notepad if that is all that was available to me, then pull up an FTP program to upload to the server. It’d decrease my efficiency, but I could do it. But if you’re paying me, don’t you want me to be as efficient with my time as possible? Of course, if you aren’t the company I work for, you’re not paying me to use Dreamweaver because I use Coda at home. But you, you’re not efficient. It takes me less time to type it all out, because I know the code, than it does for you to go through all the WYSIWYG dialogs.

Are you willing to defend Dreamweaver WYSIWYG? Go ahead, play Devil’s advocate in the comments.

Why I Switched to WordPress

The Web is ever changing, and this article is relatively ancient having been published 13 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

I’m pro-intensive-customization, anti-bloat, pro-knowing-what-your-code-does. For over a year, my site ran on a code-base authored at least 90% by me. Don’t get me wrong, I know when to say “hmm, that’s not my strong point, let me use someone else’s code,” but I wanted to have total control over every aspect of my site’s backend. Then, last night I went live with WordPress.

I was resistant to using an out-of-the-box CMS for my own site for a long time. Some of those reasons were tenable, but most were at best me being stubborn and at worst illogical.

Frankly, as often as I get stuck doing backend work at well, work, why do I want to be doing it in my free time as well? There are so many features I want to develop on my site that I just haven’t gotten around to, because at the end of the day, I don’t want to touch that kind of code. Using WP, I can just enable those features, add a plug-in or tweak a little code and quickly have that functionality. It saves me time and headaches.

But wait, why are you using WordPress?

…instead of <ANY OTHER CMS>.

WP isn’t necessarily my favorite CMS out there. I even tweeted an anti-WP haiku once:

A haiku inspired by bad advice. “Wordpress: blog system. / Bloated, not secure, real slow. / Not true CMS. ” (My opinion only)

But I promise I’m not being as hypocritical as it may seem.

  • First and foremost, my site is a blog. Or four blogs, depending on how you look at it. It’s not some gigantic commercial site. A blog needs blogging software. WP is a pretty solid blogging software.
  • My anti-WP tweet was focusing on advice someone gave a client that their 1000+ page absolutely had to be in WP because that’s the only CMS in existence that is any good. Uhh, no.
  • More and more often, I’m finding myself using it for client sites (where the decision to use WP was already made or where it seems like the best solution). In order to be the successful, efficient developer I like to be, I need to become more intimately familiar with the system, and what better way to do that than to use it on my own site?

That last bullet has about 70% of the weight in this decision. Maybe when I start inheriting a bunch of Joomla sites, I’ll develop a different personal project on it. Although I probably won’t port this one to anything else again. That bit was painful.

Great, I’m going to switch to WP too!

…just because of this article.

Hold up there. WP isn’t necessarily the right fit for every site.

If you want to start a blog, sure, go for it. It’s simple, has a ton of themes, and mostly uses pretty good, standards-compliant code.

If you already have a blog using another CMS, stop. Evaluate. Why do you need to switch? Are you unhappy with your current system? Is there some very important feature you want that doesn’t exist in the current system? Why WP? Those are all questions to consider.

If you don’t blog (or your site is separate from your blogs), but have heard that your business absolutely has to have a site built on WordPress, stop. You need to talk to a developer. And I’m not talking about your wife’s niece that took a few design classes at the community college and is now a “Web designer.” WP very likely might not by the right CMS for you. But don’t fret, there’s something out there that will help you meet your goals, and the right developer can help you decide what that is and how to get it going.

What’s your CMS of choice? Are you happy with what you’re using? Think I’m totally bonkers? Everyone has their preferences. When porting the site over, I found quite a few things I’m not 100% happy about with WP, but that’s what custom themes and plug-ins are for, right? So, as I learn more, you’ll surely start seeing some changes around here. And probably some WP-centric posts as well.

Dictionary Lists: Child Elements and How to Use

One thing I see far more often than is excusable in code that I inherit is improperly used and structured dictionary lists. Certain elements in HTML are limited to having only a few specific children, and dictionary lists are no exception. Putting incorrect elements as direct children can cause display issues, parsing issues, compatibility issues and headaches for future development (whether it’s a new developer or your own updates). When developing, it should be a priority to use the correct—and only the correct—children in parent elements. Here’s how to properly use dictionary lists.

Dictionary Lists (<dl>)

The dictionary list element is meant to be used for a list of items containing terms and their definitions. That doesn’t mean you’re restricted to using this element only for word lists. For instance, the structure of the element is perfect for frequenty asked questions (FAQs): the question is a term, the answer is a definition. Dialog is another option: the speaker is the term, the words spoken are the definition.

So, let’s repeat: dictionary lists are lists of items containing terms (<dt>) and their definitions (<dd>).

A dictionary list can only have two types of child elements: dictionary term (<dt>) and dictionary definition (<dd>). Semantically, each definition can have multiple terms, and each term can have multiple definitions. That said, the first child should always be a term and the last child should always be a definition.

But <dt> and <dd>—that’s it. No other immediate children are allowed. Of course, you can put other elements inside of those two child elements. But even they have restrictions.

Dictionary Terms (<dt>)

Dictionary term elements can only contain inline elements. That means you can use things like <a>, <strong>, <em> or <span>. You can not use <hn>, <p>, <div>, etc.

Dictionary Definitions (<dd>)

Dictionary definition elements can contain any flow elements— inline or block. That means you can use things like <a>, <strong>, <em> or <span> and <hn>, <p>, <div>, etc. You can have a dictionary list inside of a dictionary definition. You can have a form inside of a dictionary definition. You can basically have anything that is allowed inside the <body> element inside of a dictionary definition.

Valid vs. invalid

The following is an invalid list (with shorthand code showing only elements, not required attributes). Don’t do it.

<dl>
<form>
<dt>Name</dt>
<dd><input></dd>
...
</form>
<dl>

Here’s a valid list.

<dl>
<dt>Ginormous</dt>
<dt>Gargantuan</dt>
<dd>Both are words that mean “enormous,” but sound way cooler.</dd>
<dl>

Get it? Good. Go forth and dev.

What tips do you have for using dictionary lists?

Creating Right Triangles in Adobe Illustrator

Here’s a quick way to draw a right triangle in Adobe Illustrator. It involves using just two tools: the rectangle tool and the pen tool. Don’t worry if you don’t have much experience with the pen tool—we’re using it very simply. The method: draw a rectangle or square and then use the pen to delete a corner, instantly creating a right triangle.

These instructions will work in Adobe Illustrator from CS–CS5. The same strategy should work in any vector drawing program that allows you to use a pen-type tool to delete anchor points from a shape.

How to create a right triangle in Illustrator

  1.  Select the rectangle tool. (Keyboard shortcut m)
  2. Use the rectangle tool to draw either a rectangle or square, depending on the type of right triangle you want.For a 45°-45°-90° triangle (half-square triangle) draw a square

    For all other right angles draw a rectangle

    A. Freehand method
    Square: Hold down the shift key on your keyboard, click and drag to draw a square of the desired size.
    Rectangle: Click and drag to draw a rectangle of the desired size.

    screencap of freehand method
    B. Exact-size method
    Click once anywhere on your artboard to open the rectangle dialog.

    screencap of dialog

    Type in your desired dimensions for the legs of your triangle (not the hyptenuse).

    Click ok.

  3.  Select the pen tool. (Keyboard shortcut p)
  4. Point your cursor in pen tool mode over the anchor (small square in shape outline) in one corner of your shape. The cursor will change into the delete anchor point tool.
    screencap of delete anchor point tool

    Click on that anchor to delete it.

  5. Success. You should now have a right triangle.
    screencap of right triangle

If something happens so that your shape is deselected before you try to delete the anchor, use the  select tool (black arrow tool, keyboard shortcut v), to click on your new shape so that it is selected, then try from step 3 again.

This entry is part of the Keyword Answer Quest series. The series focuses on answering queries presented by long tail keywords that bring searchers to other pages on my site. Sometimes, these keywords don’t lead readers to a very relevant page, but when my expertise can meet their needs, Keyword Answer Quest comes in. This entry was inspired by searches including:

  • cut right square into right triangle illustrator
  • how to make half square in illustrator

Online Retailers: Help Your Customers Find Your Products

The Web is ever changing, and this article is relatively ancient having been published 13 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

Aisle of products One of my favorite (only because it has the best, low-price selection) sources of quality fabrics has horrible UX on their store site. Horrible to the point that I’m only able to do rudimentary filtering because I understand the GET variables they use to display their catalog. In fact, I wrote a post to help non-developer users figure out how to filter the catalog by changing the URL. The fact that I had to do either of those things really bothers me as a front-end developer; your users should never have to resort to manipulating the URL in order to filter or find products.

If a user can’t easily figure out that you carry a certain product, you just lost a sale. Think about that and what it means to your business.

Say a customer walks into your brick-and-mortar store wanting a specific type of whatchamacallit with a budget of $5. They see that there is a whatchamacallit aisle, but it’s just overwhelming: you have have 200 different colors of that specific type of whatchamacallit. There are different sizes, weights, and patterns. The customer’s not too picky about some of the finer points, or maybe they are, but it doesn’t matter because they only have $5 that they want to spend. So, they want to quickly narrow it down to all whatchamacallits under $5. They could go down the aisle looking at every one, but it’s easier for them to find a store employee and ask, “can you show me the whatchamacallits that are under $5?”

Being a store that cares about making a sale, your employee says yes, helps the customer, maybe even upsells them, and the customer makes a purchase. Money in the bank for the store.

Now stop. Why should this interaction be any different in your online store? That’s right, it shouldn’t be. Sure, it’s a bit difficult to have a person there, so to speak (you could have a live chat function). But there are alternatives:

  • An obvious search box that accepts queries like “whatchamacallits under $5” and returns useful, intuitive results.
  • Obvious, intuitive filtering and sorting options for search results with obvious, intuitive controls.
  • Obvious, intuitive filtering and sorting options within categories with obvious, intuitive controls.
  • An obvious, intuitive way to change the number of items shown on a page.

Notice the similarities up there: obvious and intuitive. It’s not simply adequate to provide those controls; people need to be able to find them and use them easily—just like they’d need to be able to easily find a knowledgeable employee. Good online store software will have all of those things out of the box or your developer will set it up as a standard part of your store creation. All of these filters should persist until the user says to remove it, as well: if a user filters to blue whatchamacallits then applies a $5 filter, they should be shown blue, $5 whatchamacallits not just $5 ones in any color. Sounds like common sense, right? Too many online stores don’t seem to get it.

Now, back to the earlier example. What if your employee said to the customer, “no, find it yourself.” Maybe the customer would spend time looking, but more likely they’d realize that you don’t care about their patronage and they’d go somewhere else to find the whatchamacallit. You just lost the sale. You’d probably fire an employee that did that consistently.

That’s exactly what’s happening at the fabric store. And many other online stores with outdated store software that has no filtering. There’s no provided way to easily narrow the products down to a specific one you’re searching for. There’s a search function, but it’s not that great, and there’s no way to narrow down the results. There’s absolutely no way to sort of filter the category item listings at all. They need to fire their store software.

Keep in mind that simple categorization is not sufficient criteria browsing or searching. Just because I want a whatchamacallit doesn’t mean I’m interested any whatchamacallit you carry. Shoppers, whether they’re just browsing or are looking for a very specific item, are more likely to buy from you if they can find what they are looking for. If they can’t find it, they can’t buy it. If they’re browsing a sales listing hoping to find something they think they need, you’ll have more success on a conversion if they can narrow down that sales list to items they are interested in. Sure, they can start at the top—viewing everything—but maybe they see a coolthing that intrigues them, but it’s not the perfect coolthing they want to buy. If they can easily narrow that listing to all coolthings, your ability to sell them something just increased. They know you carry the type of item, and are easily able to drill down to all items of that type. If they can’t, then maybe they keep looking, or maybe they get bored after going through another 2 pages with no more coolthings because all the other coolthings are 12 pages into the sales. A bored visitor leaves, and so does their money.

What do you expect from online shopping user interfaces? What makes you go to another store? Stay at the current store? Feel free to share good or bad experiences and examples in the comments.

Losing Values When Cloning Forms

The Web is ever changing, and this article is relatively ancient having been published 13 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

I’ve finally started development of a book recommendation widget for the musings and reviews on books I read section of my site. The general functionality is pretty simple: visitors have a few fields to complete with info about the book; upon submission, their recommendation is saved to a database; the new recommendation is shown to all and sundry in a “last recommendation” section; rinse & repeat. The whole no-JS needed, server-side scripting processing involved is simple, straight-forward and was quickly completed. Being a front-end developer, however, I want to make sure this can all be done in a smooth JS-enhanced way as well (for some nifty UX). That’s where I encountered yet another annoying JavaScript problem.

Each browser interprets “clone” differently

Due to differences in how each browser implemented cloneNode() in their JavaScript engines, there is an issue with values for form elements not persisting to the copy of an element. Inconsistencies like this are many of the reasons why I’m a fan of using a JavaScript library for most projects. In this case, because the library has usually worked out the issues and can handle copying without losing important data. Unfortunately, jQuery still has some issues to work out; it loses select and textarea values on clone(). Other inputs types don’t seem to have any issues, including hidden fields.

How this affected my widget

In order to display the submitted form data in the “last recommendation” section, I decided the best approach would be to copy the form, then replace each form element with an inline element containing the value based on type of element. It might not be the most elegant solution, but it seemed better than specifying each individual element by name and manipulating it that way.

So, step one: use clone() to copy the form (no need for cloning events and the like). Step two: do the replacement. Step three: realize that regardless of selection, the last recommendation always displays the first option in a select box. And an empty string for any text area.

Solutions

Honestly, my current solution is just a dirty hack. I only have two affected fields, so I explicitly copy the original values to where they need to go. I’m more concerned about getting this up and running, knowing that there won’t be much in the way of extension in the future. I am about 99% positive I won’t be adding any additional fields, at least.

For other projects though, this could be a major issue for scalability and ongoing maintenance, especially if there are multiple affected elements. A quick search around the Internet shows a lot of inelegant solutions. One that approaches a decent solution for jQuery is this solution at mddev.co.uk, although it only attacks the select issue (and later inputs as well with a bit overkill [see the comments], but no textarea). That approach could work with some modifications.

Have you seen this before? How’d you solve it/work around it?

Trigger AJAX Error Event

The Web is ever changing, and this article is relatively ancient having been published 13 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

When I was new to working with AJAX functions—especially in the realm of form submission—one hurdle I often encountered was how to handle processing errors in my back-end script and give meaningful feedback to my users. I didn’t understand how to designate a response as an error instead of successful processing. Early on, I sometimes employed a dirty hack of prepending any error with the string ERROR: and then adding in some quick checking to see if that substring existed in my response text. While that may get the job done, it’s not good form. It causes convoluted code usage, thumbs its nose at existing error handling functionality and makes future maintenance a headache. But there is a better way by simply utilizing your processing language’s inherent header and error handling functionality.

N.B. From a JavaScript standpoint, I’m showing code based on the jQuery library, because I use it on a regular basis. The concept of triggering the XMLHttpRequest object error handling with proper headings is applicable to any type of JavaScript coding. Likewise, my server-side processing examples in this article are coded in PHP, but that is not the only applicable language. You can produce similar results with other languages as well, so long as that language allows you to send header information. If you’re willing to translate my examples into another language or non-libraried JavaScript, please do so in the comments or e-mail me (rae.arnold@gmail.com), and I’ll add it into this article (and give you credit, of course).

The information in this article refers to AJAX requests with return dataTypes of html or text. JSON and XML dataTypes are for another day.

The client side of things

Let’s say we’re working with a bare-bones comment form: your users add a name, e-mail address and their comment. Three fields, all required, easy-peasy. For the purposes of this article, we’re going to ignore all of the validation you would want to do on the form and focus solely on the process of sending it via AJAX to your PHP processing script. The resulting AJAX call with jQuery might look something like:

//[warning: most of this is pseudo-code, not code you can copy+paste and expect to immediately work]
$.ajax({
    type: "get",
    url: "/processing/process_comment.php",
    data: $("#commentForm").serialize(),
    dataType: "html",
    async: true,
    beforeSend: function(obj) {
        //give user feedback that something is happening
        showProcessing();
    },
    success: function(msg) {
        //add a success notice
        showNotice("success",msg);
        clearForm();
    },
    error: function(obj,text,error) {
       //show error
       showNotice("error",obj.responseText);
    },
    complete: function(obj,text) {
        //remove whatever user feedback was shown in beforeSend
        removeProcessing();
    }
});

Essentially, the above JS expects the server-side processing script to return a message to show the user. We’ll set up such a script next.

The server side of things

Processing our simple comment form is close to trivial. We’d want to do some basic validation, make sure the submitter hasn’t been blacklisted for spamming or other reasons (in this example based on IP address), and then add the comment to a DB. The interesting part, however is how to tell the server that an error occurred during the processing and have that error propagate back to the AJAX properly. This is where the header and exit functions come in handy. Look at this example:

<?php //[warning: the "processing" is pseduo-code functions, however the error throwing parts are valid]
    // perform validation
    if (validValues($_GET)) {
        if (blacklisted()) {
            header('HTTP/1.1 403 Forbidden');
            exit("Uh, hi. Your IP address has been blacklisted for too many spammy attempts. Back away from the keyboard slowly. And go away.");
        }
        if (addComment($_GET)) {
            // We have success!
            print("Your comment has been successfully added.");
            exit(0);
        }
        // if the code reaches this point, something went wrong with saving the comment to the db, so we should show an error
        header('HTTP/1.1 500 Internal Server Error');
        exit("Something went wrong when we tried to save your comment. Please try again later. Sorry for any inconvenience");
    } else {
        header('HTTP/1.1 400 Bad Request');
        exit("This is a message about your invalid fields. Please correct before resubmitting.");
    }
?>

In PHP, the header function allows you to send headers to the client. In the syntax used above, it is allowing us to specify error status. For more info on the header function, head to the PHP manual on header. exit is a handy construct that ends script execution while allowing you to print an error. Upon successful completion of the processing, we make sure to call exit(0), which signifies successful completion of the script. Any non-0 value indicates that an error occurred. Learn more at the PHP manual on exit. For errors, you can also use the die construct, which is equivalent to exit.

Putting it all together: View a Demo

Let’s get advanced

The above examples for the error function are pretty simple, but you can create very elegant error handling solutions with it by utilizing other properties of the XMLHttpRequest object. One possibility is to take unique actions based on status code returned. By using the status property of the object, you can customize your error handling based on the status returned. For instance, this error function script would alert a user to modify form information if needed, but completely remove the form if they found the user is a blacklisted IP (using the same server-side script from above).


    error: function(obj,text,error) {
        self.showNotice("error",obj.responseText);
        if (obj.status == "403") {
            self.remove();
        }
    }

Have you utilized this method in your AJAX programming before? Let us know how it worked for you.