| OLD | NEW |
| 1 <!-- | 1 <!-- |
| 2 @license | 2 @license |
| 3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. | 3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. |
| 4 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt | 4 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt |
| 5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | 5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt |
| 6 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt | 6 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt |
| 7 Code distributed by Google as part of the polymer project is also | 7 Code distributed by Google as part of the polymer project is also |
| 8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt | 8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt |
| 9 --> | 9 --> |
| 10 | 10 |
| 11 <link rel="import" href="../polymer/polymer.html"> | 11 <link rel="import" href="../polymer/polymer.html"> |
| 12 <link rel="import" href="../paper-styles/paper-styles.html"> | 12 <link rel="import" href="../paper-styles/paper-styles.html"> |
| 13 | 13 |
| 14 <style is="x-style"> | |
| 15 | |
| 16 * { | |
| 17 | |
| 18 --paper-input-container-font: var(--paper-font-subhead); | |
| 19 --paper-input-container-floating-label-font: var(--paper-font-caption); | |
| 20 --paper-input-container-add-on-font: var(--paper-font-caption); | |
| 21 | |
| 22 --paper-input-container-focus-color: var(--default-primary-color); | |
| 23 --paper-input-container-color: var(--secondary-text-color); | |
| 24 --paper-input-container-invalid-color: var(--google-red-500); | |
| 25 --paper-input-container-input-color: var(--primary-text-color); | |
| 26 | |
| 27 } | |
| 28 | |
| 29 </style> | |
| 30 | |
| 31 <!-- | 14 <!-- |
| 32 `<paper-input-container>` wraps an `<input>` and `<label>` element, decorating | 15 `<paper-input-container>` is a container for a `<label>`, an `<input is="iron-in
put">` or |
| 33 them following the [Material Design spec](http://www.google.com/design/spec/comp
onents/text-fields.html#text-fields-single-line-text-field) | 16 `<iron-autogrow-textarea>` and optional add-on elements such as an error message
or character |
| 17 counter, used to implement Material Design text fields. |
| 34 | 18 |
| 35 For example: | 19 For example: |
| 36 | 20 |
| 37 <paper-input-container> | 21 <paper-input-container> |
| 38 <label>email address</label> | 22 <label>Your name</label> |
| 39 <input type="email"> | 23 <input is="iron-input"> |
| 40 </paper-input-container> | 24 </paper-input-container> |
| 41 | 25 |
| 26 ### Listening for input changes |
| 27 |
| 28 By default, it listens for changes on the `bind-value` attribute on its children
nodes and perform |
| 29 tasks such as auto-validating and label styling when the `bind-value` changes. Y
ou can configure |
| 30 the attribute it listens to with the `attr-for-value` attribute. |
| 31 |
| 32 ### Using a custom input element |
| 33 |
| 34 You can use a custom input element in a `<paper-input-container>`, for example t
o implement a |
| 35 compound input field like a social security number input. The custom input eleme
nt should have the |
| 36 `paper-input-input` class, have a `notify:true` value property and optionally im
plements |
| 37 `Polymer.IronValidatableBehavior` if it is validatble. |
| 38 |
| 39 <paper-input-container attr-for-value="ssn-value"> |
| 40 <label>Social security number</label> |
| 41 <ssn-input class="paper-input-input"></ssn-input> |
| 42 </paper-input-container> |
| 43 |
| 44 ### Validation |
| 45 |
| 46 If the `auto-validate` attribute is set, the input container will validate the i
nput and update |
| 47 the container styling when the input value changes. |
| 48 |
| 49 ### Add-ons |
| 50 |
| 51 Add-ons are child elements of a `<paper-input-container>` with the `add-on` attr
ibute and |
| 52 implements the `Polymer.PaperInputAddonBehavior` behavior. They are notified whe
n the input value |
| 53 or validity changes, and may implement functionality such as error messages or c
haracter counters. |
| 54 They appear at the bottom of the input. |
| 55 |
| 56 ### Styling |
| 57 |
| 58 The following custom properties and mixins are available for styling: |
| 59 |
| 60 Custom property | Description | Default |
| 61 ----------------|-------------|---------- |
| 62 `--paper-input-container-color` | Label and underline color when the input is no
t focused | `--secondary-text-color` |
| 63 `--paper-input-container-focus-color` | Label and underline color when the input
is focused | `--default-primary-color` |
| 64 `--paper-input-container-invalid-color` | Label and underline color when the inp
ut is focused | `--google-red-500` |
| 65 `--paper-input-container-input-color` | Input foreground color | `--primary-text
-color` |
| 66 `--paper-input-container` | Mixin applied to the container | `{}` |
| 67 `--paper-input-container-label` | Mixin applied to the label | `{}` |
| 68 `--paper-input-container-input` | Mixin applied to the input | `{}` |
| 69 |
| 70 This element is `display:block` by default, but you can set the `inline` attribu
te to make it |
| 71 `display:inline-block`. |
| 42 --> | 72 --> |
| 43 <dom-module id="paper-input-container"> | 73 <dom-module id="paper-input-container"> |
| 44 | 74 |
| 45 <style> | 75 <style> |
| 46 | 76 |
| 47 :host { | 77 :host { |
| 48 display: block; | 78 display: block; |
| 49 padding: 8px 0; | 79 padding: 8px 0; |
| 50 | 80 |
| 51 --mixin(--paper-input-container); | 81 @apply(--paper-input-container); |
| 82 } |
| 83 |
| 84 :host[inline] { |
| 85 display: inline-block; |
| 52 } | 86 } |
| 53 | 87 |
| 54 :host([disabled]) { | 88 :host([disabled]) { |
| 55 pointer-events: none; | 89 pointer-events: none; |
| 56 opacity: 0.33; | 90 opacity: 0.33; |
| 57 } | 91 } |
| 58 | 92 |
| 59 .floated-label-placeholder { | 93 .floated-label-placeholder { |
| 60 mixin(--paper-input-container-label-font); | 94 @apply(--paper-font-caption); |
| 95 } |
| 96 |
| 97 .underline { |
| 98 position: relative; |
| 61 } | 99 } |
| 62 | 100 |
| 63 .focused-line { | 101 .focused-line { |
| 64 height: 2px; | 102 height: 2px; |
| 65 | 103 |
| 66 -webkit-transform-origin: center center; | 104 -webkit-transform-origin: center center; |
| 67 transform-origin: center center; | 105 transform-origin: center center; |
| 68 -webkit-transform: scale3d(0,1,1); | 106 -webkit-transform: scale3d(0,1,1); |
| 69 transform: scale3d(0,1,1); | 107 transform: scale3d(0,1,1); |
| 70 | 108 |
| 71 background: var(--paper-input-container-focus-color); | 109 background: var(--paper-input-container-focus-color, --default-primary-col
or); |
| 72 } | 110 } |
| 73 | 111 |
| 74 .is-highlighted .focused-line { | 112 .is-highlighted .focused-line { |
| 75 -webkit-transform: none; | 113 -webkit-transform: none; |
| 76 transform: none; | 114 transform: none; |
| 77 -webkit-transition: -webkit-transform 0.25s; | 115 -webkit-transition: -webkit-transform 0.25s; |
| 78 transition: transform 0.25s; | 116 transition: transform 0.25s; |
| 79 | 117 |
| 80 mixin(--paper-transition-easing); | 118 @apply(--paper-transition-easing); |
| 81 } | 119 } |
| 82 | 120 |
| 83 .is-invalid .focused-line { | 121 .is-invalid .focused-line { |
| 84 background: var(--paper-input-container-invalid-color); | 122 background: var(--paper-input-container-invalid-color, --google-red-500); |
| 85 | 123 |
| 86 -webkit-transform: none; | 124 -webkit-transform: none; |
| 87 transform: none; | 125 transform: none; |
| 88 -webkit-transition: -webkit-transform 0.25s; | 126 -webkit-transition: -webkit-transform 0.25s; |
| 89 transition: transform 0.25s; | 127 transition: transform 0.25s; |
| 90 | 128 |
| 91 mixin(--paper-transition-easing); | 129 @apply(--paper-transition-easing); |
| 92 } | 130 } |
| 93 | 131 |
| 94 .unfocused-line { | 132 .unfocused-line { |
| 95 height: 1px; | 133 height: 1px; |
| 96 background: var(--paper-input-container-color); | 134 background: var(--paper-input-container-color, --secondary-text-color); |
| 97 } | 135 } |
| 98 | 136 |
| 99 :host([disabled]) .unfocused-line { | 137 :host([disabled]) .unfocused-line { |
| 100 border-bottom: 1px dashed; | 138 border-bottom: 1px dashed; |
| 101 border-color: var(--paper-input-container-color); | 139 border-color: var(--paper-input-container-color, --secondary-text-color); |
| 102 background: transparent; | 140 background: transparent; |
| 103 } | 141 } |
| 104 | 142 |
| 143 .input-content { |
| 144 position: relative; |
| 145 } |
| 146 |
| 105 .input-content ::content label, | 147 .input-content ::content label, |
| 106 .input-content ::content .paper-input-label { | 148 .input-content ::content .paper-input-label { |
| 107 position: absolute; | 149 position: absolute; |
| 108 top: 0; | 150 top: 0; |
| 109 right: 0; | 151 right: 0; |
| 110 left: 0; | 152 left: 0; |
| 111 font: inherit; | 153 font: inherit; |
| 112 color: var(--paper-input-container-color); | 154 color: var(--paper-input-container-color, --secondary-text-color); |
| 113 | 155 |
| 114 mixin(--paper-input-container-font); | 156 @apply(--paper-font-subhead); |
| 115 | 157 @apply(--paper-input-container-label); |
| 116 mixin(--paper-input-container-label); | |
| 117 } | 158 } |
| 118 | 159 |
| 119 .input-content.label-is-floating ::content label, | 160 .input-content.label-is-floating ::content label, |
| 120 .input-content.label-is-floating ::content .paper-input-label { | 161 .input-content.label-is-floating ::content .paper-input-label { |
| 121 -webkit-transform: translate3d(0, -75%, 0) scale(0.75); | 162 -webkit-transform: translate3d(0, -75%, 0) scale(0.75); |
| 122 transform: translate3d(0, -75%, 0) scale(0.75); | 163 transform: translate3d(0, -75%, 0) scale(0.75); |
| 123 -webkit-transform-origin: left top; | 164 -webkit-transform-origin: left top; |
| 124 transform-origin: left top; | 165 transform-origin: left top; |
| 125 -webkit-transition: -webkit-transform 0.25s; | 166 -webkit-transition: -webkit-transform 0.25s; |
| 126 transition: transform 0.25s; | 167 transition: transform 0.25s; |
| 127 | 168 |
| 128 mixin(--paper-transition-easing); | 169 @apply(--paper-transition-easing); |
| 129 } | 170 } |
| 130 | 171 |
| 131 .input-content.label-is-highlighted ::content label, | 172 .input-content.label-is-highlighted ::content label, |
| 132 .input-content.label-is-highlighted ::content .paper-input-label { | 173 .input-content.label-is-highlighted ::content .paper-input-label { |
| 133 color: var(--paper-input-container-focus-color); | 174 color: var(--paper-input-container-focus-color, --default-primary-color); |
| 134 } | 175 } |
| 135 | 176 |
| 136 .input-content.is-invalid ::content label, | 177 .input-content.is-invalid ::content label, |
| 137 .input-content.is-invalid ::content .paper-input-label { | 178 .input-content.is-invalid ::content .paper-input-label { |
| 138 color: var(--paper-input-container-invalid-color); | 179 color: var(--paper-input-container-invalid-color, --google-red-500); |
| 139 } | 180 } |
| 140 | 181 |
| 141 .input-content.label-is-hidden ::content label, | 182 .input-content.label-is-hidden ::content label, |
| 142 .input-content.label-is-hidden ::content .paper-input-label { | 183 .input-content.label-is-hidden ::content .paper-input-label { |
| 143 visibility: hidden; | 184 visibility: hidden; |
| 144 } | 185 } |
| 145 | 186 |
| 146 .input-content ::content input, | 187 .input-content ::content input, |
| 147 .input-content ::content textarea, | 188 .input-content ::content textarea, |
| 189 .input-content ::content iron-autogrow-textarea, |
| 148 .input-content ::content .paper-input-input { | 190 .input-content ::content .paper-input-input { |
| 149 position: relative; /* to make a stacking context */ | 191 position: relative; /* to make a stacking context */ |
| 150 outline: none; | 192 outline: none; |
| 151 color: var(--paper-input-container-input-color); | 193 box-shadow: none; |
| 152 | |
| 153 mixin(--paper-input-container-floating-label-font); | |
| 154 } | |
| 155 | |
| 156 .input-content ::content input, | |
| 157 .input-content ::content textarea { | |
| 158 padding: 0; | 194 padding: 0; |
| 159 width: 100%; | 195 width: 100%; |
| 160 background: transparent; | 196 background: transparent; |
| 161 border: none; | 197 border: none; |
| 198 color: var(--paper-input-container-input-color, --primary-text-color); |
| 162 | 199 |
| 163 mixin(--paper-input-container-font); | 200 @apply(--paper-font-subhead); |
| 201 @apply(--paper-input-container-input); |
| 202 } |
| 164 | 203 |
| 165 mixin(--paper-input-container-input); | 204 /* Firefox sets a min-width on the input, which can cause layout issues */ |
| 205 .input-content ::content input { |
| 206 min-width: 0; |
| 166 } | 207 } |
| 167 | 208 |
| 168 .input-content ::content textarea { | 209 .input-content ::content textarea { |
| 169 resize: none; | 210 resize: none; |
| 170 } | 211 } |
| 171 | 212 |
| 172 .add-on-content.is-invalid ::content * { | 213 .add-on-content.is-invalid ::content * { |
| 173 color: var(--paper-input-container-invalid-color); | 214 color: var(--paper-input-container-invalid-color, --google-red-500); |
| 174 } | 215 } |
| 175 | 216 |
| 176 .add-on-content.is-highlighted ::content * { | 217 .add-on-content.is-highlighted ::content * { |
| 177 color: var(--paper-input-container-focus-color); | 218 color: var(--paper-input-container-focus-color, --default-primary-color); |
| 178 } | |
| 179 | |
| 180 .input-content, | |
| 181 .underline { | |
| 182 position: relative; | |
| 183 } | 219 } |
| 184 | 220 |
| 185 </style> | 221 </style> |
| 186 | 222 |
| 187 <template> | 223 <template> |
| 188 | 224 |
| 189 <template is="x-if" if="[[!noLabelFloat]]"> | 225 <template is="dom-if" if="[[!noLabelFloat]]"> |
| 190 <div class="floated-label-placeholder"> </div> | 226 <div class="floated-label-placeholder"> </div> |
| 191 </template> | 227 </template> |
| 192 | 228 |
| 193 <div class$="[[_computeInputContentClass(noLabelFloat,focused,_inputHasConte
nt,_inputIsInvalid)]]"> | 229 <div class$="[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focus
ed,invalid,_inputHasContent)]]"> |
| 194 <content select=":not([add-on])"></content> | 230 <content select=":not([add-on])"></content> |
| 195 </div> | 231 </div> |
| 196 | 232 |
| 197 <div class$="[[_computeUnderlineClass(focused,_inputIsInvalid)]]"> | 233 <div class$="[[_computeUnderlineClass(focused,invalid)]]"> |
| 198 <div class="unfocused-line fit"></div> | 234 <div class="unfocused-line fit"></div> |
| 199 <div class="focused-line fit"></div> | 235 <div class="focused-line fit"></div> |
| 200 </div> | 236 </div> |
| 201 | 237 |
| 202 <div class$="[[_computeAddOnContentClass(focused,_inputIsInvalid)]]"> | 238 <div class$="[[_computeAddOnContentClass(focused,invalid)]]"> |
| 203 <content id="addOnContent" select="[add-on]"></content> | 239 <content id="addOnContent" select="[add-on]"></content> |
| 204 </div> | 240 </div> |
| 205 | 241 |
| 206 </template> | 242 </template> |
| 207 | 243 |
| 208 </dom-module> | 244 </dom-module> |
| 209 | 245 |
| 210 <script> | 246 <script> |
| 211 (function() { | 247 (function() { |
| 212 | 248 |
| 213 Polymer({ | 249 Polymer({ |
| 214 | 250 |
| 215 is: 'paper-input-container', | 251 is: 'paper-input-container', |
| 216 | 252 |
| 217 enableCustomStyleProperties: true, | |
| 218 | |
| 219 properties: { | 253 properties: { |
| 220 | 254 |
| 221 /** | 255 /** |
| 222 * Set to true to disable the floating label. | 256 * Set to true to disable the floating label. The label disappears when th
e input value is |
| 257 * not null. |
| 223 */ | 258 */ |
| 224 noLabelFloat: { | 259 noLabelFloat: { |
| 225 type: Boolean, | 260 type: Boolean, |
| 226 value: false | 261 value: false |
| 227 }, | 262 }, |
| 228 | 263 |
| 229 /** | 264 /** |
| 265 * Set to true to always float the floating label. |
| 266 */ |
| 267 alwaysFloatLabel: { |
| 268 type: Boolean, |
| 269 value: false |
| 270 }, |
| 271 |
| 272 /** |
| 230 * The attribute to listen for value changes on. | 273 * The attribute to listen for value changes on. |
| 231 */ | 274 */ |
| 232 attrForValue: { | 275 attrForValue: { |
| 233 type: String, | 276 type: String, |
| 234 value: 'bind-value' | 277 value: 'bind-value' |
| 235 }, | 278 }, |
| 236 | 279 |
| 237 /** | 280 /** |
| 238 * Set to true to auto-validate the input value. | 281 * Set to true to auto-validate the input value when it changes. |
| 239 */ | 282 */ |
| 240 autoValidate: { | 283 autoValidate: { |
| 241 type: Boolean, | 284 type: Boolean, |
| 242 value: false | 285 value: false |
| 243 }, | 286 }, |
| 244 | 287 |
| 245 /** | 288 /** |
| 289 * True if the input is invalid. This property is set automatically when t
he input value |
| 290 * changes if auto-validating, or when the `iron-input-valid` event is hea
rd from a child. |
| 291 */ |
| 292 invalid: { |
| 293 observer: '_invalidChanged', |
| 294 type: Boolean, |
| 295 value: false |
| 296 }, |
| 297 |
| 298 /** |
| 246 * True if the input has focus. | 299 * True if the input has focus. |
| 247 */ | 300 */ |
| 248 focused: { | 301 focused: { |
| 249 readOnly: true, | 302 readOnly: true, |
| 250 type: Boolean, | 303 type: Boolean, |
| 251 value: false | 304 value: false |
| 252 }, | 305 }, |
| 253 | 306 |
| 254 _addons: { | 307 _addons: { |
| 255 type: Array, | 308 type: Array, |
| 256 value: function() { | 309 value: function() { |
| 257 return []; | 310 return []; |
| 258 } | 311 } |
| 259 }, | 312 }, |
| 260 | 313 |
| 261 _inputHasContent: { | 314 _inputHasContent: { |
| 262 type: Boolean, | 315 type: Boolean, |
| 263 value: false | 316 value: false |
| 264 }, | 317 }, |
| 265 | 318 |
| 266 _inputIsInvalid: { | |
| 267 type: Boolean, | |
| 268 value: false | |
| 269 }, | |
| 270 | |
| 271 _inputSelector: { | 319 _inputSelector: { |
| 272 type: String, | 320 type: String, |
| 273 value: 'input,textarea,.paper-input-input' | 321 value: 'input,textarea,.paper-input-input' |
| 274 }, | 322 }, |
| 275 | 323 |
| 276 _boundOnFocus: { | 324 _boundOnFocus: { |
| 277 type: Function, | 325 type: Function, |
| 278 value: function() { | 326 value: function() { |
| 279 return this._onFocus.bind(this); | 327 return this._onFocus.bind(this); |
| 280 } | 328 } |
| 281 }, | 329 }, |
| 282 | 330 |
| 283 _boundOnBlur: { | 331 _boundOnBlur: { |
| 284 type: Function, | 332 type: Function, |
| 285 value: function() { | 333 value: function() { |
| 286 return this._onBlur.bind(this); | 334 return this._onBlur.bind(this); |
| 287 } | 335 } |
| 288 }, | 336 }, |
| 289 | 337 |
| 338 _boundOnInput: { |
| 339 type: Function, |
| 340 value: function() { |
| 341 this._onInput.bind(this) |
| 342 } |
| 343 }, |
| 344 |
| 290 _boundValueChanged: { | 345 _boundValueChanged: { |
| 291 type: Function, | 346 type: Function, |
| 292 value: function() { | 347 value: function() { |
| 293 return this._onValueChanged.bind(this); | 348 return this._onValueChanged.bind(this); |
| 294 } | 349 } |
| 295 } | 350 } |
| 296 | 351 |
| 297 }, | 352 }, |
| 298 | 353 |
| 299 listeners: { | 354 listeners: { |
| 300 'addon-attached': '_onAddonAttached', | 355 'addon-attached': '_onAddonAttached', |
| 301 'input': '_onInput' | 356 'iron-input-validate': '_onIronInputValidate' |
| 302 }, | 357 }, |
| 303 | 358 |
| 304 get _valueChangedEvent() { | 359 get _valueChangedEvent() { |
| 305 return this.attrForValue + '-changed'; | 360 return this.attrForValue + '-changed'; |
| 306 }, | 361 }, |
| 307 | 362 |
| 308 get _propertyForValue() { | 363 get _propertyForValue() { |
| 309 return Polymer.CaseMap.dashToCamelCase(this.attrForValue); | 364 return Polymer.CaseMap.dashToCamelCase(this.attrForValue); |
| 310 }, | 365 }, |
| 311 | 366 |
| 312 get _inputElement() { | 367 get _inputElement() { |
| 313 return Polymer.dom(this).querySelector(this._inputSelector); | 368 return Polymer.dom(this).querySelector(this._inputSelector); |
| 314 }, | 369 }, |
| 315 | 370 |
| 316 ready: function() { | 371 ready: function() { |
| 317 this.addEventListener('focus', this._boundOnFocus, true); | 372 this.addEventListener('focus', this._boundOnFocus, true); |
| 318 this.addEventListener('blur', this._boundOnBlur, true); | 373 this.addEventListener('blur', this._boundOnBlur, true); |
| 319 this.addEventListener(this._valueChangedEvent, this._boundValueChanged, tr
ue); | 374 if (this.attrForValue) { |
| 375 this._inputElement.addEventListener(this._valueChangedEvent, this._bound
ValueChanged); |
| 376 } else { |
| 377 this.addEventListener('input', this._onInput); |
| 378 } |
| 320 }, | 379 }, |
| 321 | 380 |
| 322 attached: function() { | 381 attached: function() { |
| 323 this._handleInput(this._inputElement); | 382 this._handleValue(this._inputElement); |
| 324 }, | 383 }, |
| 325 | 384 |
| 326 _onAddonAttached: function(event) { | 385 _onAddonAttached: function(event) { |
| 327 this._addons.push(event.target); | 386 this._addons.push(event.target); |
| 328 this._handleInput(this._inputElement); | 387 this._handleValue(this._inputElement); |
| 329 }, | 388 }, |
| 330 | 389 |
| 331 _onFocus: function() { | 390 _onFocus: function() { |
| 332 this._setFocused(true); | 391 this._setFocused(true); |
| 333 }, | 392 }, |
| 334 | 393 |
| 335 _onBlur: function() { | 394 _onBlur: function() { |
| 336 this._setFocused(false); | 395 this._setFocused(false); |
| 337 }, | 396 }, |
| 338 | 397 |
| 339 _onInput: function(event) { | 398 _onInput: function(event) { |
| 340 this._handleInput(event.target); | 399 this._handleValue(event.target); |
| 341 }, | 400 }, |
| 342 | 401 |
| 343 _onValueChanged: function(event) { | 402 _onValueChanged: function(event) { |
| 344 this._handleInput(event.target); | 403 this._handleValue(event.target); |
| 345 }, | 404 }, |
| 346 | 405 |
| 347 _handleInput: function(inputElement) { | 406 _handleValue: function(inputElement) { |
| 348 var value = inputElement[this._propertyForValue] || inputElement.value; | 407 var value = inputElement[this._propertyForValue] || inputElement.value; |
| 349 var valid = inputElement.checkValidity(); | 408 |
| 409 if (this.autoValidate) { |
| 410 var valid; |
| 411 if (inputElement.validate) { |
| 412 valid = inputElement.validate(value); |
| 413 } else { |
| 414 valid = inputElement.checkValidity(); |
| 415 } |
| 416 this.invalid = !valid; |
| 417 } |
| 350 | 418 |
| 351 // type="number" hack needed because this.value is empty until it's valid | 419 // type="number" hack needed because this.value is empty until it's valid |
| 352 if (value || inputElement.type === 'number' && !valid) { | 420 if (value || (inputElement.type === 'number' && !inputElement.checkValidit
y())) { |
| 353 this._inputHasContent = true; | 421 this._inputHasContent = true; |
| 354 } else { | 422 } else { |
| 355 this._inputHasContent = false; | 423 this._inputHasContent = false; |
| 356 } | 424 } |
| 357 | 425 |
| 358 if (this.autoValidate) { | 426 this.updateAddons({ |
| 359 this._inputIsInvalid = !valid; | 427 inputElement: inputElement, |
| 360 } | 428 value: value, |
| 429 invalid: this.invalid |
| 430 }); |
| 431 }, |
| 361 | 432 |
| 362 // notify add-ons | 433 _onIronInputValidate: function(event) { |
| 363 for (var addon, i = 0; addon = this._addons[i]; i++) { | 434 this.invalid = this._inputElement.invalid; |
| 364 // need to set all of these, or call method... thanks input type="number
"! | 435 }, |
| 365 addon.inputElement = inputElement; | 436 |
| 366 addon.value = value; | 437 _invalidChanged: function() { |
| 367 addon.invalid = !valid; | 438 if (this._addons) { |
| 439 this.updateAddons({invalid: this.invalid}); |
| 368 } | 440 } |
| 369 }, | 441 }, |
| 370 | 442 |
| 371 _computeInputContentClass: function(noLabelFloat, focused, _inputHasContent,
_inputIsInvalid) { | 443 /** |
| 444 * Call this to update the state of add-ons. |
| 445 * @param {Object} state Add-on state. |
| 446 */ |
| 447 updateAddons: function(state) { |
| 448 for (var addon, index = 0; addon = this._addons[index]; index++) { |
| 449 addon.update(state); |
| 450 } |
| 451 }, |
| 452 |
| 453 _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused,
invalid, _inputHasContent) { |
| 372 var cls = 'input-content'; | 454 var cls = 'input-content'; |
| 373 if (!noLabelFloat) { | 455 if (!noLabelFloat) { |
| 374 if (_inputHasContent) { | 456 if (alwaysFloatLabel || _inputHasContent) { |
| 375 cls += ' label-is-floating'; | 457 cls += ' label-is-floating'; |
| 376 if (_inputIsInvalid) { | 458 if (invalid) { |
| 377 cls += ' is-invalid'; | 459 cls += ' is-invalid'; |
| 378 } else if (focused) { | 460 } else if (focused) { |
| 379 cls += " label-is-highlighted"; | 461 cls += " label-is-highlighted"; |
| 380 } | 462 } |
| 381 } | 463 } |
| 382 } else { | 464 } else { |
| 383 if (_inputHasContent) { | 465 if (_inputHasContent) { |
| 384 cls += ' label-is-hidden'; | 466 cls += ' label-is-hidden'; |
| 385 } | 467 } |
| 386 } | 468 } |
| 387 return cls; | 469 return cls; |
| 388 }, | 470 }, |
| 389 | 471 |
| 390 _computeUnderlineClass: function(focused, _inputIsInvalid) { | 472 _computeUnderlineClass: function(focused, invalid) { |
| 391 var cls = 'underline'; | 473 var cls = 'underline'; |
| 392 if (_inputIsInvalid) { | 474 if (invalid) { |
| 393 cls += ' is-invalid'; | 475 cls += ' is-invalid'; |
| 394 } else if (focused) { | 476 } else if (focused) { |
| 395 cls += ' is-highlighted' | 477 cls += ' is-highlighted' |
| 396 } | 478 } |
| 397 return cls; | 479 return cls; |
| 398 }, | 480 }, |
| 399 | 481 |
| 400 _computeAddOnContentClass: function(focused, _inputIsInvalid) { | 482 _computeAddOnContentClass: function(focused, invalid) { |
| 401 var cls = 'add-on-content'; | 483 var cls = 'add-on-content'; |
| 402 if (_inputIsInvalid) { | 484 if (invalid) { |
| 403 cls += ' is-invalid'; | 485 cls += ' is-invalid'; |
| 404 } else if (focused) { | 486 } else if (focused) { |
| 405 cls += ' is-highlighted' | 487 cls += ' is-highlighted' |
| 406 } | 488 } |
| 407 return cls; | 489 return cls; |
| 408 } | 490 } |
| 409 | 491 |
| 410 }); | 492 }); |
| 411 | 493 |
| 412 })(); | 494 })(); |
| 413 </script> | 495 </script> |
| OLD | NEW |