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.github.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/CONTRIBUTORS.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/PATENTS.txt
11 <link rel=
"import" href=
"../polymer/polymer.html">
12 <link rel=
"import" href=
"../iron-validatable-behavior/iron-validatable-behavior.html">
17 `<iron-input>` adds two-way binding and custom validators using `Polymer.IronValidatorBehavior`
22 By default you can only get notified of changes to an `input`'s `value` due to user input:
24 <input value="{{myValue::input}}">
26 `iron-input` adds the `bind-value` property that mirrors the `value` property, and can be used
27 for two-way data binding. `bind-value` will notify if it is changed either by user input or by script.
29 <input is="iron-input" bind-value="{{myValue}}">
33 You can use custom validators that implement `Polymer.IronValidatorBehavior` with `<iron-input>`.
35 <input is="iron-input" validator="my-custom-validator">
37 ### Stopping invalid input
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.
43 <!-- only allow characters that match [0-9] -->
44 <input is="iron-input" prevent-invalid-input allowed-pattern="[0-9]">
57 Polymer
.IronValidatableBehavior
63 * Use this property instead of `value` for two-way data binding.
66 observer
: '_bindValueChanged',
71 * Set to true to prevent the user from entering invalid input. The new input 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`).
75 preventInvalidInput
: {
80 * Regular expression to match valid input characters.
86 _previousValidInput
: {
91 _patternAlreadyChecked
: {
100 'keypress': '_onKeypress'
103 get _patternRegExp() {
105 if (this.allowedPattern
) {
106 pattern
= new RegExp(this.allowedPattern
);
107 } else if (this.pattern
) {
108 pattern
= new RegExp(this.pattern
);
112 pattern
= /[0-9.,e-]/;
120 this.bindValue
= this.value
;
123 _bindValueChanged: function() {
124 if (this.value
!== this.bindValue
) {
125 this.value
= !this.bindValue
? '' : this.bindValue
;
127 // manually notify because we don't want to notify until after setting value
128 this.fire('bind-value-changed', {value
: this.bindValue
});
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();
137 this.value
= this._previousValidInput
;
141 this.bindValue
= this.value
;
142 this._previousValidInput
= this.value
;
143 this._patternAlreadyChecked
= false;
146 _isPrintable: function(event
) {
147 // What a control/printable character is varies wildly based on the browser.
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.
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
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, home, arrows
172 (event
.keyCode
> 111 && event
.keyCode
< 124); // fn keys
174 return !anyNonPrintable
&& !(event
.charCode
== 0 && mozNonPrintable
);
177 _onKeypress: function(event
) {
178 if (!this.preventInvalidInput
&& this.type
!== 'number') {
181 var regexp
= this._patternRegExp
;
186 // Handle special keys and backspace
187 if (event
.metaKey
|| event
.ctrlKey
|| event
.altKey
)
190 // Check the pattern either here or in `_onInput`, but not in both.
191 this._patternAlreadyChecked
= true;
193 var thisChar
= String
.fromCharCode(event
.charCode
);
194 if (this._isPrintable(event
) && !regexp
.test(thisChar
)) {
195 event
.preventDefault();
199 _checkPatternValidity: function() {
200 var regexp
= this._patternRegExp
;
204 for (var i
= 0; i
< this.value
.length
; i
++) {
205 if (!regexp
.test(this.value
[i
])) {
213 * Returns true if `value` is valid. The validator provided in `validator` will be used first,
214 * then any constraints.
215 * @return {boolean} True if the value is valid.
217 validate: function() {
218 // Empty, non-required input is valid.
219 if (!this.required
&& this.value
== '') {
220 this.invalid
= false;
225 if (this.hasValidator()) {
226 valid
= Polymer
.IronValidatableBehavior
.validate
.call(this, this.value
);
228 this.invalid
= !this.validity
.valid
;
229 valid
= this.validity
.valid
;
231 this.fire('iron-input-validate');
238 The `iron-input-validate` event is fired whenever `validate()` is called.
239 @event iron-input-validate