From 7327915650758b27570cd66fb7da16392a000aa4 Mon Sep 17 00:00:00 2001 From: cdaringe Date: Wed, 18 Feb 2015 22:56:37 +0200 Subject: [PATCH 1/6] (1) Demo (2) Add label application configurations (3) Supporting test (4) Fix package.json repo --- .gitignore | 1 + README.md | 9 +- ampersand-floatinglabel-input-view.js | 33 +- demo/demo.html | 76 +++++ demo/demo.js | 79 +++++ demo/normalize.css | 427 ++++++++++++++++++++++++++ package.json | 13 +- test/index.js | 19 +- 8 files changed, 647 insertions(+), 10 deletions(-) create mode 100644 demo/demo.html create mode 100644 demo/demo.js create mode 100644 demo/normalize.css diff --git a/.gitignore b/.gitignore index 8f3346a..051a307 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules +.npmrc .tmp .DS_Store Thumbs.db diff --git a/README.md b/README.md index b566b87..05f4ee7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A simple ampersand input view extension to enable the [floating label pattern](h This extension will: -- Dynamically provide a `floating` class on the `[data-hook="label"]` element for styling a floating label +- Dynamically provide a `floating` class on the `[data-hook="label"]` element for styling a floating label. Overridable by supplying option `labelClass: 'your other classes'` - Check if the input already has a value and float the label - Check if the input has a value as the user types and dynamically float the label @@ -77,10 +77,17 @@ module.exports = AmpersandView.extend({ ## API reference +### options +Options are passed into the ViewConstructor + +`labelClass` - *default: 'floating'*, applies 'yourClass' or 'yourClass andYourOtherClassToo' to data-hooked `label` element +`template` - if attribute `data-hook="label-container"` is found, `labelClass` will be applied to it instead of `data-hook="label"` + See [ampersand-input-view](https://github.com/ampersandjs/ampersand-input-view#api-reference) for the api reference. ## changelog +- 1.0.1 - Permit overridable class(es) for label. Add demo. Rev input version req - 1.0.0 - Added tests to make sure everything worked well - 0.2.0 - Added input-invalid class to the label when the input is invalid - 0.1.0 - Initial release to github/npm diff --git a/ampersand-floatinglabel-input-view.js b/ampersand-floatinglabel-input-view.js index c7c1fe4..93c63a2 100644 --- a/ampersand-floatinglabel-input-view.js +++ b/ampersand-floatinglabel-input-view.js @@ -14,24 +14,49 @@ module.exports = AmpersandInputView.extend({ } ] }), + initialize: function( options ) { + "use strict"; + options = options || {}; + + if ( options.labelClass ) { + this.labelClass = options.labelClass.split( ' ' ); + } else { + this.labelClass = [ 'floating' ]; + } + + AmpersandInputView.prototype.initialize.apply( this, arguments ); + }, render: function() { 'use strict'; - AmpersandInputView.prototype.render.call( this, arguments ); + AmpersandInputView.prototype.render.apply( this, arguments ); this.on( 'change:value', this.checkLabel ); this.labelEl = this.queryByHook( 'label' ); + this.labelContainer = this.queryByHook( 'label-container' ); this.checkLabel(); }, checkLabel: function() { 'use strict'; + var self = this, + action; - if ( this.input.value ) { - this.labelEl.classList.add( 'floating' ); + // Float the label up if there is input text, or, if the warning message + // must be displayed (adjacent to label) + if ( this.input.value || (this.shouldValidate && !this.valid) ) { + action = 'add'; } else { - this.labelEl.classList.remove( 'floating' ); + action = 'remove'; } + + this.labelClass.forEach(function( cls ) { + if ( self.labelContainer ) { + self.labelContainer.classList[action]( cls ); + } else { + self.labelEl.classList[action]( cls ); + } + }); } }); diff --git a/demo/demo.html b/demo/demo.html new file mode 100644 index 0000000..77fa361 --- /dev/null +++ b/demo/demo.html @@ -0,0 +1,76 @@ + + + + floating label field input + + + + + +
+ + \ No newline at end of file diff --git a/demo/demo.js b/demo/demo.js new file mode 100644 index 0000000..5cb5ba9 --- /dev/null +++ b/demo/demo.js @@ -0,0 +1,79 @@ +var AmpersandView = require( 'ampersand-view' ), + AmpersandForm = require( 'ampersand-form-view' ), + Input = require('ampersand-input-view'), + FloatingInput = require( '../ampersand-floatinglabel-input-view' ), + domready = require('domready'), + view; + +var DemoView = AmpersandView.extend({ + template: [ + '
', + '
', + '
', + '
', + '
' + ].join(''), + render: function() { + 'use strict'; + view = this; + + this.renderWithTemplate(); + + this.form = new AmpersandForm({ + autoAppend: false, + el: this.query( 'form' ), + submitCallback: function( data ) { + console.log( 'here\'s your data!:' ); + console.dir( data ); + }, + validCallback: function( data ) { + console.log( "am i valid form?: " + data ); + }, + fields: [ + new FloatingInput({ + template: [ + '
', + '', + '
', + '
', + '', + '', + '
', + '
', + '
' + ].join(''), + labelClass: 'floating', + el: view.queryByHook('floatme'), + type: 'email', + name: 'email', + label: 'Email', + placeholder: 'Email', + required: false, + tests: [ + function( val ) { + if ( val.length < 5 ) { + return 'Your email must be at least 5 characters'; + } + } + ] + }) + // new FloatingInput({ + // el: view.queryByHook('floatme'), + // name: 'test', + // label: 'Test label', + // value: 'Test value' + // }) + ] + }); + + this.registerSubview( this.form ); + } +}); + +domready(function() { + var demoView = new DemoView({ + el: window.document.getElementById('target') + }); + demoView.render(); + view.form._fieldViewsArray[0].render() +}); diff --git a/demo/normalize.css b/demo/normalize.css new file mode 100644 index 0000000..81c6f31 --- /dev/null +++ b/demo/normalize.css @@ -0,0 +1,427 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} \ No newline at end of file diff --git a/package.json b/package.json index 49bb91f..d5126a0 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,14 @@ "name": "ampersand-floatinglabel-input-view", "version": "1.0.0", "description": "An extended Ampersand.js input view to provide floating labels on input elements", - "repo": "https://github.com/datuhealth/ampersand-floatinglabel-input-view", + "repository": { + "type": "git", + "url": "https://github.com/datuhealth/ampersand-floatinglabel-input-view" + }, "main": "ampersand-floatinglabel-input-view.js", "scripts": { - "test": "mkdir tmp; browserify ./test/index.js > ./tmp/index.js; gulp test; rm -r tmp" + "test": "mkdir tmp; browserify ./test/index.js > ./tmp/index.js; gulp test; rm -r tmp", + "demo": "beefy demo/demo.js:demo.js --cwd demo" }, "keywords": [ "ampersand", @@ -21,11 +25,14 @@ "license": "Apache 2.0", "dependencies": { "amp-extend": "^1.0.1", - "ampersand-input-view": "^3.1.1" + "ampersand-input-view": "^4.0.1" }, "devDependencies": { + "ampersand-form-view": "^2.2.0", + "ampersand-view": "^7.2.0", "browserify": "^8.1.1", "chai": "^1.10.0", + "domready": "^1.0.7", "gulp": "^3.8.10", "gulp-jscs": "^1.4.0", "gulp-jshint": "^1.9.0", diff --git a/test/index.js b/test/index.js index 688e124..c19a32a 100644 --- a/test/index.js +++ b/test/index.js @@ -48,6 +48,21 @@ describe( 'The input view', function() { expect( input.el.querySelector( '[data-hook="label"]' ).classList.contains( 'floating' )).to.equal( true ); }); + it( 'should be alt-floating with an initial value', function() { + var input = new InputView({ + name: 'test', + label: 'Test label', + value: 'Test value', + labelClass: 'floating alt-floating' + }); + + input.render(); + + expect( input.el.querySelector( '[data-hook="label"]' ).classList.contains( 'floating' )).to.equal( true ); + expect( input.el.querySelector( '[data-hook="label"]' ).classList.contains( 'alt-floating' )).to.equal( true ); + + }); + it( 'should be floating when a user enters a value', function() { var input = new InputView({ name: 'test', @@ -100,7 +115,7 @@ describe( 'The input view', function() { input.setValue( 'test' ); input.handleInputChanged(); - input.handleBlur(); + input.handleChange(); expect( input.el.querySelector( '[data-hook="label"]' ).classList.contains( 'input-invalid' )).to.equal( true ); }); @@ -125,7 +140,7 @@ describe( 'The input view', function() { input.setValue( 'test' ); input.handleInputChanged(); - input.handleBlur(); + input.handleChange(); expect( input.el.querySelector( 'input' ).classList.contains( 'input-invalid' )).to.equal( true ); }); From f0949ea241dc5679f7a7b1e227a87660dfb0b4ef Mon Sep 17 00:00:00 2001 From: cdaringe Date: Wed, 18 Feb 2015 23:00:40 +0200 Subject: [PATCH 2/6] Change behavior for when to not show error and label if input is empty --- ampersand-floatinglabel-input-view.js | 4 ++-- test/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ampersand-floatinglabel-input-view.js b/ampersand-floatinglabel-input-view.js index 93c63a2..012301c 100644 --- a/ampersand-floatinglabel-input-view.js +++ b/ampersand-floatinglabel-input-view.js @@ -15,7 +15,7 @@ module.exports = AmpersandInputView.extend({ ] }), initialize: function( options ) { - "use strict"; + 'use strict'; options = options || {}; if ( options.labelClass ) { @@ -45,7 +45,7 @@ module.exports = AmpersandInputView.extend({ // Float the label up if there is input text, or, if the warning message // must be displayed (adjacent to label) - if ( this.input.value || (this.shouldValidate && !this.valid) ) { + if ( this.input.value || ( this.shouldValidate && this.changed ) ) { action = 'add'; } else { action = 'remove'; diff --git a/test/index.js b/test/index.js index c19a32a..836bfff 100644 --- a/test/index.js +++ b/test/index.js @@ -79,7 +79,7 @@ describe( 'The input view', function() { expect( input.el.querySelector( '[data-hook="label"]' ).classList.contains( 'floating' )).to.equal( true ); }); - it( 'should not be floating when a user removes the value', function() { + it( 'should not be floating when a user removes the value if originally empty', function() { var input = new InputView({ name: 'test', label: 'Test label', From dd1a4cd42988ab19e5412ff96abd0e36a2601ca6 Mon Sep 17 00:00:00 2001 From: cdaringe Date: Wed, 18 Feb 2015 23:07:26 +0200 Subject: [PATCH 3/6] Correct README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 05f4ee7..3f5b82f 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,9 @@ module.exports = AmpersandView.extend({ ### options Options are passed into the ViewConstructor -`labelClass` - *default: 'floating'*, applies 'yourClass' or 'yourClass andYourOtherClassToo' to data-hooked `label` element -`template` - if attribute `data-hook="label-container"` is found, `labelClass` will be applied to it instead of `data-hook="label"` +`labelClass` - [*default: 'floating'*], applies 'yourClass' or 'yourClass andYourOtherClassToo' to data-hooked `label` element + +`template` - standard View convetion applies. However, if attribute `data-hook="label-container"` is found, `labelClass` will be applied to it instead of `data-hook="label"` See [ampersand-input-view](https://github.com/ampersandjs/ampersand-input-view#api-reference) for the api reference. From c5e7b53f6b2ed86ebd2720ae71728bff1dfed63a Mon Sep 17 00:00:00 2001 From: cdaringe Date: Thu, 19 Feb 2015 02:13:50 +0200 Subject: [PATCH 4/6] Bump minor version --- README.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3f5b82f..bb8e101 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ See [ampersand-input-view](https://github.com/ampersandjs/ampersand-input-view#a ## changelog -- 1.0.1 - Permit overridable class(es) for label. Add demo. Rev input version req +- 1.1.0 - Permit overridable class(es) for label. Add demo. Rev input version req - 1.0.0 - Added tests to make sure everything worked well - 0.2.0 - Added input-invalid class to the label when the input is invalid - 0.1.0 - Initial release to github/npm diff --git a/package.json b/package.json index d5126a0..d0259ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ampersand-floatinglabel-input-view", - "version": "1.0.0", + "version": "1.1.0", "description": "An extended Ampersand.js input view to provide floating labels on input elements", "repository": { "type": "git", From d829dcea572fc760da81a39b1828b9d8127815fa Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 19 Feb 2015 02:18:08 +0200 Subject: [PATCH 5/6] README typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bb8e101..6d0a661 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Options are passed into the ViewConstructor `labelClass` - [*default: 'floating'*], applies 'yourClass' or 'yourClass andYourOtherClassToo' to data-hooked `label` element -`template` - standard View convetion applies. However, if attribute `data-hook="label-container"` is found, `labelClass` will be applied to it instead of `data-hook="label"` +`template` - standard View convention applies. However, if attribute `data-hook="label-container"` is found, `labelClass` will be applied to it instead of `data-hook="label"` See [ampersand-input-view](https://github.com/ampersandjs/ampersand-input-view#api-reference) for the api reference. From 4c4efbb0020e97baf57572527638b931035fbcf0 Mon Sep 17 00:00:00 2001 From: cdaringe Date: Sun, 22 Feb 2015 08:04:05 +0200 Subject: [PATCH 6/6] Update package.json w/ beefy req for demo --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index d0259ed..f5dd117 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "devDependencies": { "ampersand-form-view": "^2.2.0", "ampersand-view": "^7.2.0", + "beefy": "2.1.3", "browserify": "^8.1.1", "chai": "^1.10.0", "domready": "^1.0.7",