Skip to content
This repository has been archived by the owner on May 13, 2020. It is now read-only.

Commit

Permalink
Add in auto character limit approximation option.
Browse files Browse the repository at this point in the history
  • Loading branch information
remybach committed Nov 7, 2012
1 parent 891eb3f commit c7087bd
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 26 deletions.
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Here's a (very) [simple demo](http://remy.bach.me.uk/superlabels_demo/) of Super

You need to make sure that the element containing both the field and the label has `position:relative;`. Other than that, the plugin should have enough flexibility to handle most of your needs.

#### Basic
### Basic

The quickest and easiest way to use this plugin is as follows:

Expand All @@ -38,10 +38,11 @@ Lastly, you can choose to ONLY apply superLabels to specific fields if you wish

$('input.foo, textarea.bar, select.baz').superLabels();

#### Advanced
### Advanced

There are quite a number of options you can pass the plugin additional to the two I mentioned above:

* `autoCharLimit` - Whether to automatically attempt to determine the number of characters after which to fade the label out or not (see below for more on this). _(default: false)_
* `baseZindex` - The base z-index which we display on top of. _(default: 0)_
* `debug` - Whether or not to show console messages. _(default: false)_
* Note: this is not available in the minified version.
Expand All @@ -60,13 +61,21 @@ There are quite a number of options you can pass the plugin additional to the tw
* `wrapSelector` - The selector for the element you have wrapping each field. _(default: false)_
* This is used to find the label - use as a last resort. Rather make sure the field and label are next to each other in your markup, or failing that, that your labels use the `for` attribute that point to the field's `name` or `id`.

