| 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-invaild-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 var nonPrintable = |
| 158 (event.keyCode == 8) || // backspace |
| 159 (event.keyCode == 19) || // pause |
| 160 (event.keyCode == 20) || // caps lock |
| 161 (event.keyCode == 27) || // escape |
| 162 (event.keyCode == 45) || // insert |
| 163 (event.keyCode == 46) || // delete |
| 164 (event.keyCode == 144) || // num lock |
| 165 (event.keyCode == 145) || // scroll lock |
| 166 (event.keyCode > 32 && event.keyCode < 41) || // page up/down, end, ho
me, arrows |
| 167 (event.keyCode > 111 && event.keyCode < 124); // fn keys |
| 168 |
| 169 return !(event.charCode == 0 && nonPrintable); |
| 170 }, |
| 171 |
| 172 _onKeypress: function(event) { |
| 173 if (!this.preventInvalidInput && this.type !== 'number') { |
| 174 return; |
| 175 } |
| 176 var regexp = this._patternRegExp; |
| 177 if (!regexp) { |
| 178 return; |
| 179 } |
| 180 |
| 181 // Handle special keys and backspace |
| 182 if (event.metaKey || event.ctrlKey || event.altKey) |
| 183 return; |
| 184 |
| 185 // Check the pattern either here or in `_onInput`, but not in both. |
| 186 this._patternAlreadyChecked = true; |
| 187 |
| 188 var thisChar = String.fromCharCode(event.charCode); |
| 189 if (this._isPrintable(event) && !regexp.test(thisChar)) { |
| 190 event.preventDefault(); |
| 191 } |
| 192 }, |
| 193 |
| 194 _checkPatternValidity: function() { |
| 195 var regexp = this._patternRegExp; |
| 196 if (!regexp) { |
| 197 return true; |
| 198 } |
| 199 for (var i = 0; i < this.value.length; i++) { |
| 200 if (!regexp.test(this.value[i])) { |
| 201 return false; |
| 202 } |
| 203 } |
| 204 return true; |
| 205 }, |
| 206 |
| 207 /** |
| 208 * Returns true if `value` is valid. The validator provided in `validator` w
ill be used first, |
| 209 * then any constraints. |
| 210 * @return {boolean} True if the value is valid. |
| 211 */ |
| 212 validate: function() { |
| 213 // Empty, non-required input is valid. |
| 214 if (!this.required && this.value == '') { |
| 215 this.invalid = false; |
| 216 return true; |
| 217 } |
| 218 |
| 219 var valid; |
| 220 if (this.hasValidator()) { |
| 221 valid = Polymer.IronValidatableBehavior.validate.call(this, this.value); |
| 222 } else { |
| 223 this.invalid = !this.validity.valid; |
| 224 valid = this.validity.valid; |
| 225 } |
| 226 this.fire('iron-input-validate'); |
| 227 return valid; |
| 228 } |
| 229 |
| 230 }); |
| 231 |
| 232 /* |
| 233 The `iron-input-validate` event is fired whenever `validate()` is called. |
| 234 @event iron-input-validate |
| 235 */ |
| 236 |
| 237 </script> |
| OLD | NEW |