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
10 <link rel=
"import" href=
"../polymer/polymer.html">
11 <link rel=
"import" href=
"../iron-behaviors/iron-control-state.html">
16 * Use `Polymer.PaperInputBehavior` to implement inputs with `<paper-input-container>`. This
17 * behavior is implemented by `<paper-input>`. It exposes a number of properties from
18 * `<paper-input-container>` and `<input is="iron-input">` and they should be bound in your
21 * The input element can be accessed by the `inputElement` property if you need to access
22 * properties or methods that are not exposed.
23 * @polymerBehavior Polymer.PaperInputBehavior
25 Polymer
.PaperInputBehaviorImpl
= {
30 * The label for this input. Bind this to `<paper-input-container>`'s `label` property.
37 * The value for this input. Bind this to the `<input is="iron-input">`'s `bindValue`
38 * property, or the value property of your input that is `notify:true`.
46 * Set to true to disable this input. Bind this to both the `<paper-input-container>`'s
47 * and the input's `disabled` property.
55 * Returns true if the value is invalid. Bind this to both the `<paper-input-container>`'s
56 * and the input's `invalid` property.
64 * Set to true to prevent the user from entering invalid input. Bind this to the
65 * `<input is="iron-input">`'s `preventInvalidInput` property.
67 preventInvalidInput
: {
72 * Set this to specify the pattern allowed by `preventInvalidInput`. Bind this to the
73 * `<input is="iron-input">`'s `allowedPattern` property.
80 * The type of the input. The supported types are `text`, `number` and `password`. Bind this
81 * to the `<input is="iron-input">`'s `type` property.
88 * The datalist of the input (if any). This should match the id of an existing <datalist>. Bind this
89 * to the `<input is="iron-input">`'s `list` property.
96 * A pattern to validate the `input` with. Bind this to the `<input is="iron-input">`'s
104 * Set to true to mark the input as required. Bind this to the `<input is="iron-input">`'s
105 * `required` property.
113 * The maximum length of the input value. Bind this to the `<input is="iron-input">`'s
114 * `maxlength` property.
121 * The error message to display when the input is invalid. Bind this to the
122 * `<paper-input-error>`'s content, if using.
129 * Set to true to show a character counter.
137 * Set to true to disable the floating label. Bind this to the `<paper-input-container>`'s
138 * `noLabelFloat` property.
146 * Set to true to always float the label. Bind this to the `<paper-input-container>`'s
147 * `alwaysFloatLabel` property.
155 * Set to true to auto-validate the input value. Bind this to the `<paper-input-container>`'s
156 * `autoValidate` property.
164 * Name of the validator to use. Bind this to the `<input is="iron-input">`'s `validator`
171 // HTMLInputElement attributes for binding if needed
174 * Bind this to the `<input is="iron-input">`'s `autocomplete` property.
182 * Bind this to the `<input is="iron-input">`'s `autofocus` property.
189 * Bind this to the `<input is="iron-input">`'s `inputmode` property.
196 * Bind this to the `<input is="iron-input">`'s `minlength` property.
203 * Bind this to the `<input is="iron-input">`'s `name` property.
210 * A placeholder string in addition to the label. If this is set, the label will always float.
214 // need to set a default so _computeAlwaysFloatLabel is run
219 * Bind this to the `<input is="iron-input">`'s `readonly` property.
227 * Bind this to the `<input is="iron-input">`'s `size` property.
233 // Nonstandard attributes for binding if needed
236 * Bind this to the `<input is="iron-input">`'s `autocapitalize` property.
244 * Bind this to the `<input is="iron-input">`'s `autocorrect` property.
259 'addon-attached': '_onAddonAttached'
263 '_focusedControlStateChanged(focused)'
267 * Returns a reference to the input element.
273 attached: function() {
274 this._updateAriaLabelledBy();
277 _appendStringWithSpace: function(str
, more
) {
279 str
= str
+ ' ' + more
;
286 _onAddonAttached: function(event
) {
287 var target
= event
.path
? event
.path
[0] : event
.target
;
289 this._ariaDescribedBy
= this._appendStringWithSpace(this._ariaDescribedBy
, target
.id
);
291 var id
= 'paper-input-add-on-' + Math
.floor((Math
.random() * 100000));
293 this._ariaDescribedBy
= this._appendStringWithSpace(this._ariaDescribedBy
, id
);
298 * Validates the input element and sets an error style if needed.
300 validate: function() {
301 return this.inputElement
.validate();
305 * Restores the cursor to its original position after updating the value.
306 * @param {string} newValue The value that should be saved.
308 updateValueAndPreserveCaret: function(newValue
) {
309 // Not all elements might have selection, and even if they have the
310 // right properties, accessing them might throw an exception (like for
311 // <input type=number>)
313 var start
= this.inputElement
.selectionStart
;
314 this.value
= newValue
;
316 // The cursor automatically jumps to the end after re-setting the value,
317 // so restore it to its original position.
318 this.inputElement
.selectionStart
= start
;
319 this.inputElement
.selectionEnd
= start
;
321 // Just set the value and give up on the caret.
322 this.value
= newValue
;
326 _computeAlwaysFloatLabel: function(alwaysFloatLabel
, placeholder
) {
327 return placeholder
|| alwaysFloatLabel
;
330 _focusedControlStateChanged: function(focused
) {
331 // IronControlState stops the focus and blur events in order to redispatch them on the host
332 // element, but paper-input-container listens to those events. Since there are more
333 // pending work on focus/blur in IronControlState, I'm putting in this hack to get the
334 // input focus state working for now.
335 if (!this.$.container
) {
336 this.$.container
= Polymer
.dom(this.root
).querySelector('paper-input-container');
337 if (!this.$.container
) {
342 this.$.container
._onFocus();
344 this.$.container
._onBlur();
348 _updateAriaLabelledBy: function() {
349 var label
= Polymer
.dom(this.root
).querySelector('label');
351 this._ariaLabelledBy
= '';
356 labelledBy
= label
.id
;
358 labelledBy
= 'paper-input-label-' + new Date().getUTCMilliseconds();
359 label
.id
= labelledBy
;
361 this._ariaLabelledBy
= labelledBy
;
366 /** @polymerBehavior */
367 Polymer
.PaperInputBehavior
= [Polymer
.IronControlState
, Polymer
.PaperInputBehaviorImpl
];