/* -------------------------------------------------- *
* ToggleVal 3.0
* Updated: 01/15/2010
* -------------------------------------------------- *
* Author: Aaron Kuzemchak
* URL: http://aaronkuzemchak.com/
* Copyright: 2008-2010 Aaron Kuzemchak
* License: MIT License
** -------------------------------------------------- */

(function($) {
// main plugin function
$.fn.toggleVal = function(theOptions) {
// check whether we want real options, or to destroy functionality
if(!theOptions || typeof theOptions == 'object') {
theOptions = $.extend({}, $.fn.toggleVal.defaults, theOptions);
}
else if(typeof theOptions == 'string' && theOptions.toLowerCase() == 'destroy') {
var destroy = true;
}

return this.each(function() {
// unbind everything if we're destroying, and stop executing the script
if(destroy) {
$(this).unbind('focus.toggleval').unbind('blur.toggleval').removeData('defText');
return false;
}

// define our variables
var defText = '';

// let's populate the field, if not default
switch(theOptions.populateFrom) {
case 'title':
if($(this).attr('title')) {
defText = $(this).attr('title');
$(this).val(defText);
}
break;
case 'label':
if($(this).attr('id')) {
defText = $('label[for="' + $(this).attr('id') + '"]').text();
$(this).val(defText);
}
break;
case 'custom':
defText = theOptions.text;
$(this).val(defText);
break;
default:
defText = $(this).val();
}

// let's give this field a special class, so we can identify it later
// also, we'll give it a data attribute, which will help jQuery remember what the default value is
$(this).addClass('toggleval').data('defText', defText);

// now that fields are populated, let's remove the labels if applicable
if(theOptions.removeLabels == true && $(this).attr('id')) {
$('label[for="' + $(this).attr('id') + '"]').remove();
}

// on to the good stuff... the focus and blur actions
$(this).bind('focus.toggleval', function() {
if($(this).val() == $(this).data('defText')) { $(this).val(''); }

// add the focusClass, remove changedClass
$(this).addClass(theOptions.focusClass);
}).bind('blur.toggleval', function() {
if($(this).val() == '' && !theOptions.sticky) { $(this).val($(this).data('defText')); }

// remove focusClass, add changedClass if, well, different
$(this).removeClass(theOptions.focusClass);
if($(this).val() != '' && $(this).val() != $(this).data('defText')) { $(this).addClass(theOptions.changedClass); }
else { $(this).removeClass(theOptions.changedClass); }
});
});
};

// default options
$.fn.toggleVal.defaults = {
focusClass: 'tv-focused', // class during focus
changedClass: 'tv-changed', // class after focus
populateFrom: 'default', // choose from: default, label, custom, or title
text: null, // text to use in conjunction with populateFrom: custom
removeLabels: false, // remove labels associated with the fields
sticky: false // if true, default text won't reappear
};

// create custom selectors
// :toggleval for affected elements
// :changed for changed elements
$.extend($.expr[':'], {
toggleval: function(elem) {
return $(elem).data('defText') || false;
},
changed: function(elem) {
if($(elem).data('defText') && $(elem).val() != $(elem).data('defText')) {
return true;
}
return false;
}
});
})(jQuery);
