├── .gitattributes
├── .gitignore
├── CONTRIBUTING.md
├── Gruntfile.js
├── LICENSE.txt
├── README.md
├── bower.json
├── index.html
├── jquery.placeholder.js
├── jquery.placeholder.min.js
├── jquery.placeholder.min.js.map
├── package.json
├── simulated.html
└── tests
├── index.html
└── tests.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | * eol=lf
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | bower_components/
3 | node_modules/
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | #Found a bug?
2 |
3 | ###Please include the following when opening an issue:
4 |
5 | 1. jquery-placeholder version
6 | 2. jquery version
7 | 3. Browser vendor and versions where you are seeing the issue
8 | 4. Example code to reproduce the issue (using jsfiddle is best)
9 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(grunt) {
4 |
5 | // Get devDependencies
6 | require('load-grunt-tasks')(grunt, {scope: 'devDependencies'});
7 |
8 | // Displays the execution time of grunt tasks
9 | require('time-grunt')(grunt);
10 |
11 | // Config
12 | grunt.initConfig({
13 | pkg: grunt.file.readJSON('package.json'),
14 |
15 | // uglify
16 | uglify: {
17 | options: {
18 | sourceMap: true,
19 | compress: {
20 | drop_console: true,
21 | drop_debugger: true
22 | },
23 | banner: '/* <%= pkg.title %> - v<%= pkg.version %>\n' +
24 | ' * Copyright (c)<%= grunt.template.today("yyyy") %> Mathias Bynens\n' +
25 | ' * <%= grunt.template.today("yyyy-mm-dd") %>\n' +
26 | ' */'
27 | },
28 | minify : {
29 | files: {
30 | 'jquery.placeholder.min.js': ['jquery.placeholder.js']
31 | }
32 | }
33 | }
34 |
35 | });
36 |
37 | /**
38 | * Register own tasks by putting together existing ones
39 | */
40 |
41 | // Default task
42 | grunt.registerTask('default',
43 | ['uglify']
44 | );
45 |
46 | };
47 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright Mathias Bynens
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HTML5 Placeholder jQuery Plugin
2 |
3 | ## Demo & Examples
4 |
5 |
6 |
7 | ## Example Usage
8 |
9 | ### HTML
10 |
11 | ```html
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | ```
20 |
21 | ### jQuery
22 |
23 | Use the plugin as follows:
24 |
25 | ```js
26 | $('input, textarea').placeholder();
27 | ```
28 |
29 | By default, `.placeholder` css class will be added. You can override default by passing the `customClass` option:
30 | ```js
31 | $('input, textarea').placeholder({ customClass: 'my-placeholder' });
32 | ```
33 |
34 | You’ll still be able to use `jQuery.val()` to get and set the input values. If the element is currently showing a placeholder, `.val()` will return an empty string instead of the placeholder text, just like it does in browsers with a native `@placeholder` implementation. Calling `.val('')` to set an element’s value to the empty string will result in the placeholder text (re)appearing.
35 |
36 | ### CSS
37 |
38 | The plugin automatically adds `class="placeholder"` to the elements who are currently showing their placeholder text. You can use this to style placeholder text differently:
39 |
40 | ```css
41 | input, textarea { color: #000; }
42 | .placeholder { color: #aaa; }
43 | ```
44 |
45 | I’d suggest sticking to the `#aaa` color for placeholder text, as it’s the default in most browsers that support `@placeholder`. If you really want to, though, you can [style the placeholder text in some of the browsers that natively support it](https://stackoverflow.com/a/2610741/96656).
46 |
47 | ## Installation
48 |
49 | You can install jquery-placeholder by using [Bower](http://bower.io/).
50 |
51 | ```bash
52 | bower install jquery-placeholder
53 | ```
54 |
55 | Or you can install it through [npm](https://www.npmjs.com/):
56 |
57 | ```
58 | npm install --save jquery-placeholder
59 | ```
60 |
61 | Contributors should install the »dev dependencies« after forking and cloning via [npm](https://www.npmjs.com/).
62 |
63 | ```bash
64 | npm install
65 | ```
66 |
67 | ## Notes
68 |
69 | * Requires jQuery 1.6+. For an older version of this plugin that works under jQuery 1.4.2+, see [v1.8.7](https://github.com/mathiasbynens/jquery-placeholder/tree/v1.8.7).
70 | * Works in all A-grade browsers, including IE6.
71 | * Automatically checks if the browser natively supports the HTML5 `placeholder` attribute for `input` and `textarea` elements. If this is the case, the plugin won’t do anything. If `@placeholder` is only supported for `input` elements, the plugin will leave those alone and apply to `textarea`s exclusively. (This is the case for Safari 4, Opera 11.00, and possibly other browsers.)
72 | * Caches the results of its two feature tests in `jQuery.fn.placeholder.input` and `jQuery.fn.placeholder.textarea`. For example, if `@placeholder` is natively supported for `input` elements, `jQuery.fn.placeholder.input` will be `true`. After loading the plugin, you can re-use these properties in your own code.
73 | * Using ` ` will break the plugin functionality
74 | * Makes sure it never causes duplicate IDs in your DOM, even in browsers that need an extra `input` element to fake `@placeholder` for password inputs. This means you can safely do stuff like:
75 |
76 | ```html
77 | Example label
78 |
79 | ```
80 |
81 | And the `` will always point to the ` ` element you’d expect. Also, all CSS styles based on the ID will just work™.
82 |
83 | ## License
84 |
85 | This plugin is available under [the MIT license](http://mths.be/mit).
86 |
87 | ## Thanks to…
88 |
89 | * [Paul Irish](http://paulirish.com/) for his inspiring snippet in [jQuery 1.4 Hawtness #1](http://jquery14.com/day-05/jquery-1-4-hawtness-1-with-paul-irish)
90 | * everyone from [#jquery](http://webchat.freenode.net/?channels=jquery) for the tips, ideas and patches
91 | * anyone who [contributed a patch](https://github.com/mathiasbynens/jquery-placeholder/contributors) or [made a helpful suggestion](https://github.com/mathiasbynens/jquery-placeholder/issues)
92 |
93 | _– [Mathias](http://mathiasbynens.be/)_
94 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-placeholder",
3 | "description": "A jQuery plugin that enables HTML5 placeholder behavior for browsers that aren’t trying hard enough yet",
4 | "license": "MIT",
5 | "main": ["jquery.placeholder.js"],
6 | "keywords": [
7 | "form",
8 | "placeholder",
9 | "jQuery",
10 | "jquery-plugin"
11 | ],
12 | "dependencies": {
13 | "jquery": ">=1.6"
14 | },
15 | "ignore": [
16 | "*",
17 | "!/bower.json",
18 | "!/jquery.placeholder.js",
19 | "!/jquery.placeholder.min.js",
20 | "!/jquery.placeholder.min.js.map"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HTML5 placeholder jQuery Plugin
6 |
16 |
17 |
18 |
19 | HTML5 Placeholder jQuery Plugin
20 |
21 |
22 |
23 |
99 |
100 |
101 |
102 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/jquery.placeholder.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery Placeholder Plugin v2.3.1
3 | * https://github.com/mathiasbynens/jquery-placeholder
4 | *
5 | * Copyright 2011, 2015 Mathias Bynens
6 | * Released under the MIT license
7 | */
8 | (function(factory) {
9 | if (typeof define === 'function' && define.amd) {
10 | // AMD
11 | define(['jquery'], factory);
12 | } else if (typeof module === 'object' && module.exports) {
13 | factory(require('jquery'));
14 | } else {
15 | // Browser globals
16 | factory(jQuery);
17 | }
18 | }(function($) {
19 |
20 | /****
21 | * Allows plugin behavior simulation in modern browsers for easier debugging.
22 | * When setting to true, use attribute "placeholder-x" rather than the usual "placeholder" in your inputs/textareas
23 | * i.e.
24 | */
25 | var debugMode = false;
26 |
27 | // Opera Mini v7 doesn't support placeholder although its DOM seems to indicate so
28 | var isOperaMini = Object.prototype.toString.call(window.operamini) === '[object OperaMini]';
29 | var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini && !debugMode;
30 | var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini && !debugMode;
31 | var valHooks = $.valHooks;
32 | var propHooks = $.propHooks;
33 | var hooks;
34 | var placeholder;
35 | var settings = {};
36 |
37 | if (isInputSupported && isTextareaSupported) {
38 |
39 | placeholder = $.fn.placeholder = function() {
40 | return this;
41 | };
42 |
43 | placeholder.input = true;
44 | placeholder.textarea = true;
45 |
46 | } else {
47 |
48 | placeholder = $.fn.placeholder = function(options) {
49 |
50 | var defaults = {customClass: 'placeholder'};
51 | settings = $.extend({}, defaults, options);
52 |
53 | return this.filter((isInputSupported ? 'textarea' : ':input') + '[' + (debugMode ? 'placeholder-x' : 'placeholder') + ']')
54 | .not('.'+settings.customClass)
55 | .not(':radio, :checkbox, [type=hidden]')
56 | .bind({
57 | 'focus.placeholder': clearPlaceholder,
58 | 'blur.placeholder': setPlaceholder
59 | })
60 | .data('placeholder-enabled', true)
61 | .trigger('blur.placeholder');
62 | };
63 |
64 | placeholder.input = isInputSupported;
65 | placeholder.textarea = isTextareaSupported;
66 |
67 | hooks = {
68 | 'get': function(element) {
69 |
70 | var $element = $(element);
71 | var $passwordInput = $element.data('placeholder-password');
72 |
73 | if ($passwordInput) {
74 | return $passwordInput[0].value;
75 | }
76 |
77 | return $element.data('placeholder-enabled') && $element.hasClass(settings.customClass) ? '' : element.value;
78 | },
79 | 'set': function(element, value) {
80 |
81 | var $element = $(element);
82 | var $replacement;
83 | var $passwordInput;
84 |
85 | if (value !== '') {
86 |
87 | $replacement = $element.data('placeholder-textinput');
88 | $passwordInput = $element.data('placeholder-password');
89 |
90 | if ($replacement) {
91 | clearPlaceholder.call($replacement[0], true, value) || (element.value = value);
92 | $replacement[0].value = value;
93 |
94 | } else if ($passwordInput) {
95 | clearPlaceholder.call(element, true, value) || ($passwordInput[0].value = value);
96 | element.value = value;
97 | }
98 | }
99 |
100 | if (!$element.data('placeholder-enabled')) {
101 | element.value = value;
102 | return $element;
103 | }
104 |
105 | if (value === '') {
106 |
107 | element.value = value;
108 |
109 | // Setting the placeholder causes problems if the element continues to have focus.
110 | if (element != safeActiveElement()) {
111 | // We can't use `triggerHandler` here because of dummy text/password inputs :(
112 | setPlaceholder.call(element);
113 | }
114 |
115 | } else {
116 |
117 | if ($element.hasClass(settings.customClass)) {
118 | clearPlaceholder.call(element);
119 | }
120 |
121 | element.value = value;
122 | }
123 | // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
124 | return $element;
125 | }
126 | };
127 |
128 | if (!isInputSupported) {
129 | valHooks.input = hooks;
130 | propHooks.value = hooks;
131 | }
132 |
133 | if (!isTextareaSupported) {
134 | valHooks.textarea = hooks;
135 | propHooks.value = hooks;
136 | }
137 |
138 | $(function() {
139 | // Look for forms
140 | $(document).delegate('form', 'submit.placeholder', function() {
141 |
142 | // Clear the placeholder values so they don't get submitted
143 | var $inputs = $('.'+settings.customClass, this).each(function() {
144 | clearPlaceholder.call(this, true, '');
145 | });
146 |
147 | setTimeout(function() {
148 | $inputs.each(setPlaceholder);
149 | }, 10);
150 | });
151 | });
152 |
153 | // Clear placeholder values upon page reload
154 | $(window).bind('beforeunload.placeholder', function() {
155 |
156 | var clearPlaceholders = true;
157 |
158 | try {
159 | // Prevent IE javascript:void(0) anchors from causing cleared values
160 | if (document.activeElement.toString() === 'javascript:void(0)') {
161 | clearPlaceholders = false;
162 | }
163 | } catch (exception) { }
164 |
165 | if (clearPlaceholders) {
166 | $('.'+settings.customClass).each(function() {
167 | this.value = '';
168 | });
169 | }
170 | });
171 | }
172 |
173 | function args(elem) {
174 | // Return an object of element attributes
175 | var newAttrs = {};
176 | var rinlinejQuery = /^jQuery\d+$/;
177 |
178 | $.each(elem.attributes, function(i, attr) {
179 | if (attr.specified && !rinlinejQuery.test(attr.name)) {
180 | newAttrs[attr.name] = attr.value;
181 | }
182 | });
183 |
184 | return newAttrs;
185 | }
186 |
187 | function clearPlaceholder(event, value) {
188 |
189 | var input = this;
190 | var $input = $(this);
191 |
192 | if (input.value === $input.attr((debugMode ? 'placeholder-x' : 'placeholder')) && $input.hasClass(settings.customClass)) {
193 |
194 | input.value = '';
195 | $input.removeClass(settings.customClass);
196 |
197 | if ($input.data('placeholder-password')) {
198 |
199 | $input = $input.hide().nextAll('input[type="password"]:first').show().attr('id', $input.removeAttr('id').data('placeholder-id'));
200 |
201 | // If `clearPlaceholder` was called from `$.valHooks.input.set`
202 | if (event === true) {
203 | $input[0].value = value;
204 |
205 | return value;
206 | }
207 |
208 | $input.focus();
209 |
210 | } else {
211 | input == safeActiveElement() && input.select();
212 | }
213 | }
214 | }
215 |
216 | function setPlaceholder(event) {
217 | var $replacement;
218 | var input = this;
219 | var $input = $(this);
220 | var id = input.id;
221 |
222 | // If the placeholder is activated, triggering blur event (`$input.trigger('blur')`) should do nothing.
223 | if (event && event.type === 'blur' && $input.hasClass(settings.customClass)) {
224 | return;
225 | }
226 |
227 | if (input.value === '') {
228 | if (input.type === 'password') {
229 | if (!$input.data('placeholder-textinput')) {
230 |
231 | try {
232 | $replacement = $input.clone().prop({ 'type': 'text' });
233 | } catch(e) {
234 | $replacement = $(' ').attr($.extend(args(this), { 'type': 'text' }));
235 | }
236 |
237 | $replacement
238 | .removeAttr('name')
239 | .data({
240 | 'placeholder-enabled': true,
241 | 'placeholder-password': $input,
242 | 'placeholder-id': id
243 | })
244 | .bind('focus.placeholder', clearPlaceholder);
245 |
246 | $input
247 | .data({
248 | 'placeholder-textinput': $replacement,
249 | 'placeholder-id': id
250 | })
251 | .before($replacement);
252 | }
253 |
254 | input.value = '';
255 | $input = $input.removeAttr('id').hide().prevAll('input[type="text"]:first').attr('id', $input.data('placeholder-id')).show();
256 |
257 | } else {
258 |
259 | var $passwordInput = $input.data('placeholder-password');
260 |
261 | if ($passwordInput) {
262 | $passwordInput[0].value = '';
263 | $input.attr('id', $input.data('placeholder-id')).show().nextAll('input[type="password"]:last').hide().removeAttr('id');
264 | }
265 | }
266 |
267 | $input.addClass(settings.customClass);
268 | $input[0].value = $input.attr((debugMode ? 'placeholder-x' : 'placeholder'));
269 |
270 | } else {
271 | $input.removeClass(settings.customClass);
272 | }
273 | }
274 |
275 | function safeActiveElement() {
276 | // Avoid IE9 `document.activeElement` of death
277 | try {
278 | return document.activeElement;
279 | } catch (exception) {}
280 | }
281 | }));
282 |
--------------------------------------------------------------------------------
/jquery.placeholder.min.js:
--------------------------------------------------------------------------------
1 | /* HTML5 Placeholder jQuery Plugin - v2.3.1
2 | * Copyright (c)2015 Mathias Bynens
3 | * 2015-12-16
4 | */
5 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof module&&module.exports?require("jquery"):jQuery)}(function(a){function b(b){var c={},d=/^jQuery\d+$/;return a.each(b.attributes,function(a,b){b.specified&&!d.test(b.name)&&(c[b.name]=b.value)}),c}function c(b,c){var d=this,f=a(this);if(d.value===f.attr(h?"placeholder-x":"placeholder")&&f.hasClass(n.customClass))if(d.value="",f.removeClass(n.customClass),f.data("placeholder-password")){if(f=f.hide().nextAll('input[type="password"]:first').show().attr("id",f.removeAttr("id").data("placeholder-id")),b===!0)return f[0].value=c,c;f.focus()}else d==e()&&d.select()}function d(d){var e,f=this,g=a(this),i=f.id;if(!d||"blur"!==d.type||!g.hasClass(n.customClass))if(""===f.value){if("password"===f.type){if(!g.data("placeholder-textinput")){try{e=g.clone().prop({type:"text"})}catch(j){e=a(" ").attr(a.extend(b(this),{type:"text"}))}e.removeAttr("name").data({"placeholder-enabled":!0,"placeholder-password":g,"placeholder-id":i}).bind("focus.placeholder",c),g.data({"placeholder-textinput":e,"placeholder-id":i}).before(e)}f.value="",g=g.removeAttr("id").hide().prevAll('input[type="text"]:first').attr("id",g.data("placeholder-id")).show()}else{var k=g.data("placeholder-password");k&&(k[0].value="",g.attr("id",g.data("placeholder-id")).show().nextAll('input[type="password"]:last').hide().removeAttr("id"))}g.addClass(n.customClass),g[0].value=g.attr(h?"placeholder-x":"placeholder")}else g.removeClass(n.customClass)}function e(){try{return document.activeElement}catch(a){}}var f,g,h=!1,i="[object OperaMini]"===Object.prototype.toString.call(window.operamini),j="placeholder"in document.createElement("input")&&!i&&!h,k="placeholder"in document.createElement("textarea")&&!i&&!h,l=a.valHooks,m=a.propHooks,n={};j&&k?(g=a.fn.placeholder=function(){return this},g.input=!0,g.textarea=!0):(g=a.fn.placeholder=function(b){var e={customClass:"placeholder"};return n=a.extend({},e,b),this.filter((j?"textarea":":input")+"["+(h?"placeholder-x":"placeholder")+"]").not("."+n.customClass).not(":radio, :checkbox, [type=hidden]").bind({"focus.placeholder":c,"blur.placeholder":d}).data("placeholder-enabled",!0).trigger("blur.placeholder")},g.input=j,g.textarea=k,f={get:function(b){var c=a(b),d=c.data("placeholder-password");return d?d[0].value:c.data("placeholder-enabled")&&c.hasClass(n.customClass)?"":b.value},set:function(b,f){var g,h,i=a(b);return""!==f&&(g=i.data("placeholder-textinput"),h=i.data("placeholder-password"),g?(c.call(g[0],!0,f)||(b.value=f),g[0].value=f):h&&(c.call(b,!0,f)||(h[0].value=f),b.value=f)),i.data("placeholder-enabled")?(""===f?(b.value=f,b!=e()&&d.call(b)):(i.hasClass(n.customClass)&&c.call(b),b.value=f),i):(b.value=f,i)}},j||(l.input=f,m.value=f),k||(l.textarea=f,m.value=f),a(function(){a(document).delegate("form","submit.placeholder",function(){var b=a("."+n.customClass,this).each(function(){c.call(this,!0,"")});setTimeout(function(){b.each(d)},10)})}),a(window).bind("beforeunload.placeholder",function(){var b=!0;try{"javascript:void(0)"===document.activeElement.toString()&&(b=!1)}catch(c){}b&&a("."+n.customClass).each(function(){this.value=""})}))});
--------------------------------------------------------------------------------
/jquery.placeholder.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["jquery.placeholder.js"],"names":["factory","define","amd","module","exports","require","jQuery","$","args","elem","newAttrs","rinlinejQuery","each","attributes","i","attr","specified","test","name","value","clearPlaceholder","event","input","this","$input","debugMode","hasClass","settings","customClass","removeClass","data","hide","nextAll","show","removeAttr","focus","safeActiveElement","select","setPlaceholder","$replacement","id","type","clone","prop","e","extend","placeholder-enabled","placeholder-password","placeholder-id","bind","placeholder-textinput","before","prevAll","$passwordInput","addClass","document","activeElement","exception","hooks","placeholder","isOperaMini","Object","prototype","toString","call","window","operamini","isInputSupported","createElement","isTextareaSupported","valHooks","propHooks","fn","textarea","options","defaults","filter","not","focus.placeholder","blur.placeholder","trigger","get","element","$element","set","delegate","$inputs","setTimeout","clearPlaceholders"],"mappings":"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","file":"jquery.placeholder.min.js"}
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-placeholder",
3 | "version": "2.3.1",
4 | "title": "HTML5 Placeholder jQuery Plugin",
5 | "description": "A jQuery plugin that enables HTML5 placeholder behavior for browsers that aren’t trying hard enough yet",
6 | "author": {
7 | "name": "Mathias Bynens",
8 | "url": "https://mathiasbynens.be/"
9 | },
10 | "license": "MIT",
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/mathiasbynens/jquery-placeholder.git"
14 | },
15 | "homepage": "https://github.com/mathiasbynens/jquery-placeholder",
16 | "bugs": {
17 | "url": "https://github.com/mathiasbynens/jquery-placeholder/issues"
18 | },
19 | "main": "jquery.placeholder.js",
20 | "files": [ "jquery.placeholder.js" ],
21 | "directories": {
22 | "test": "tests"
23 | },
24 | "keywords": [
25 | "form",
26 | "placeholder",
27 | "jQuery",
28 | "jquery-plugin"
29 | ],
30 | "peerDependencies": {
31 | "jquery": "*"
32 | },
33 | "devDependencies": {
34 | "grunt": "^0.4.5",
35 | "grunt-contrib-uglify": "^0.7.0",
36 | "grunt-notify": "^0.4.1",
37 | "load-grunt-tasks": "^2.0.0",
38 | "time-grunt": "^1.0.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/simulated.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HTML5 placeholder jQuery Plugin
6 |
16 |
17 |
18 |
19 | HTML5 Placeholder jQuery Plugin
20 |
21 |
22 |
23 |
24 | Red
25 | Green
26 |
27 |
28 |
29 | Apple
30 | Banana
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | A Label: Click me to focus password field up above
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jquery-placeholder test suite
6 |
7 |
11 |
12 |
13 |
14 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/tests/tests.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 |
3 | QUnit.module('jQuery#placeholder');
4 |
5 | var test = QUnit.test;
6 |
7 | test('caches results of feature tests', function(assert) {
8 | assert.strictEqual(typeof $.fn.placeholder.input, 'boolean', '$.fn.placeholder.input');
9 | assert.strictEqual(typeof $.fn.placeholder.textarea, 'boolean', '$.fn.placeholder.textarea');
10 | });
11 |
12 | if ($.fn.placeholder.input && $.fn.placeholder.textarea) {
13 | return;
14 | }
15 |
16 | var testElement = function($el, assert) {
17 |
18 | var el = $el[0];
19 | var placeholder = el.getAttribute('placeholder');
20 |
21 | deepEqual($el.placeholder(), $el, 'should be chainable');
22 |
23 | assert.strictEqual(el.value, placeholder, 'should set `placeholder` text as `value`');
24 | assert.strictEqual($el.prop('value'), '', 'propHooks works properly');
25 | assert.strictEqual($el.val(), '', 'valHooks works properly');
26 | ok($el.hasClass('placeholder'), 'should have `placeholder` class');
27 |
28 | // test on focus
29 | $el.focus();
30 | assert.strictEqual(el.value, '', '`value` should be the empty string on focus');
31 | assert.strictEqual($el.prop('value'), '', 'propHooks works properly');
32 | assert.strictEqual($el.val(), '', 'valHooks works properly');
33 | ok(!$el.hasClass('placeholder'), 'should not have `placeholder` class on focus');
34 |
35 | // and unfocus (blur) again
36 | $el.blur();
37 |
38 | assert.strictEqual(el.value, placeholder, 'should set `placeholder` text as `value`');
39 | assert.strictEqual($el.prop('value'), '', 'propHooks works properly');
40 | assert.strictEqual($el.val(), '', 'valHooks works properly');
41 | ok($el.hasClass('placeholder'), 'should have `placeholder` class');
42 |
43 | // change the value
44 | $el.val('lorem ipsum');
45 | assert.strictEqual($el.prop('value'), 'lorem ipsum', '`$el.val(string)` should change the `value` property');
46 | assert.strictEqual(el.value, 'lorem ipsum', '`$el.val(string)` should change the `value` attribute');
47 | ok(!$el.hasClass('placeholder'), '`$el.val(string)` should remove `placeholder` class');
48 |
49 | // and clear it again
50 | $el.val('');
51 | assert.strictEqual($el.prop('value'), '', '`$el.val("")` should change the `value` property');
52 | assert.strictEqual(el.value, placeholder, '`$el.val("")` should change the `value` attribute');
53 | ok($el.hasClass('placeholder'), '`$el.val("")` should re-enable `placeholder` class');
54 |
55 | // make sure the placeholder property works as expected.
56 | assert.strictEqual($el.prop('placeholder'), placeholder, '$el.prop(`placeholder`) should return the placeholder value');
57 | $el.prop('placeholder', 'new placeholder');
58 | assert.strictEqual($el.prop('placeholder'), 'new placeholder', '$el.prop(`placeholder`, ) should set the placeholder value');
59 | assert.strictEqual($el.value, 'new placeholder', '$el.prop(`placeholder`, ) should update the displayed placeholder value');
60 | $el.prop('placeholder', placeholder);
61 | };
62 |
63 | test('emulates placeholder for ', function(assert) {
64 | testElement( assert, $('#input-type-text') );
65 | });
66 |
67 | test('emulates placeholder for ', function(assert) {
68 | testElement( assert, $('#input-type-search') );
69 | });
70 |
71 | test('emulates placeholder for ', function(assert) {
72 | testElement( assert, $('#input-type-email') );
73 | });
74 |
75 | test('emulates placeholder for ', function(assert) {
76 | testElement( assert, $('#input-type-url') );
77 | });
78 |
79 | test('emulates placeholder for ', function(assert) {
80 | testElement( assert, $('#input-type-tel') );
81 | });
82 |
83 | test('emulates placeholder for ', function(assert) {
84 | testElement( assert, $('#input-type-tel') );
85 | });
86 |
87 | test('emulates placeholder for ', function(assert) {
88 | var selector = '#input-type-password';
89 |
90 | var $el = $(selector);
91 | var el = $el[0];
92 |
93 | var placeholder = el.getAttribute('placeholder');
94 |
95 | assert.strictEqual($el.placeholder(), $el, 'should be chainable');
96 |
97 | // Re-select the element, as it gets replaced by another one in some browsers
98 | $el = $(selector);
99 | el = $el[0];
100 |
101 | assert.strictEqual(el.value, placeholder, 'should set `placeholder` text as `value`');
102 | assert.strictEqual($el.prop('value'), '', 'propHooks works properly');
103 | assert.strictEqual($el.val(), '', 'valHooks works properly');
104 | ok($el.hasClass('placeholder'), 'should have `placeholder` class');
105 |
106 | // test on focus
107 | $el.focus();
108 |
109 | // Re-select the element, as it gets replaced by another one in some browsers
110 | $el = $(selector);
111 | el = $el[0];
112 |
113 | assert.strictEqual(el.value, '', '`value` should be the empty string on focus');
114 | assert.strictEqual($el.prop('value'), '', 'propHooks works properly');
115 | assert.strictEqual($el.val(), '', 'valHooks works properly');
116 | ok(!$el.hasClass('placeholder'), 'should not have `placeholder` class on focus');
117 |
118 | // and unfocus (blur) again
119 | $el.blur();
120 |
121 | // Re-select the element, as it gets replaced by another one in some browsers
122 | $el = $(selector);
123 | el = $el[0];
124 |
125 | assert.strictEqual(el.value, placeholder, 'should set `placeholder` text as `value`');
126 | assert.strictEqual($el.prop('value'), '', 'propHooks works properly');
127 | assert.strictEqual($el.val(), '', 'valHooks works properly');
128 | ok($el.hasClass('placeholder'), 'should have `placeholder` class');
129 |
130 | });
131 |
132 | test('emulates placeholder for ', function(assert) {
133 | testElement( assert, $('#textarea') );
134 | });
135 |
136 | }(jQuery));
137 |
--------------------------------------------------------------------------------