Watermark Love

Posted by James | Filed under

While stumbling through the twittersphere, I ran across an article from UX Movement about watermarking HTML inputs.  Naturally, I thought that I would come up with my own jQuery watermark plugin.

I have the code hosted on bitbucket @ https://bitbucket.org/xstoney/watermarklove/src.  It is a simple implementation of a watermark control.  It allows for the developer to define their own styles for the watermarked text, the field selected watermark text and the style when the watermark has been removed. 

Watermark

watermark

Input Selected

inputselected

Input Filled In

normaltext

There is also the option of marking the field as optional.  This would allow for a form that, instead of marking fields that are required, displayed fields that were optional.

address

First Attempt

This is my first attempt at this plugin. There are several improvements that could be made.

  1. Fade transition between text modes
  2. Callback methods for adding/removing/switching out the watermark
  3. In Google Chrome the text is highlighted in the box but what I would prefer is for the insert point to be placed at the beginning of the text
  4. Possibly use HTML5 Data attributes to semantically declare the watermark-y-ness of an input
  5. Watermark a select element
The Code

There are a couple of ways to setup a jQuery plugin. I chose the method where you select the elements that need to be enhanced and call the plugin method for each of these selected elements.

Create the watermark like so:

$("#firstname").watermark({text: "First Name"});

Here is the plugin code.

// Copyright (c) 2011 James Roberts

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

(function($){
   $.fn.watermark = function(options){               
      var defaults = {
         "style": {"color":"#EDAC80","font-style":"italic","font-weight":"bold"},
         "activestyle": {"color":"#EDD8CA","font-style":"normal"},
         "normalstyle": {"color":"000000", "font-style":"normal", "font-weight":"normal"},
         "optional": false,
         "text": ""
      };
      
      if(options) { $.extend(defaults, options); }
      
      var wmText = options.text + (defaults.optional ? " (optional)" : "");
      
      var util = {
         focus:    function(){
                  if(this.createTextRange){
                     var range = this.createTextRange();
                     range.move("character", 0);
                     range.select();
                  }
                  else if(this.selectionStart){
                     this.focus();
                     this.setSelectionRange(0, 0);
                  }
                  if($(this).val().replace(/^\s+|\s+$/g,"") === wmText){$(this).css(defaults.activestyle);}
                  
               },
         blur:   function(){
                  var $this = $(this);
                  if($this.val().replace(/^\s+|\s+$/g,"") === ""){
                     $this.val(wmText);
                     $this.css(defaults.style);
                  } else if($this.val() === wmText){$this.css(defaults.style);}
               },
         keypress:   function(){
                  var $this = $(this);
                  if($this.val().replace(/^\s+|\s+$/g,"") === wmText){
                     $this.val("");
                     $this.css(defaults.normalstyle);
                  }
                  else if($this.val() === ""){$this.val(wmText);}
               }
      };
      
      return this.each(function(){
         var $elm = $(this);
         if(options && options.text){
            if($elm.val().replace(/^\s+|\s+$/g,"") === ""){
               $elm.val(wmText);
               $elm.css(defaults.style);
            }
            $elm.focus(util.focus)
               .blur(util.blur)
               .keypress(util.keypress);
         }
      });
      
   };
})(jQuery);

Mercury Poisoning

Posted by James | Filed under

Ok, maybe it’s not poisoning and it’s actually pretty cool.  This post, as you may have guessed, is about source control.  Specifically I will cover some useful Mercurial (Hg) tools.  I have the opportunity of using Hg for source control on a project.  I am excited.  Here it goes…

What is it?

Mercurial is a source control tool. More specifically it is a Distributed Source Control Management Tool.  Find out more here about Mercurial specifically here and here.  Find out more about distributed source control here.

Where can I get some?

Download it here

How can I use it?

There are several tutorials available to learn how to use Mercurial.  Selenic, the company that maintains the software, has a wiki and set of tutorials here.  Joel Spolsky has a nice set of tutorials here.  He also offers hosting through Kiln here.  There is also free hosting here at bitbucket.org (which I personally use).

GUI fan?

If you just can’t stand the thought of using the command line utilities then there are some nice integration packages.  The first, TortiseHg integrates Mercurial into the Windows Explorer.  VisualHG is a tool to integrate Hg into Visual Studio. 

That’s it

Source control, I got to get me some of that.

One Time, at Give Camp

Posted by James | Filed under

Southwest Ohio Give Camp 2010

This weekend I had the opportunity to serve the local community.  The venue was the first annual Southwest Ohio Give Camp.  The tagline reads Geeks Giving Back.  That was definitely the case this weekend.

Three Days

The idea of a give camp is to have software developers, designers and analysts to create software for local charities.  Give camps were started a couple of years ago and have been done in several cities across the country. 

Community

A couple of aspects about this event stand out to me.  They both revolve around community.  The first is the obvious literal community.  Work is done at no cost for a local charity.  What better way to help those that help others each and every day.  The work assists charities that could not afford the work we can provide.  It is also a way to help others which most of the time makes us feel good.  It’s a win-win situation.

The second aspect of community is that of the local developer community.  Volunteering for give camp is a wonderful way to meet others in your local area that have similar interests and daily struggles.  Meeting others this way allows a developer to network with other developers and potentially learn new skills. 

In my project alone I was able to work with SQL, the Entity Framework 4.0, ASP.Net WebForms, a simple MVP framework, nUnit and SSRS.  Other solutions were done with CMS applications using languages that ranged from .Net to Ruby to PHP.

Looking Forward to 2011

If at all possible, I plan on attending next year.  Tell your friends, volunteer and make a difference.

Ruby Koans

Posted by James | Filed under , ,

koan  [koh – ahn] a nonsensical or paradoxical question to a student for which an answer is demanded, the stress of meditation on the question often being illuminating.

definition from dictionary.com

Fancy Name

I recently had the opportunity to go to the Cincinnati Day of Ruby.  I am primarily an ASP.Net developer but I thought this would be an interesting topic.  The objective was to learn a little about the Ruby language and the Ruby on Rails web development framework. 

The Rails content was a little sketchy because of several things, the worst was the non-standardization of the developer computers.  That said, the Ruby language portion, however, was quite nice.  The method to teach the Ruby language was Ruby Koans.

The Koans

The koans are a set of unit tests grouped by language topic.  For example, there is an entire section on Ruby arrays and another on methods, etc…  The tests initially all fail.  This causes the developer/learner to go through the code and make the test pass.  In order to do this, the user has to learn a little bit about Ruby each time. 

Check it out

I highly recommend the koans as a way to learn a new language.  Since learning Ruby (just a bit) from the koans I investigated other koans variants.  There are koans for most languages that are currently in vogue.  I’ve seen Python koans and JavaScript koans and I’m sure there are tons more.  My suggestion is now to go and learn.