| OLD | NEW |
| (Empty) |
| 1 <!-- | |
| 2 @license | |
| 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 | |
| 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 | |
| 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 | |
| 9 --> | |
| 10 | |
| 11 <link rel="import" href="../polymer/polymer.html"> | |
| 12 <link rel="import" href="../iron-validatable-behavior/iron-validatable-behavior.
html"> | |
| 13 | |
| 14 <script> | |
| 15 | |
| 16 /* | |
| 17 `<iron-input>` adds two-way binding and custom validators using `Polymer.IronVal
idatorBehavior` | |
| 18 to `<input>`. | |
| 19 | |
| 20 ### Two-way binding | |
| 21 | |
| 22 By default you can only get notified of changes to an `input`'s `value` due to u
ser input: | |
| 23 | |
| 24 <input value="{{myValue::input}}"> | |
| 25 | |
| 26 `iron-input` adds the `bind-value` property that mirrors the `value` property, a
nd can be used | |
| 27 for two-way data binding. `bind-value` will notify if it is changed either by us
er input or by script. | |
| 28 | |
| 29 <input is="iron-input" bind-value="{{myValue}}"> | |
| 30 | |
| 31 ### Custom validators | |
| 32 | |
| 33 You can use custom validators that implement `Polymer.IronValidatorBehavior` wit
h `<iron-input>`. | |
| 34 | |
| 35 <input is="iron-input" validator="my-custom-validator"> | |
| 36 | |
| 37 ### Stopping invalid input | |
| 38 | |
| 39 It may be desirable to only allow users to enter certain characters. You can use
the | |
| 40 `prevent-invalid-input` and `allowed-pattern` attributes together to accomplish
this. This feature | |
| 41 is separate from validation, and `allowed-pattern` does not affect how the input
is validated. | |
| 42 | |
| 43 <!-- only allow characters that match [0-9] --> | |
| 44 <input is="iron-input" prevent-invalid-input allowed-pattern="[0-9]"> | |
| 45 | |
| 46 @hero hero.svg | |
| 47 @demo demo/index.html | |
| 48 */ | |
| 49 | |
| 50 Polymer({ | |
| 51 | |
| 52 is: 'iron-input', | |
| 53 | |
| 54 extends: 'input', | |
| 55 | |
| 56 behaviors: [ | |
| 57 Polymer.IronValidatableBehavior | |
| 58 ], | |
| 59 | |
| 60 properties: { | |
| 61 | |
| 62 /** | |
| 63 * Use this property instead of `value` for two-way data binding. | |
| 64 */ | |
| 65 bindValue: { | |
| 66 observer: '_bindValueChanged', | |
| 67 type: String | |
| 68 }, | |
| 69 | |
| 70 /** | |
| 71 * Set to true to prevent the user from entering invalid input. The new in
put characters are | |
| 72 * matched with `allowedPattern` if it is set, otherwise it will use the `
pattern` attribute if | |
| 73 * set, or the `type` attribute (only supported for `type=number`). | |
| 74 */ | |
| 75 preventInvalidInput: { | |
| 76 type: Boolean | |
| 77 }, | |
| 78 | |
| 79 /** | |
| 80 * Regular expression to match valid input characters. | |
| 81 */ | |
| 82 allowedPattern: { | |
| 83 type: String | |
| 84 }, | |
| 85 | |
| 86 _previousValidInput: { | |
| 87 type: String, | |
| 88 value: '' | |
| 89 }, | |
| 90 | |
| 91 _patternAlreadyChecked: { | |
| 92 type: Boolean, | |
| 93 value: false | |
| 94 } | |
| 95 | |
| 96 }, | |
| 97 | |
| 98 listeners: { | |
| 99 'input': '_onInput', | |
| 100 'keypress': '_onKeypress' | |
| 101 }, | |
| 102 | |
| 103 get _patternRegExp() { | |
| 104 var pattern; | |
| 105 if (this.allowedPattern) { | |
| 106 pattern = new RegExp(this.allowedPattern); | |
| 107 } else if (this.pattern) { | |
| 108 pattern = new RegExp(this.pattern); | |
| 109 } else { | |
| 110 switch (this.type) { | |
| 111 case 'number': | |
| 112 pattern = /[0-9.,e-]/; | |
| 113 break; | |
| 114 } | |
| 115 } | |
| 116 return pattern; | |
| 117 }, | |
| 118 | |
| 119 ready: function() { | |
| 120 this.bindValue = this.value; | |
| 121 }, | |
| 122 | |
| 123 _bindValueChanged: function() { | |
| 124 if (this.value !== this.bindValue) { | |
| 125 this.value = !this.bindValue ? '' : this.bindValue; | |
| 126 } | |
| 127 // manually notify because we don't want to notify until after setting val
ue | |
| 128 this.fire('bind-value-changed', {value: this.bindValue}); | |
| 129 }, | |
| 130 | |
| 131 _onInput: function() { | |
| 132 // Need to validate each of the characters pasted if they haven't | |
| 133 // been validated inside `_onKeypress` already. | |
| 134 if (this.preventInvalidInput && !this._patternAlreadyChecked) { | |
| 135 var valid = this._checkPatternValidity(); | |
| 136 if (!valid) { | |
| 137 this.value = this._previousValidInput; | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 this.bindValue = this.value; | |
| 142 this._previousValidInput = this.value; | |
| 143 this._patternAlreadyChecked = false; | |
| 144 }, | |
| 145 | |
| 146 _isPrintable: function(event) { | |
| 147 // What a control/printable character is varies wildly based on the browse
r. | |
| 148 // - most control characters (arrows, backspace) do not send a `keypress`
event | |
| 149 // in Chrome, but the *do* on Firefox | |
| 150 // - in Firefox, when they do send a `keypress` event, control chars have | |
| 151 // a charCode = 0, keyCode = xx (for ex. 40 for down arrow) | |
| 152 // - printable characters always send a keypress event. | |
| 153 // - in Firefox, printable chars always have a keyCode = 0. In Chrome, the
keyCode | |
| 154 // always matches the charCode. | |
| 155 // None of this makes any sense. | |
| 156 | |
| 157 // For these keys, ASCII code == browser keycode. | |
| 158 var anyNonPrintable = | |
| 159 (event.keyCode == 8) || // backspace | |
| 160 (event.keyCode == 13) || // enter | |
| 161 (event.keyCode == 27); // escape | |
| 162 | |
| 163 // For these keys, make sure it's a browser keycode and not an ASCII code. | |
| 164 var mozNonPrintable = | |
| 165 (event.keyCode == 19) || // pause | |
| 166 (event.keyCode == 20) || // caps lock | |
| 167 (event.keyCode == 45) || // insert | |
| 168 (event.keyCode == 46) || // delete | |
| 169 (event.keyCode == 144) || // num lock | |
| 170 (event.keyCode == 145) || // scroll lock | |
| 171 (event.keyCode > 32 && event.keyCode < 41) || // page up/down, end, ho
me, arrows | |
| 172 (event.keyCode > 111 && event.keyCode < 124); // fn keys | |
| 173 | |
| 174 return !anyNonPrintable && !(event.charCode == 0 && mozNonPrintable); | |
| 175 }, | |
| 176 | |
| 177 _onKeypress: function(event) { | |
| 178 if (!this.preventInvalidInput && this.type !== 'number') { | |
| 179 return; | |
| 180 } | |
| 181 var regexp = this._patternRegExp; | |
| 182 if (!regexp) { | |
| 183 return; | |
| 184 } | |
| 185 | |
| 186 // Handle special keys and backspace | |
| 187 if (event.metaKey || event.ctrlKey || event.altKey) | |
| 188 return; | |
| 189 | |
| 190 // Check the pattern either here or in `_onInput`, but not in both. | |
| 191 this._patternAlreadyChecked = true; | |
| 192 | |
| 193 var thisChar = String.fromCharCode(event.charCode); | |
| 194 if (this._isPrintable(event) && !regexp.test(thisChar)) { | |
| 195 event.preventDefault(); | |
| 196 } | |
| 197 }, | |
| 198 | |
| 199 _checkPatternValidity: function() { | |
| 200 var regexp = this._patternRegExp; | |
| 201 if (!regexp) { | |
| 202 return true; | |
| 203 } | |
| 204 for (var i = 0; i < this.value.length; i++) { | |
| 205 if (!regexp.test(this.value[i])) { | |
| 206 return false; | |
| 207 } | |
| 208 } | |
| 209 return true; | |
| 210 }, | |
| 211 | |
| 212 /** | |
| 213 * Returns true if `value` is valid. The validator provided in `validator` w
ill be used first, | |
| 214 * then any constraints. | |
| 215 * @return {boolean} True if the value is valid. | |
| 216 */ | |
| 217 validate: function() { | |
| 218 // Empty, non-required input is valid. | |
| 219 if (!this.required && this.value == '') { | |
| 220 this.invalid = false; | |
| 221 return true; | |
| 222 } | |
| 223 | |
| 224 var valid; | |
| 225 if (this.hasValidator()) { | |
| 226 valid = Polymer.IronValidatableBehavior.validate.call(this, this.value); | |
| 227 } else { | |
| 228 this.invalid = !this.validity.valid; | |
| 229 valid = this.validity.valid; | |
| 230 } | |
| 231 this.fire('iron-input-validate'); | |
| 232 return valid; | |
| 233 } | |
| 234 | |
| 235 }); | |
| 236 | |
| 237 /* | |
| 238 The `iron-input-validate` event is fired whenever `validate()` is called. | |
| 239 @event iron-input-validate | |
| 240 */ | |
| 241 | |
| 242 </script> | |
| OLD | NEW |