Last, but not least, you can choose to only fade out the label *after* a certain number of characters have been typed (as of version 1.1.2). You can make use of this by adding a `data-sl-char-limit` with the number of characters you wish for any given field (simply leave it out if you don't want to use this)
#### "Character Limit"

Last, but not least, you can choose to only fade out the label *after* a certain number of characters have been typed. You can make use of this by adding a `data-sl-char-limit` (as of version 1.1.2) with the number of characters you wish for any given field (simply leave it out if you don't want to use this).

For example, to make the label fade out only *after* 20 characters have been typed in the field:

<label for="text-input">Name</label>
<input type="text" name="text-input" value="" data-sl-char-limit="20" />

As of version 1.1.3, you can now choose to let superLabels do the heavy lifting for you and let it automatically try to guess the character length☨. You can do this by using the above `autoCharLimit` option, _or_ by setting the `data-sl-char-limit` to `auto` for a given field.

The `autoCharLimit` option will be overridden by whatever is specified in the `data-sl-char-limit` attribute for that given element.

☨ Note that this is only an approximation. Unless a mono-spaced font is used, there isn't a method of figuring out _exactly_ what length the characters are that _isn't_ expensive in terms of performance.

## Concerning placeholders

According to [the spec](http://www.w3.org/wiki/HTML/Elements/input/text) placeholders are meant to be used to represent "a short hint (a word or short phrase) intended to aid the user with data entry." *NOT* as a replacement for labels.
Expand Down
74 changes: 53 additions & 21 deletions jquery.superLabels.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/*
* Title: jQuery Super Labels Plugin - Give your forms a helping of awesome!
* Author: Rémy Bach
* Version: 1.1.2
* Version: 1.1.3
* License: http://remybach.mit-license.org
* Url: http://github.com/remybach/jQuery.superLabels
* Description:
* This plugin allows you to display your form labels on top of your form fields, saving you space on your page.
*/
;(function($) {
var defaults = {
autoCharLimit:false, // Whether to automatically attempt to determine the number of characters after which to fade the label out or not.
baseZindex:0, // The base z-index which we display on top of.
debug:false,
duration:500, // Time of the slide in milliseconds.
Expand Down Expand Up @@ -40,8 +41,7 @@

// If options were passed in, merge them with the defaults.
$.extend(defaults, options || {});
if (!$.easing.def) { _info('Easing plugin not found - using standard jQuery animations.'); }


// Check for whether the user has just passed in the form. If so, we need to fetch all the accepted fields.
if (this.length === 1 && /form/i.test(this[0].tagName)) {
_fields = $(acceptedElements.join(','), this);
Expand All @@ -64,7 +64,6 @@

// Don't even bother going further if this isn't one of the accepted input field types or elements.
if ((_field[0].tagName.toLowerCase() === 'input' && $.inArray(_field.attr('type'), acceptedInputTypes)) === -1 && $.inArray(_field[0].tagName.toLowerCase(), acceptedElements) !== -1) {
_info('Doh! The following '+this.tagName.toLowerCase()+', is not supported.', this);
return true; // Equivalent to continue in a normal for loop.
}

Expand All @@ -91,7 +90,6 @@

// Make sure this form field has a label
if (_label.length === 0) {
_info('Doh! The following '+this.tagName.toLowerCase()+' has no related label.', this);
return true;
}

Expand Down Expand Up @@ -136,7 +134,9 @@

// Position the label.
_prepLabel = function(_field, _label) {
var opacity = 0;
var _charLimit,
_charLimitAttr = _field.data('slCharLimit'),
_opacity = 0;

// Handle drop down list labels differently
if (_field[0].tagName.match(/select/i)) {
Expand All @@ -149,18 +149,24 @@

_label.css('display','none');
} else {
// If we need to figure out the length automatically (and this field isn't specifically excluded),
// or if this field is specifically requesting this functionality.
if (_charLimitAttr === 'auto' || (defaults.autoCharLimit && isNaN(_charLimitAttr))) {
_approximateChars(_field, _label);
}

// If the field is empty, make the label fully opaque.
if (_noVal(_field)) {
opacity = 1;
// Otherwise, if the field is not empty, but below the character count (if any), use the passed in option.
} else if (_withinCharCount(_field)) {
opacity = defaults.opacity;
_opacity = 1;
// Otherwise, if the field is not empty, but below the character limit (if any), use the passed in option.
} else if (_withinCharLimit(_field)) {
_opacity = defaults._opacity;
}

_field.css({ zIndex:defaults.baseZindex+1 }).addClass('sl_field');
_label.css({
left:_noVal(_field) ? defaults.labelLeft : $(_field).width()-_label.width(),
opacity:opacity,
opacity:_opacity,
position:'absolute',
top:defaults.labelTop,
zIndex:defaults.baseZindex+2
Expand Down Expand Up @@ -225,7 +231,7 @@
}

// If the field is empty and the label isn't showing, make it show up again.
if ( (_noVal(this) && _label.css('opacity') !== 0) || _withinCharCount(this) ) {
if ( (_noVal(this) && _label.css('opacity') !== 0) || _withinCharLimit(this) ) {
_o = defaults.opacity;
}

Expand All @@ -235,24 +241,50 @@
/*===== Utility Functions =====*/
// Tell us whether the form field has a value.
_noVal = function(_el) { return $(_el).val() === ''; };
// Tell us whether the form field meets a given character count (if necessary)
_withinCharCount = function(_el) {
var count = $(_el).data('slCharLimit');
// Tell us whether the form field meets a given character limit (if necessary)
_withinCharLimit = function(_el) {
var _limit = $(_el).data('slCharLimit');

// Stop here if there's no need to check for number of characters.
if (!count || typeof count !== 'number') {
if (!_limit || typeof _limit !== 'number') {
return false;
}

// If this has a length property, we can assume this element is part of a
// jQuery object-like Array, thus: grab the DOM element from it.
_el = _el.length ? _el[0] : _el;

return count && _el.value && _el.value.length <= count;
return _limit && _el.value && _el.value.length <= _limit;
};
// Attempt to automatically set up the character limit and attach it to the field.
_approximateChars = function(_field, _label) {
var _available,
_charLen,
_chars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
_properties = ["font-family", "font-size", "font-weight", "letter-spacing", "line-height", "text-shadow", "text-transform"],
_tmp = $('<div>'+_chars+'</div>');

// Loop through each of the defined properties so that we can get the font looking the same size.
// I know this isn't too great for performance, but for now I don't know of a better way to do this.
// If you do know of a better way, please hit me with a pull request.
$.each(_properties, function(i, _prop) {
_tmp.css(_prop, _field.css(_prop));
});

// Console Functions (We need these to make sure this only displays when the console exists.)
_log = function() { if (defaults.debug && console && console.log) console.log.apply(console, arguments); };
_info = function() { if (defaults.debug && console && console.info) console.info.apply(console, arguments); };
_error = function() { if (defaults.debug && console && console.error) console.error.apply(console, arguments); };
_tmp.css({
'position':'absolute', // so it's out of the document flow.
'visibility':'hidden' // so that it's not visible, but still takes up space in the DOM so we can grab the width
});

$('body').append(_tmp);
// Get the average length *per character*
_charLen = Math.round(_tmp.width() / _chars.length);
// Remove our temporary div from the DOM.
_tmp.remove();

_available = _field.width() - _label.width();

// Set the data-sl-char-limit attribute for this field to our approximated value.
_field.data('slCharLimit', Math.floor(_available / _charLen));
};
})(jQuery);
4 changes: 2 additions & 2 deletions jquery.superLabels.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c7087bd

Please sign in to comment.