Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,22 @@
<input type="text" placeholder="Username">
<input type="text" placeholder="Required" required>
<input type="text" placeholder="Has ID" id="testid">
<input type="text" placeholder="Has ID" value='ll'>
<select name="my_select" title='My select'>
<option value="" selected> My select </option>
<option value="01">AA</option>
<option value="02">BB</option>
</select>
<div class='jvFloat'>
<!-- i have a correct html model -->
<label class=''></label>
<input type="text" placeholder="Has ID" id="testid">
</div>
<textarea placeholder="Textarea!"></textarea>
<textarea placeholder="Textarea with id!" id="textarea"></textarea>
<input type="submit">
</body>
<script>
$('input, textarea').jvFloat();
$('input, textarea, select').jvFloat();
</script>
</html>
</html>
4 changes: 4 additions & 0 deletions jvfloat.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
transition: transform 100ms, opacity 120ms, visibility 120ms;
opacity: 1;
}
.jvFloat .placeHolder.visible {
color: #333333;
}

/* End CSS3 */

/* Legacy browser */
Expand Down
125 changes: 72 additions & 53 deletions jvfloat.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,92 @@
* modified on: 18/09/2014
*/

(function($) {
(function _jv_float_module($, window) {
'use strict';


var namespace = 'jv_float';

// Init Plugin Functions
$.fn.jvFloat = function () {
$.fn.jvFloat = function _jv_float_plugin() {
// Check input type - filter submit buttons.
return this.filter('input:not([type=submit]), textarea, select').each(function() {
function getPlaceholderText($el) {
var text = $el.attr('placeholder');
return this.each(function _jv_float_each() {
// create basic variables
var
$el = $(this),
el = $el[0]; // native element

if (typeof text == 'undefined') {
text = $el.attr('title');
}
// use tagName to define supported elements, if unsuported, break
if (!(~['INPUT', 'TEXTAREA', 'SELECT'].indexOf(el.tagName)) || el.getAttribute('type') == 'submit') {
return false;
}

// fix properties
generate_id();

// generate complete base structure
var
$parent = $el.parent('div.jvFloat'),
$label = $parent.find('label.placeHolder[for="' + el.getAttribute('id') + '"]'),
placeholder = el.getAttribute("placeholder") || el.getAttribute("title"), // get placeholder with native function
// added `required` input detection and state
required = el.getAttribute('required') || '';

return text;
// if parent div don't exists, create it
if ($parent.length == 0) {
// Wrap the input in div.jvFloat
$parent = $el.wrap('<div class=jvFloat>').parent('.jvFloat');
}
function setState () {

// if label for element don't exists, create it
if ($label.length == 0) {

// adds a different class tag for text areas (.jvFloat .placeHolder.textarea)
// to allow better positioning of the element for multiline text area inputs
$label = $('<label>', {
"class": 'placeHolder ' + (el.tagName == 'TEXTAREA' ? 'textarea' : '') + required,
"for": el.getAttribute('id'),
"text": placeholder
});

$parent.prepend($label);

}


function setState(ev) {
// change span.placeHolder to span.placeHolder.active
var currentValue = $el.val();
var currentValue = $el.val() || '',
toggle = currentValue !== '';

if (currentValue == null) {
currentValue = '';
}
else if ($el.is('select')) {
var placeholderValue = getPlaceholderText($el);
if (ev && ev.type == 'blur' || !ev) {
$label.toggleClass('visible', toggle);
} else if (ev.type == 'keyup') {
$label.removeClass('visible');

if (placeholderValue == currentValue) {
currentValue = '';
}
}

placeholder.toggleClass('active', currentValue !== '');
}
function generateUIDNotMoreThan1million () {
var id = '';
do {
id = ('0000' + (Math.random()*Math.pow(36,4) << 0).toString(36)).substr(-4);
} while (!!$('#' + id).length);
return id;
$label.toggleClass('active', toggle);
}
function createIdOnElement($el) {
var id = generateUIDNotMoreThan1million();
$el.prop('id', id);
return id;
}
// Wrap the input in div.jvFloat
var $el = $(this).wrap('<div class=jvFloat>');
var forId = $el.attr('id');
if (!forId) { forId = createIdOnElement($el);}
// Store the placeholder text in span.placeHolder
// added `required` input detection and state
var required = $el.attr('required') || '';

// adds a different class tag for text areas (.jvFloat .placeHolder.textarea)
// to allow better positioning of the element for multiline text area inputs
var placeholder = '';
var placeholderText = getPlaceholderText($el);

if ($(this).is('textarea')) {
placeholder = $('<label class="placeHolder ' + ' textarea ' + required + '" for="' + forId + '">' + placeholderText + '</label>').insertBefore($el);
} else {
placeholder = $('<label class="placeHolder ' + required + '" for="' + forId + '">' + placeholderText + '</label>').insertBefore($el);

/**
* Generate a unique id if element not has one
*/
function generate_id() {

if (!el.getAttribute('id')) {

// if window don't have UUID, create with 1, else append one each time
!('JVFLOAT_UUID' in window) ? window.JVFLOAT_UUID = 1 : window.JVFLOAT_UUID += 1;

el.setAttribute('id', [namespace, window.JVFLOAT_UUID].join('__'));

}
}

// checks to see if inputs are pre-populated and adds active to span.placeholder
setState();
$el.bind('keyup blur', setState);
$el.bind('keyup blur change', setState);
});
};
// Make Zeptojs & jQuery Compatible
})(window.jQuery || window.Zepto || window.$);
// Make Zeptojs & jQuery Compatible
})(window.jQuery || window.Zepto, window);