Archive for the 'web design' Category


JQuery textbox watermark revisited: making it a plugin 1

In a previous post I talked about how you can do a textbox watermark very easily using JQuery. I’m long overdue in showing how you can take that same JQuery code and make it into a simple plugin.

So why would we make it a plugin? A JQuery plugin gives you the chance to encapsulate JQuery functionality into a single, pluggable module which can then be activated by calling a single method (with optional settings passed to it). If you’ve used things like the JQuery Validation library, you’ve seen a bit of the power of plugins. They are not hard to write, and the official documentation on the JQuery site gives you enough information to get started.

We will start off with the same basic HTML text box that we had in the previous post:

<input type="text" id="textBox1" />

And some simple CSS to go with it:

.watermark { color: #CCC; font-style: italic; }

So, just to recap what we want to do: when our focus is off of the textbox, and the textbox is empty, we want to display the default text, which is “type here…” in a light gray color. When the focus is on the textbox and the default text is displayed, we want to clear the box and the styling. If they type something in the box and then click elsewhere, we want to keep the new text and not reactivate the watermark style.

Using the previous JQuery code I posted as a base, here is the plugin code with comments to explain how it works:

(function($) {
	// Create a plugin with the name 'watermark'
	$.fn.watermark = function() {
		// Loop through the elements in the selector that we call the plug-in on
		this.each(function() {
			// Apply defaults to the box
			$(this).addClass("watermark").val("type here...");

			// Apply our focus and blur events
			// When we click on the field, we expect it to clear the field and remove the watermark
			$(this).focus(function() {
				$(this).filter(function() {
					// Check to see if we have a blank field or the default text
					return $(this).val() === "" || $(this).val() === "type here...";
				}).val("").removeClass("watermark");
			});

			// When we click off of the field, we expect it to replace the watermark,
			// unless we have entered text
			$(this).blur(function() {
				$(this).filter(function() {
					// Check to see if the field is blank
					return $(this).val() === "";
				}).addClass("watermark").val("type here...");
			});
		});
	};
})(jQuery);

To apply the plugin to our text box above we can now simply do this:

$(function() {
	$("#textBox1").watermark();
});

Making it better

What we’ve done so far is fine if you’re only concerned with a specific case, but what if we wanted to use this same plugin for different default text scenarios, or with different CSS classes? As it turns out, this is not hard to do.

We’re going to add two simple options to our plugin, but leave our defaults as they currently are:

(function($) {
	// Create a plugin with the name 'watermark'
	$.fn.watermark = function(settings) {
		// Defaults
		var config = {
			watermarkClass: 'watermark',
			defaultText: 'type here...'
		};

		// merge the passed in settings with our default config
		if(settings) $.extend(config, settings);

		// Loop through the elements in the selector that we call the plug-in on
		this.each(function() {
			// Apply defaults to the box
			$(this).addClass(config.watermarkClass).val(config.defaultText);

			// Apply our focus and blur events
			// When we click on the field, we expect it to clear the field and remove the watermark
			$(this).focus(function() {
				$(this).filter(function() {
					// Check to see if we have a blank field or the default text
					return $(this).val() === "" || $(this).val() === config.defaultText;
				}).val("").removeClass(config.watermarkClass);
			});

			// When we click off of the field, we expect it to replace the watermark,
			// unless we have entered text
			$(this).blur(function() {
				$(this).filter(function() {
					// Check to see if the field is blank
					return $(this).val() === "";
				}).addClass(config.watermarkClass).val(config.defaultText);
			});
		});
	};
})(jQuery);

Now, we can customize how we use the plugin:

$(function() {
	$("#textBox1").watermark({
		watermarkClass: 'grayText',
		defaultText: 'search'
	});
});

Files

Useful links

We don’t support the (insert name) browser 2

There are lots of web browsers out there now, which makes browser support a daunting task for any web developer or designer.  It doesn’t help the fact that even though there are standards, each browser has its own quirks as to how it interprets those standards.  Add to this the recent surge in mobile web use, and things get even more complicated, as you have mobile browsers that can support most web conventions (i.e. the iPhone) and older or smaller phones which cannot.  It may be permissible, for now, to say you cannot support all mobile browsing situations, but rarely is there a good excuse for not taking the time to assure quality in a variety of desktop browsers.

By adhering to the standards, you can get a website that is compatible for most situations.  There will likely be a few places where it is not, and more than likely the offending browser will be Internet Explorer.  There have been situations where I have spent hours just trying to work out a small kink in a design because of IE’s lack of full support for established standards.  Nevertheless, with some time and testing, all of this can be worked out if the design is good and the designer is familiar with browser quirks.  Not taking the time to test multiple browsers and versions is a sign of one or more of the following things: laziness, rushed to delivery, or poor quality assurance testing.

Laziness, or perhaps more appropriately, apathy about whether or not a site or application is cross-browser compatible, is probably the worst excuse for lack of cross-browser compatibility.  This is when the designer or developer of the application only tested it in, say, Internet Explorer, and didn’t care whether or not it worked in any other browser.  When people ask for support and are asked what browser they are using, if the answer is not Internet Explorer, they are met with the response “Oh, I’m sorry, we only support Internet Explorer.”  I don’t really find that to be acceptable today.  It is not difficult to install Mozilla Firefox or Google Chrome, at least the latest versions of them, and test the site.  At least know where the issues are!  And do not even get me started on the IT guys who will not let you install Firefox on a network computer because it is “insecure” (yes, I have actually encountered one).

There are some products that are rushed to delivery without the attention to testing that needs to happen.  Really, with these types of products and/or sites, the UI being cross-browser friendly is probably the least of their concerns, because there’s probably a lot more going wrong.  Tied together with this is the constant rush to get new features out the door and paying little attention to what’s happening with the UI.  As things are added, manipulated, or taken away, the chances of every little thing on the page working across different browsers decrease dramatically, especially if they were rushed, not tested, and thrown out into the world.  If the product is actually going so far as to throw errors in certain browsers, then you really have issues.  I have come across components from a certain vendor that would blow up when you viewed them in Google Chrome or Safari.  While this component vendor should have tested their product for cross-browser compatibility a bit better, so should the company using the component for their own product which produces the same error when viewed in those browsers.

Poor, or complete lack of, quality assurance testing means that any cross-browser issues that would have been caught will not be.  Even if there is not a QA “team” in place, some testing can be done by the designers and/or developers working on the project.  UI issues are generally pretty obvious, and testers with keen eyes can identify differences as small as one pixel.  In some respects, this is very similar to my explanation for laziness above, when it comes to the person designing or developing the project of checking their work in different browsers.  Having a team in place for testing means that additional eyes are looking over stuff that the designer or developer has been staring at for hours on end, which can be very beneficial.  Alas, not all companies can afford this luxury.

Cross-browser compatibility testing has become an important part of user experience testing, and it is not one that should be taken lightly.  The more popular the site or web application is, the more types of traffic it should be designed to accommodate.  One area I see this growing even more is in mobile web browsing, especially since mobile web browsers tend to have tighter restrictions as to what content they can actually display, and display correctly.  Many sites already have separate mobile versions, and it may be that this is the best way to address that particular issue.  All in all, the number of browsers that we need to support is not getting any smaller, so our workload is only growing.

Paying attention to your event binding in jQuery 0

When doing event binding in jQuery on a page that has a lot going on, it might be best to make sure you unbind and rebind the events, just to make sure you only get one event per element. I recently ran into an issue where the number of events triggered grew exponentially, and it was linked to this. Luckily, jQuery has a nice convention for working with rebinding. For instance, if we were binding to a button’s click event, and wanted to make sure this method was only ever called once when this button was clicked, we could do the following:

1
2
3
4
5
6
7
8
...
$("#some-button-id").unbind("click", buttonClickCallback)
    .bind("click", buttonClickCallback);
...

function buttonClickCallback(e) {
    // code for the button click event
}

This way, we explicitly remove and reset the function that will be called when that button is clicked. Inside the function body, you can still use $(this), just as you would do had you written the function inline. There are a couple of variations to the unbind method: without any arguments, it can unbind ALL bound events, and with only the event type, it will unbind all events of that type.

You can read more about bind and unbind with jQuery in the official jQuery documentation at http://docs.jquery.com.

Next Page »