291 lines
6.9 KiB
JavaScript
291 lines
6.9 KiB
JavaScript
(function($) {
|
|
|
|
/**
|
|
* Apply "placeholder" attribute polyfill to one or more forms.
|
|
* @return {jQuery} jQuery object.
|
|
*/
|
|
$.fn.placeholder = function() {
|
|
|
|
// Browser natively supports placeholders? Bail.
|
|
if (typeof (document.createElement('input')).placeholder != 'undefined')
|
|
return $(this);
|
|
|
|
// No elements?
|
|
if (this.length == 0)
|
|
return $this;
|
|
|
|
// Multiple elements?
|
|
if (this.length > 1) {
|
|
|
|
for (var i=0; i < this.length; i++)
|
|
$(this[i]).placeholder();
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
// Vars.
|
|
var $this = $(this);
|
|
|
|
// Text, TextArea.
|
|
$this.find('input[type=text],textarea')
|
|
.each(function() {
|
|
|
|
var i = $(this);
|
|
|
|
if (i.val() == ''
|
|
|| i.val() == i.attr('placeholder'))
|
|
i
|
|
.addClass('polyfill-placeholder')
|
|
.val(i.attr('placeholder'));
|
|
|
|
})
|
|
.on('blur', function() {
|
|
|
|
var i = $(this);
|
|
|
|
if (i.attr('name').match(/-polyfill-field$/))
|
|
return;
|
|
|
|
if (i.val() == '')
|
|
i
|
|
.addClass('polyfill-placeholder')
|
|
.val(i.attr('placeholder'));
|
|
|
|
})
|
|
.on('focus', function() {
|
|
|
|
var i = $(this);
|
|
|
|
if (i.attr('name').match(/-polyfill-field$/))
|
|
return;
|
|
|
|
if (i.val() == i.attr('placeholder'))
|
|
i
|
|
.removeClass('polyfill-placeholder')
|
|
.val('');
|
|
|
|
});
|
|
|
|
// Password.
|
|
$this.find('input[type=password]')
|
|
.each(function() {
|
|
|
|
var i = $(this);
|
|
var x = $(
|
|
$('<div>')
|
|
.append(i.clone())
|
|
.remove()
|
|
.html()
|
|
.replace(/type="password"/i, 'type="text"')
|
|
.replace(/type=password/i, 'type=text')
|
|
);
|
|
|
|
if (i.attr('id') != '')
|
|
x.attr('id', i.attr('id') + '-polyfill-field');
|
|
|
|
if (i.attr('name') != '')
|
|
x.attr('name', i.attr('name') + '-polyfill-field');
|
|
|
|
x.addClass('polyfill-placeholder')
|
|
.val(x.attr('placeholder')).insertAfter(i);
|
|
|
|
if (i.val() == '')
|
|
i.hide();
|
|
else
|
|
x.hide();
|
|
|
|
i
|
|
.on('blur', function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
|
|
|
|
if (i.val() == '') {
|
|
|
|
i.hide();
|
|
x.show();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
x
|
|
.on('focus', function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
|
|
|
|
x.hide();
|
|
|
|
i
|
|
.show()
|
|
.focus();
|
|
|
|
})
|
|
.on('keypress', function(event) {
|
|
|
|
event.preventDefault();
|
|
x.val('');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// Events.
|
|
$this
|
|
.on('submit', function() {
|
|
|
|
$this.find('input[type=text],input[type=password],textarea')
|
|
.each(function(event) {
|
|
|
|
var i = $(this);
|
|
|
|
if (i.attr('name').match(/-polyfill-field$/))
|
|
i.attr('name', '');
|
|
|
|
if (i.val() == i.attr('placeholder')) {
|
|
|
|
i.removeClass('polyfill-placeholder');
|
|
i.val('');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
})
|
|
.on('reset', function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
$this.find('select')
|
|
.val($('option:first').val());
|
|
|
|
$this.find('input,textarea')
|
|
.each(function() {
|
|
|
|
var i = $(this),
|
|
x;
|
|
|
|
i.removeClass('polyfill-placeholder');
|
|
|
|
switch (this.type) {
|
|
|
|
case 'submit':
|
|
case 'reset':
|
|
break;
|
|
|
|
case 'password':
|
|
i.val(i.attr('defaultValue'));
|
|
|
|
x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
|
|
|
|
if (i.val() == '') {
|
|
i.hide();
|
|
x.show();
|
|
}
|
|
else {
|
|
i.show();
|
|
x.hide();
|
|
}
|
|
|
|
break;
|
|
|
|
case 'checkbox':
|
|
case 'radio':
|
|
i.attr('checked', i.attr('defaultValue'));
|
|
break;
|
|
|
|
case 'text':
|
|
case 'textarea':
|
|
i.val(i.attr('defaultValue'));
|
|
|
|
if (i.val() == '') {
|
|
i.addClass('polyfill-placeholder');
|
|
i.val(i.attr('placeholder'));
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
i.val(i.attr('defaultValue'));
|
|
break;
|
|
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
return $this;
|
|
|
|
};
|
|
|
|
/**
|
|
* Moves elements to/from the first positions of their respective parents.
|
|
* @param {jQuery} $elements Elements (or selector) to move.
|
|
* @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
|
|
*/
|
|
$.prioritize = function($elements, condition) {
|
|
|
|
var key = '__prioritize';
|
|
|
|
// Expand $elements if it's not already a jQuery object.
|
|
if (typeof $elements != 'jQuery')
|
|
$elements = $($elements);
|
|
|
|
// Step through elements.
|
|
$elements.each(function() {
|
|
|
|
var $e = $(this), $p,
|
|
$parent = $e.parent();
|
|
|
|
// No parent? Bail.
|
|
if ($parent.length == 0)
|
|
return;
|
|
|
|
// Not moved? Move it.
|
|
if (!$e.data(key)) {
|
|
|
|
// Condition is false? Bail.
|
|
if (!condition)
|
|
return;
|
|
|
|
// Get placeholder (which will serve as our point of reference for when this element needs to move back).
|
|
$p = $e.prev();
|
|
|
|
// Couldn't find anything? Means this element's already at the top, so bail.
|
|
if ($p.length == 0)
|
|
return;
|
|
|
|
// Move element to top of parent.
|
|
$e.prependTo($parent);
|
|
|
|
// Mark element as moved.
|
|
$e.data(key, $p);
|
|
|
|
}
|
|
|
|
// Moved already?
|
|
else {
|
|
|
|
// Condition is true? Bail.
|
|
if (condition)
|
|
return;
|
|
|
|
$p = $e.data(key);
|
|
|
|
// Move element back to its original location (using our placeholder).
|
|
$e.insertAfter($p);
|
|
|
|
// Unmark element as moved.
|
|
$e.removeData(key);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
})(jQuery); |