jQuery Curtain 0.5.2

Just a few small changes.
  • Streamlined the code for removing curtains, which might be a small performance boost.
  • Removed an unnecessary call to makeArray in the get code.
  • Changed it to add the image as a hidden element then show it after it finishes loading. This is to prevent the user from seeing the image flash from the top left corner to the center of the screen in certain instances.
  • Most importantly, I fixed a bug that was causing the passed in options to be discarded.
On a side note, I have received some feedback recently about the API being a little "unclean". I was told (and I completely agree) that the passing in of strings to initiate certain specific actions is not a good way of doing that. I was thinking about this today and I see two alternative ways to implement this. The first is to have three separate functions.
  • The curtain() function that would create the curtains and return the curtained elements.
  • A curtainRemove() that would remove the curtains.
  • A curtainRetrieve() that would return the curtains instead of the curtained elements.
I am personally opposed to this approach, as having three separate functions for this plugin, in my opinion, muddies up the jQuery waters. The other solution I came up with is to change the curtain() function to return the curtains instead of the curtained elements. This seems like a better solution from an API perspective, but it would break your ability to chain the curtain call with other calls on the curtained objects. That isn't necessarily a big deal as certain functions already break the ability to chain. If we do that, then the API would just have curtain({options}), which would double as creating them and getting them. You could then call $("...").curtain().remove(); to destroy them all. Breaking the chaining seems like the cleanest solution to me. If you have any thoughts on the subject, please e-mail me, tweet me, or leave a comment.

Scoping Functions in Document Ready

When writing your event handlers in your document ready, it sometimes happens that you have the same functionality bound in a few different places. It is really easy to make a function that is not visible outside of your document ready but that allows you to reuse that code. Let's say, for example, that you have a link's click event and input field's keypress event that both need do the same simple action. We definitely want to reuse the same code for both places, but don't want the function exposed to the whole world. The easy thing to do is just declare the function in the bottom of your document ready's anonymous function, like so: [js] $(function() { $("a").click(doSomething); $(":text").keypress(doSomething); function doSomething() { console.log("we did something!"); }; }); [/js] This way, we have a local function that is accessible only from inside the document ready block. Reducing the scope like that will prevent accidental usage in other places, but still keep the code clean.

New Fork of InFieldLabels jQuery Plugin

I recently found an excellent plugin written by Doug Neiner for applying a label over an input field that appears as a default value. Implementing it as a label instead of defaulting the value of the input element is a better approach, IMO, because it allow you flexibility for animating the text and it will also work on password fields without showing ****. It isn't too difficult to use. All you need to do is have a container that is relatively positioned and contains a label and input field. The label should be absolutely positioned and you need to, in your css, make it hover correctly over the input. This also required you to calculate the margin, border, and padding of the input and apply the same to the label otherwise the text wouldn't line up. When I started rolling it out on a site I was working on, however, I quickly found that the special requirements for the label and its container proved challenging to mix with my existing designs. I thought it would be much better if the usage of the plugin was flipped around and instead of calling it on the label, you called it on the input itself and everything else just happened automagically. So, I forked the project and made the changes to support this approach. I won't go into too much detail here, as I explained it in the README of the project itself, but now all you need to do is have any input on the screen and call it like this: [js] $(":input").inFieldLabels("label text"); [/js] Doing that will insert an absolutely positioned label into the base of the body, calculate the position of your input and apply those values to the label, and calculate the margin, border, and padding of the input and set the padding of the label to match. This way, all you need to do is include the plugin and start using it. No special DOM structure or CSS required. The only thing to be aware of is that it does use a label tag and so you need to make sure that you set up "label.infieldlabel" in your css to match the text of your input elements. GitHub Project

Caps Lock Detection

UPDATED 2009.09.06 - Updated to support Opera Operating system logons (well OS X at least) provide a visual indicator alerting you to when you have caps lock turned on when you are typing your password. This is a pretty cool feature and it is actually really easy to implement in JavaScript. The vast majority of your users will type upper case letters in one of two ways: pressing the shift key or turning on caps lock. Following that assumption, you can easily check to see if a keypress event has the shift key pressed and what the charCode was. A simple function to detect caps lock and enable a visual cue would look something like this: [js] $(":password").keypress(function(e) { //Opera doesn't populate the charCode var charCode = e.charCode || e.which; !e.shiftKey && charCode >= 65 && charCode <= 90 ? $("#caps_lock").show() : $("#caps_lock").hide(); }); [/js] Here is the code in action:

CAPS LOCK IS ON!

Safari 4 on OS X will provide a cue for you, but adding a little extra flare to it won't hurt.