/*
* @File: jquery.formLabels1.0.js
* @Version: 1.0
* @Author: Andrei Zharau (www.o2v.net) - Senior UX Engineer at LibertyConcepts.com
*
* @Requires: jQuery v1.4++ & jQueryUI v1.8++
* @Usage: $j.fn.formLabels()
* @Options: excludeElts - Excludes certain elements from being 'labelized'. Default: ''. Example: $.fn.formLabels(excludeElts:'#email, .nolabel')
* refreshOnResize - whether or not refresh labels on window resize. Default: true
* safemode - if enabled the plugin runs in the safemode without using spans and animation. Default: false
* labelParent - parentContainer for your 'labels'. Default: 'form'
* semantic - puts label before input element. Default: true
* @Methods: $.fn.formLabels.refreshLabels() - refresh labels' position. Useful when input positioning has been changed due to DOM modifications, elements resizing, etc.
* @Changelog
* 1.0
* + depending on which element is a parent element, script creates formLabels either as spans or labels (suggested by Alex Hall)
* + new option 'semantic'. If true, then plugin renders label before input box (works only if labelParent:'form')
* * 'labelParent' option supports any element on the page, but labelParent: 'form' puts labels into closest form. Default value has been changed to form. (suggested by Ferry Mulyono)
* * changed logic for label's background detection
* * fixed problem with blur event (formLabel did not disappear on auto-complete)
* 1.0RC3
* + fixed probmlems with input events in IE
* + Green Hue Opacity bug in FF (thanks to Ionut Staicu)
* 1.0RC2
* + plugin supports a new refresh method
* + new options: safemode and labelParent
* + refresh on window resize is now an option
* + slightly updated performance
*
* Copyright 2010 Liberty Concepts, all rights reserved.
*
* This source file is free software, under either the GPL v2 license or a
* BSD style license, as supplied with this software.
*
* This source file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
*/
;
(function($){
var formLabels,
opts,
elts;
$.fn.tagName = function() {
return this.get(0).tagName;
}
formLabels = $.fn.formLabels = function(options) {
opts = $.extend({
excludeElts: '', //elements to be excluded
refreshOnResize: false, //whether or not refresh labels on 'resize' event for window
safemode:false, //enable safe mode without DOM modifications
labelParent: 'form', //specifies a block that will store the form labels (body or form)
semantic: true //if true, then plugin renders label before input box (works only if labelParent:'form')
},options);
var spanID = 0;
elts = $("textarea, input[type='email'], input[type='text'], input[type='password']").not(opts.excludeElts).filter(":visible[title]");
if (elts.length && !opts.safemode) {
elts.each(function(){
var $this = $(this);
var spanBg = '';
var $thisBC, //background-color of input box
$thisBI, //background-image of input box
labelParent, //parent element
tagName; //type of the element to be inserted
if(this.value == '' && this.title != '') {
if (opts.labelParent == 'form') {
labelParent = $this.closest('form');
tagName = '';
}
else {
labelParent = $(opts.labelParent);
tagName = '';
}
if (labelParent.css('position') == 'static') {
labelParent.css({'position':'relative'})
}
var label = this.title;
var parentPosition, offsetValue, myPosition;
var paddingValue = {
top: parseFloat($this.css("padding-top")) + 1,
left: (parseFloat($this.css("padding-left")) < 2) ? 2 : parseFloat($this.css("padding-left")) + 1
}
if ($this.tagName() == 'TEXTAREA') {
parentPosition = 'left top';
myPosition = 'left top';
offsetValue = paddingValue.left + ' ' + paddingValue.top;
}
else {
parentPosition = 'left center';
myPosition = 'left center';
offsetValue = paddingValue.left + ' 0'
}
if ($.browser.mozilla) {
$thisBC = $this.css("background-color");
$thisBI = $this.css("background-image");
if ($thisBI == 'none') {
if ($thisBC != '') {
spanBg = $thisBC
}
else {
spanBg = '#fff'
}
}
}
var formLabel = $(tagName, {
css: {
'font-family' : $this.css("font-family"),
'font-size' : $this.css("font-size"),
'font-style' : $this.css("font-style"),
'font-weight' : $this.css("font-weight"),
'text-shadow' : ($.support.opacity) ? $this.css("text-shadow") : '',
'line-height' : $this.css("line-height"),
'background-color' : spanBg,
'position' : 'absolute',
'top' : 0,
'left' : 0,
'color' : $this.css("color"),
'-moz-user-select' : 'none',
'-webkit-user-select' : 'none',
'cursor' : 'text',
'z-index' : '999'
},
id: "spanLabel" + spanID,
'for':($this.attr("id") == '') ? '' : $this.attr("id"),
"class" : "fLabel",
html : label ,
click : function(){
$this.trigger('focus');
return false;
}
});
if (opts.semantic && opts.labelParent == 'form') {
$this.before(formLabel)
}
else {
formLabel.appendTo(labelParent)
}
formLabel.position({
my: myPosition,
at: parentPosition,
of: $this,
offset: offsetValue,
collision: 'none'
});
$this.data({
"spanID" : "#spanLabel" + spanID,
"my" : myPosition,
"at" : parentPosition,
"offset" : offsetValue
})
}
spanID++; //Increasing spanID by one
});
elts.bind('focus blur change cut paste input keyup', function(e){
var LabelSpanID = $($(this).data("spanID"));
if (e.type == 'focus') {
if(this.title != '' && this.value == '') {
LabelSpanID.stop().fadeTo(300,0.2);
}
}
if (e.type == 'blur') {
if(this.title != '') {
if (this.value == '') {
LabelSpanID.stop().fadeTo(300,1, function(){
if (!$.support.opacity) this.style.removeAttribute("filter");
})
}
else {
LabelSpanID.stop().fadeOut(300)
}
}
}
if (e.type == 'change' || e.type == 'cut' || e.type == 'paste' || e.type == 'input' || e.type == 'keyup') {
if(this.title != '') {
LabelSpanID.stop().fadeOut(300)
}
if(this.value == '') {
LabelSpanID.stop().fadeTo(100,0.2)
}
}
});
if (opts.refreshOnResize) {
$(window).bind("resize", function(){
formLabels.refreshLabels(elts);
});
}
}
if (elts.length && opts.safemode) {
elts.val(function(i,v){
if(v == '')
return this.title;
else return v
});
elts.bind('focus blur', function(e){
if (e.type == 'focus') {
if(this.value == this.title)
this.value = '';
}
else {
if(this.value == '')
this.value = this.title;
}
})
$("input:image, button, input:submit").click(function(){
$(this.form.elements).each(function(){
if(this.type =='email' || this.type =='text' || this.type =='textarea' || this.type =='password' ){
if(this.value == this.title && this.title != ''){
this.value='';
}
}
});
});
}
}
//refresh method
formLabels.refreshLabels = function() {
elts.each(function(){
var $this = $(this);
var assocSpan = $($this.data("spanID"));
assocSpan.position({
my: $this.data("my"),
at: $this.data("at"),
of: $this,
offset: $this.data("offset"),
collision: 'none'
});
})
}
})(jQuery);