4 * Use `Polymer.PaperInputBehavior` to implement inputs with `<paper-input-container>`. This
5 * behavior is implemented by `<paper-input>`. It exposes a number of properties from
6 * `<paper-input-container>` and `<input is="iron-input">` and they should be bound in your
9 * The input element can be accessed by the `inputElement` property if you need to access
10 * properties or methods that are not exposed.
11 * @polymerBehavior Polymer.PaperInputBehavior
13 Polymer.PaperInputBehaviorImpl = {
18 * The label for this input. Bind this to `<paper-input-container>`'s `label` property.
25 * The value for this input. Bind this to the `<input is="iron-input">`'s `bindValue`
26 * property, or the value property of your input that is `notify:true`.
34 * Set to true to disable this input. Bind this to both the `<paper-input-container>`'s
35 * and the input's `disabled` property.
43 * Returns true if the value is invalid. Bind this to both the `<paper-input-container>`'s
44 * and the input's `invalid` property.
52 * Set to true to prevent the user from entering invalid input. Bind this to the
53 * `<input is="iron-input">`'s `preventInvalidInput` property.
55 preventInvalidInput: {
60 * Set this to specify the pattern allowed by `preventInvalidInput`. Bind this to the
61 * `<input is="iron-input">`'s `allowedPattern` property.
68 * The type of the input. The supported types are `text`, `number` and `password`. Bind this
69 * to the `<input is="iron-input">`'s `type` property.
76 * The datalist of the input (if any). This should match the id of an existing <datalist>. Bind this
77 * to the `<input is="iron-input">`'s `list` property.
84 * A pattern to validate the `input` with. Bind this to the `<input is="iron-input">`'s
92 * Set to true to mark the input as required. Bind this to the `<input is="iron-input">`'s
93 * `required` property.
101 * The maximum length of the input value. Bind this to the `<input is="iron-input">`'s
102 * `maxlength` property.
109 * The error message to display when the input is invalid. Bind this to the
110 * `<paper-input-error>`'s content, if using.
117 * Set to true to show a character counter.
125 * Set to true to disable the floating label. Bind this to the `<paper-input-container>`'s
126 * `noLabelFloat` property.
134 * Set to true to always float the label. Bind this to the `<paper-input-container>`'s
135 * `alwaysFloatLabel` property.
143 * Set to true to auto-validate the input value. Bind this to the `<paper-input-container>`'s
144 * `autoValidate` property.
152 * Name of the validator to use. Bind this to the `<input is="iron-input">`'s `validator`
159 // HTMLInputElement attributes for binding if needed
162 * Bind this to the `<input is="iron-input">`'s `autocomplete` property.
170 * Bind this to the `<input is="iron-input">`'s `autofocus` property.
177 * Bind this to the `<input is="iron-input">`'s `inputmode` property.
184 * Bind this to the `<input is="iron-input">`'s `minlength` property.
191 * Bind this to the `<input is="iron-input">`'s `name` property.
198 * A placeholder string in addition to the label. If this is set, the label will always float.
202 // need to set a default so _computeAlwaysFloatLabel is run
207 * Bind this to the `<input is="iron-input">`'s `readonly` property.
215 * Bind this to the `<input is="iron-input">`'s `size` property.
221 // Nonstandard attributes for binding if needed
224 * Bind this to the `<input is="iron-input">`'s `autocapitalize` property.
232 * Bind this to the `<input is="iron-input">`'s `autocorrect` property.
247 'addon-attached': '_onAddonAttached'
251 '_focusedControlStateChanged(focused)'
255 * Returns a reference to the input element.
261 attached: function() {
262 this._updateAriaLabelledBy();
265 _appendStringWithSpace: function(str, more) {
267 str = str + ' ' + more;
274 _onAddonAttached: function(event) {
275 var target = event.path ? event.path[0] : event.target;
277 this._ariaDescribedBy = this._appendStringWithSpace(this._ariaDescribedBy, target.id);
279 var id = 'paper-input-add-on-' + Math.floor((Math.random() * 100000));
281 this._ariaDescribedBy = this._appendStringWithSpace(this._ariaDescribedBy, id);
286 * Validates the input element and sets an error style if needed.
288 validate: function() {
289 return this.inputElement.validate();
293 * Restores the cursor to its original position after updating the value.
294 * @param {string} newValue The value that should be saved.
296 updateValueAndPreserveCaret: function(newValue) {
297 // Not all elements might have selection, and even if they have the
298 // right properties, accessing them might throw an exception (like for
299 // <input type=number>)
301 var start = this.inputElement.selectionStart;
302 this.value = newValue;
304 // The cursor automatically jumps to the end after re-setting the value,
305 // so restore it to its original position.
306 this.inputElement.selectionStart = start;
307 this.inputElement.selectionEnd = start;
309 // Just set the value and give up on the caret.
310 this.value = newValue;
314 _computeAlwaysFloatLabel: function(alwaysFloatLabel, placeholder) {
315 return placeholder || alwaysFloatLabel;
318 _focusedControlStateChanged: function(focused) {
319 // IronControlState stops the focus and blur events in order to redispatch them on the host
320 // element, but paper-input-container listens to those events. Since there are more
321 // pending work on focus/blur in IronControlState, I'm putting in this hack to get the
322 // input focus state working for now.
323 if (!this.$.container) {
324 this.$.container = Polymer.dom(this.root).querySelector('paper-input-container');
325 if (!this.$.container) {
330 this.$.container._onFocus();
332 this.$.container._onBlur();
336 _updateAriaLabelledBy: function() {
337 var label = Polymer.dom(this.root).querySelector('label');
339 this._ariaLabelledBy = '';
344 labelledBy = label.id;
346 labelledBy = 'paper-input-label-' + new Date().getUTCMilliseconds();
347 label.id = labelledBy;
349 this._ariaLabelledBy = labelledBy;
354 /** @polymerBehavior */
355 Polymer.PaperInputBehavior = [Polymer.IronControlState, Polymer.PaperInputBehaviorImpl];