1/*! 2* jQuery Placeholder Enhanced 1.5 3* Copyright (c) 2013 Denis Ciccale (@tdecs) 4* Released under MIT license (https://raw.github.com/dciccale/placeholder-enhanced/master/LICENSE.txt) 5*/ 6(function ($) { 7 8 var pluginName = 'placeholderEnhanced', 9 // if browser supports placeholder attribute, use native events to show/hide placeholder 10 hasNativeSupport = 'placeholder' in document.createElement('input') && 'placeholder' in document.createElement('textarea'), 11 // events namespaces 12 event = { 13 focus: 'focus.placeholder', 14 blur: 'blur.placeholder', 15 submit: 'submit.placeholder' 16 }, 17 // placeholder css class 18 placeholderCssClass = 'placeholder', 19 $val; 20 21 // if placeholder is not supported, the jQuery val function returns the placeholder 22 // wrap the val function to fix this 23 if (!hasNativeSupport) { 24 $val = $.fn.val; 25 $.fn.val = function () { 26 var el = this[0]; 27 if (!this.length) { 28 return; 29 } 30 if (!arguments.length && (el.nodeName === 'INPUT' || el.nodeName === 'TEXTAREA')) { 31 return el.value === this.attr('placeholder') ? '' : el.value; 32 33 } else { 34 if (this.hasClass(placeholderCssClass)) { 35 this.removeClass(placeholderCssClass); 36 } 37 return $val.apply(this, arguments); 38 } 39 }; 40 } 41 42 $.fn[pluginName] = function () { 43 44 // don't do anything with an empty collection 45 if (!this.length) { 46 return; 47 } 48 49 // ensure not sending placeholder value when placeholder is not supported 50 if (!hasNativeSupport) { 51 // filter forms to leave only the ones that submit event was not added yet 52 $('form') 53 // only grab forms that are not prepared 54 .filter(function () { 55 return !$.data(this, pluginName); 56 }) 57 .each(function () { 58 // bind submit event 59 $(this).bind(event.submit, function () { 60 // empty input value if it's the same as the placeholder attribute 61 $(this).find('input[placeholder], textarea[placeholder]').each(function () { 62 if (!$(this).val() && !this.disabled) { 63 this.value = ''; 64 } 65 }); 66 }); 67 // mark as prepared 68 $.data(this, pluginName, true); 69 }); 70 } 71 72 // copy attributes from a DOM node to a plain object to use later 73 function copyAttrs(element) { 74 var attrs = {}, exclude = ['placeholder', 'name', 'id']; 75 $.each(element.attributes, function (i, attr) { 76 if (attr.specified && $.inArray(attr.name, exclude) < 0) { 77 attrs[attr.name] = attr.value; 78 } 79 }); 80 return attrs; 81 } 82 83 // hides specified input 84 function hideInput($input) { 85 $input.css({ position: 'absolute', left: '-9999em' }); 86 } 87 88 // shows specified input 89 function showInput($input) { 90 $input.css({ position: '', left: '' }); 91 } 92 93 94 return this.each(function () { 95 96 // check if plugin already initialized 97 if ($.data(this, pluginName)) { 98 return; 99 } 100 101 var el = this, 102 $el = $(el), 103 placeholderTxt = $el.attr('placeholder'), 104 isPassword = (el.type === 'password'), 105 fakePassw, 106 setPlaceholder, 107 removePlaceholder; 108 109 // on blur set placeholder 110 setPlaceholder = function () { 111 // if there is no initial value 112 // or initial value is equal to placeholder (done in the fn.val wrapper) 113 // init the placeholder 114 if (!$el.val()) { 115 if (!hasNativeSupport) { 116 if (!isPassword) { 117 $el.val(placeholderTxt).addClass(placeholderCssClass); 118 } else { 119 showInput(fakePassw); 120 hideInput($el); 121 } 122 } else { 123 $el.addClass(placeholderCssClass); 124 } 125 } 126 }; 127 128 // on focus remove placeholder 129 if (!isPassword || hasNativeSupport) { 130 // for non-password inputs and textareas 131 removePlaceholder = function () { 132 if ($el.hasClass(placeholderCssClass)) { 133 if (!hasNativeSupport) { 134 el.value = ''; 135 } 136 $el.removeClass(placeholderCssClass); 137 } 138 }; 139 140 // for password inputs 141 } else if (!hasNativeSupport) { 142 removePlaceholder = function () { 143 showInput($el); 144 hideInput(fakePassw); 145 }; 146 147 // create a fake password input 148 fakePassw = $('<input>', $.extend(copyAttrs(el), { 149 'type': 'text', 150 value: placeholderTxt, 151 tabindex: -1 // skip tabbing 152 })) 153 // add placeholder class 154 .addClass(placeholderCssClass) 155 // when fake input has focus, trigger real input focus 156 .bind(event.focus, function () { 157 $el.trigger(event.focus); 158 }) 159 // insert fake input 160 .insertBefore($el); 161 } 162 163 // bind events and trigger blur the first time 164 $el 165 .bind(event.blur, setPlaceholder) 166 .bind(event.focus, removePlaceholder) 167 .trigger(event.blur); 168 169 // mark plugin as initialized for current element 170 $.data(el, pluginName, true); 171 }); 172 }; 173 174 // auto-initialize the plugin 175 $(function () { 176 $('input[placeholder], textarea[placeholder]')[pluginName](); 177 });
178}(jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.