| OLD | NEW |
| (Empty) |
| 1 <!-- | |
| 2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | |
| 3 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE | |
| 4 The complete set of authors may be found at http://polymer.github.io/AUTHORS | |
| 5 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS | |
| 6 Code distributed by Google as part of the polymer project is also | |
| 7 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS | |
| 8 --> | |
| 9 | |
| 10 <!-- | |
| 11 /** | |
| 12 * core-input is an unstyled single- or multi-line text field where user can | |
| 13 * enter input. | |
| 14 * | |
| 15 * Example: | |
| 16 * | |
| 17 * <core-input placeholder="Placeholder text here"></core-input> | |
| 18 * | |
| 19 * <core-input multiline placeholder="Enter multiple lines here"></core-inpu
t> | |
| 20 * | |
| 21 * The text input's value is considered "committed" if the user hits the "enter" | |
| 22 * key or blurs the input after changing the value. The `change` event is fired | |
| 23 * when the value becomes committed, and the committed value is stored in the | |
| 24 * `value` property. The current value of the input is stored in the `inputValue
` | |
| 25 * property. | |
| 26 * | |
| 27 * Validation | |
| 28 * ---------- | |
| 29 * | |
| 30 * core-input can optionally validate the value using the HTML5 constraints API, | |
| 31 * similar to native inputs. There are two methods to configure input validation
: | |
| 32 * | |
| 33 * 1. By setting the `type` attribute. For example, setting it to `email` will | |
| 34 * check the value is a valid email, and setting it to `number` will check | |
| 35 * the input is a number. | |
| 36 * | |
| 37 * 2. By setting attributes related to validation. The attributes are `pattern`, | |
| 38 * `min`, `max`, `step` and `required`. | |
| 39 * | |
| 40 * Only `required` is supported for multiline inputs currently. | |
| 41 * | |
| 42 * Example: | |
| 43 * | |
| 44 * <core-input type="email" placeholder="enter your email"></core-input> | |
| 45 * | |
| 46 * <core-input type="number" min="5" placeholder="enter a number greater tha
n or equal to 5"></core-input> | |
| 47 * | |
| 48 * <core-input pattern=".*abc.*" placeholder="enter something containing 'ab
c'"></core-input> | |
| 49 * | |
| 50 * See https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_
validation | |
| 51 * for more info on validation. | |
| 52 * | |
| 53 * @group Polymer Core Elements | |
| 54 * @element core-input | |
| 55 * @homepage github.io | |
| 56 */ | |
| 57 --> | |
| 58 | |
| 59 <!-- | |
| 60 Fired when the inputValue of is changed. This is the same event as the DOM | |
| 61 "input" event. | |
| 62 | |
| 63 @event input | |
| 64 --> | |
| 65 | |
| 66 <!-- | |
| 67 Fired when the user commits the value of the input, either by the hitting the | |
| 68 `enter` key or blurring the input after the changing the inputValue. Also see th
e | |
| 69 DOM "change" event. | |
| 70 | |
| 71 @event change | |
| 72 --> | |
| 73 | |
| 74 <!-- | |
| 75 Fired when the inputValue of this text input changes and fails validation. | |
| 76 | |
| 77 @event input-invalid | |
| 78 @param {Object} detail | |
| 79 @param {string} value The text input's inputValue. | |
| 80 --> | |
| 81 | |
| 82 <!-- | |
| 83 Fired when the inputValue of this text input changes and passes validation. | |
| 84 | |
| 85 @event input-valid | |
| 86 @param {Object} detail | |
| 87 @param {string} value The text input's inputValue. | |
| 88 --> | |
| 89 <link href="../polymer/polymer.html" rel="import"> | |
| 90 | |
| 91 <polymer-element name="core-input" on-focus="{{focusAction}}"> | |
| 92 | |
| 93 <template> | |
| 94 | |
| 95 <link href="core-input.css" rel="stylesheet"> | |
| 96 | |
| 97 <template if="{{multiline}}"> | |
| 98 <textarea id="input" value="{{inputValue}}" rows="{{rows}}" disabled?="{{d
isabled}}" placeholder="{{placeholder}}" autofocus?="{{autofocus}}" required?="{
{required}}" readonly?="{{readonly}}" maxlength="{{maxlength}}" aria-label="{{la
bel || placeholder}}" aria-invalid="{{invalid}}" on-change="{{inputChangeAction}
}" on-focus="{{inputFocusAction}}" on-blur="{{inputBlurAction}}"></textarea> | |
| 99 </template> | |
| 100 | |
| 101 <template if="{{!multiline}}"> | |
| 102 <input id="input" value="{{inputValue}}" disabled?="{{disabled}}" type="{{
type}}" placeholder="{{placeholder}}" autofocus?="{{autofocus}}" required?="{{re
quired}}" readonly?="{{readonly}}" pattern="{{pattern}}" min="{{min}}" max="{{ma
x}}" step="{{step}}" maxlength="{{maxlength}}" aria-label="{{label || placeholde
r}}" aria-invalid="{{invalid}}" on-keypress="{{keypressAction}}" on-change="{{in
putChangeAction}}" on-focus="{{inputFocusAction}}" on-blur="{{inputBlurAction}}"
> | |
| 103 </template> | |
| 104 | |
| 105 </template> | |
| 106 | |
| 107 <script> | |
| 108 | |
| 109 Polymer('core-input', { | |
| 110 publish: { | |
| 111 /** | |
| 112 * Placeholder text that hints to the user what can be entered in | |
| 113 * the input. | |
| 114 * | |
| 115 * @attribute placeholder | |
| 116 * @type string | |
| 117 * @default '' | |
| 118 */ | |
| 119 placeholder: '', | |
| 120 | |
| 121 /** | |
| 122 * If true, this input cannot be focused and the user cannot change | |
| 123 * its value. | |
| 124 * | |
| 125 * @attribute disabled | |
| 126 * @type boolean | |
| 127 * @default false | |
| 128 */ | |
| 129 disabled: false, | |
| 130 | |
| 131 /** | |
| 132 * If true, the user cannot modify the value of the input. | |
| 133 * | |
| 134 * @attribute readonly | |
| 135 * @type boolean | |
| 136 * @default false | |
| 137 */ | |
| 138 readonly: false, | |
| 139 | |
| 140 /** | |
| 141 * If true, this input will automatically gain focus on page load. | |
| 142 * | |
| 143 * @attribute autofocus | |
| 144 * @type boolean | |
| 145 * @default false | |
| 146 */ | |
| 147 autofocus: false, | |
| 148 | |
| 149 /** | |
| 150 * If true, this input accepts multi-line input like a `<textarea>` | |
| 151 * | |
| 152 * @attribute multiline | |
| 153 * @type boolean | |
| 154 * @default false | |
| 155 */ | |
| 156 multiline: false, | |
| 157 | |
| 158 /** | |
| 159 * (multiline only) The height of this text input in rows. The input | |
| 160 * will scroll internally if more input is entered beyond the size | |
| 161 * of the component. This property is meaningless if multiline is | |
| 162 * false. You can also set this property to "fit" and size the | |
| 163 * component with CSS to make the input fit the CSS size. | |
| 164 * | |
| 165 * @attribute rows | |
| 166 * @type number|'fit' | |
| 167 * @default 'fit' | |
| 168 */ | |
| 169 rows: 'fit', | |
| 170 | |
| 171 /** | |
| 172 * The current value of this input. Changing inputValue programmatically | |
| 173 * will cause value to be out of sync. Instead, change value directly | |
| 174 * or call commit() after changing inputValue. | |
| 175 * | |
| 176 * @attribute inputValue | |
| 177 * @type string | |
| 178 * @default '' | |
| 179 */ | |
| 180 inputValue: '', | |
| 181 | |
| 182 /** | |
| 183 * The value of the input committed by the user, either by changing the | |
| 184 * inputValue and blurring the input, or by hitting the `enter` key. | |
| 185 * | |
| 186 * @attribute value | |
| 187 * @type string | |
| 188 * @default '' | |
| 189 */ | |
| 190 value: '', | |
| 191 | |
| 192 /** | |
| 193 * Set the input type. Not supported for `multiline`. | |
| 194 * | |
| 195 * @attribute type | |
| 196 * @type string | |
| 197 * @default text | |
| 198 */ | |
| 199 type: 'text', | |
| 200 | |
| 201 /** | |
| 202 * If true, the input is invalid if its value is null. | |
| 203 * | |
| 204 * @attribute required | |
| 205 * @type boolean | |
| 206 * @default false | |
| 207 */ | |
| 208 required: false, | |
| 209 | |
| 210 /** | |
| 211 * A regular expression to validate the input value against. See | |
| 212 * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constra
int_validation#Validation-related_attributes | |
| 213 * for more info. Not supported if `multiline` is true. | |
| 214 * | |
| 215 * @attribute pattern | |
| 216 * @type string | |
| 217 * @default '.*' | |
| 218 */ | |
| 219 // FIXME(yvonne): The default is set to .* because we can't bind to patt
ern such | |
| 220 // that the attribute is unset if pattern is null. | |
| 221 pattern: '.*', | |
| 222 | |
| 223 /** | |
| 224 * If set, the input is invalid if the value is less than this property.
See | |
| 225 * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constra
int_validation#Validation-related_attributes | |
| 226 * for more info. Not supported if `multiline` is true. | |
| 227 * | |
| 228 * @attribute min | |
| 229 */ | |
| 230 min: null, | |
| 231 | |
| 232 /** | |
| 233 * If set, the input is invalid if the value is greater than this proper
ty. See | |
| 234 * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constra
int_validation#Validation-related_attributes | |
| 235 * for more info. Not supported if `multiline` is true. | |
| 236 * | |
| 237 * @attribute max | |
| 238 */ | |
| 239 max: null, | |
| 240 | |
| 241 /** | |
| 242 * If set, the input is invalid if the value is not `min` plus an integr
al multiple | |
| 243 * of this property. See | |
| 244 * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constra
int_validation#Validation-related_attributes | |
| 245 * for more info. Not supported if `multiline` is true. | |
| 246 * | |
| 247 * @attribute step | |
| 248 */ | |
| 249 step: null, | |
| 250 | |
| 251 /** | |
| 252 * The maximum length of the input value. | |
| 253 * | |
| 254 * @attribute maxlength | |
| 255 * @type number | |
| 256 */ | |
| 257 maxlength: null, | |
| 258 | |
| 259 /** | |
| 260 * If this property is true, the text input's inputValue failed validati
on. | |
| 261 * | |
| 262 * @attribute invalid | |
| 263 * @type boolean | |
| 264 * @default false | |
| 265 */ | |
| 266 invalid: false, | |
| 267 | |
| 268 /** | |
| 269 * If this property is true, validate the input as they are entered. | |
| 270 * | |
| 271 * @attribute validateImmediately | |
| 272 * @type boolean | |
| 273 * @default true | |
| 274 */ | |
| 275 validateImmediately: true | |
| 276 }, | |
| 277 | |
| 278 ready: function() { | |
| 279 this.handleTabindex(this.getAttribute('tabindex')); | |
| 280 }, | |
| 281 | |
| 282 disabledChanged: function() { | |
| 283 if (this.disabled) { | |
| 284 this.setAttribute('aria-disabled', true); | |
| 285 } else { | |
| 286 this.removeAttribute('aria-disabled'); | |
| 287 } | |
| 288 }, | |
| 289 | |
| 290 invalidChanged: function() { | |
| 291 this.classList.toggle('invalid', this.invalid); | |
| 292 this.fire('input-'+ (this.invalid ? 'invalid' : 'valid'), {value: this.i
nputValue}); | |
| 293 }, | |
| 294 | |
| 295 inputValueChanged: function() { | |
| 296 if (this.validateImmediately) { | |
| 297 this.updateValidity_(); | |
| 298 } | |
| 299 }, | |
| 300 | |
| 301 valueChanged: function() { | |
| 302 this.inputValue = this.value; | |
| 303 }, | |
| 304 | |
| 305 requiredChanged: function() { | |
| 306 if (this.validateImmediately) { | |
| 307 this.updateValidity_(); | |
| 308 } | |
| 309 }, | |
| 310 | |
| 311 attributeChanged: function(attr, oldVal, curVal) { | |
| 312 if (attr === 'tabindex') { | |
| 313 this.handleTabindex(curVal); | |
| 314 } | |
| 315 }, | |
| 316 | |
| 317 handleTabindex: function(tabindex) { | |
| 318 if (tabindex > 0) { | |
| 319 this.$.input.setAttribute('tabindex', -1); | |
| 320 } else { | |
| 321 this.$.input.removeAttribute('tabindex'); | |
| 322 } | |
| 323 }, | |
| 324 | |
| 325 /** | |
| 326 * Commits the inputValue to value. | |
| 327 * | |
| 328 * @method commit | |
| 329 */ | |
| 330 commit: function() { | |
| 331 this.value = this.inputValue; | |
| 332 }, | |
| 333 | |
| 334 updateValidity_: function() { | |
| 335 if (this.$.input.willValidate) { | |
| 336 this.invalid = !this.$.input.validity.valid; | |
| 337 } | |
| 338 }, | |
| 339 | |
| 340 keypressAction: function(e) { | |
| 341 // disallow non-numeric input if type = number | |
| 342 if (this.type !== 'number') { | |
| 343 return; | |
| 344 } | |
| 345 var c = String.fromCharCode(e.charCode); | |
| 346 if (e.charCode !== 0 && !c.match(/[\d-\.e]/)) { | |
| 347 e.preventDefault(); | |
| 348 } | |
| 349 }, | |
| 350 | |
| 351 inputChangeAction: function() { | |
| 352 this.commit(); | |
| 353 if (!window.ShadowDOMPolyfill) { | |
| 354 // re-fire event that does not bubble across shadow roots | |
| 355 this.fire('change', null, this); | |
| 356 } | |
| 357 }, | |
| 358 | |
| 359 focusAction: function(e) { | |
| 360 if (this.getAttribute('tabindex') > 0) { | |
| 361 // Forward focus to the inner input if tabindex is set on the element | |
| 362 // This will not cause an infinite loop because focus will not fire on
the <input> | |
| 363 // again if it's already focused. | |
| 364 this.$.input.focus(); | |
| 365 } | |
| 366 }, | |
| 367 | |
| 368 inputFocusAction: function(e) { | |
| 369 if (window.ShadowDOMPolyfill) { | |
| 370 // re-fire non-bubbling event if polyfill | |
| 371 this.fire('focus', null, this, false); | |
| 372 } | |
| 373 }, | |
| 374 | |
| 375 inputBlurAction: function() { | |
| 376 if (window.ShadowDOMPolyfill) { | |
| 377 // re-fire non-bubbling event | |
| 378 this.fire('blur', null, this, false); | |
| 379 } | |
| 380 }, | |
| 381 | |
| 382 /** | |
| 383 * Forwards to the internal input / textarea element. | |
| 384 * | |
| 385 * @method blur | |
| 386 */ | |
| 387 blur: function() { | |
| 388 this.$.input.blur(); | |
| 389 }, | |
| 390 | |
| 391 /** | |
| 392 * Forwards to the internal input / textarea element. | |
| 393 * | |
| 394 * @method click | |
| 395 */ | |
| 396 click: function() { | |
| 397 this.$.input.click(); | |
| 398 }, | |
| 399 | |
| 400 /** | |
| 401 * Forwards to the internal input / textarea element. | |
| 402 * | |
| 403 * @method focus | |
| 404 */ | |
| 405 focus: function() { | |
| 406 this.$.input.focus(); | |
| 407 }, | |
| 408 | |
| 409 /** | |
| 410 * Forwards to the internal input / textarea element. | |
| 411 * | |
| 412 * @method select | |
| 413 */ | |
| 414 select: function() { | |
| 415 this.$.input.select(); | |
| 416 }, | |
| 417 | |
| 418 /** | |
| 419 * Forwards to the internal input / textarea element. | |
| 420 * | |
| 421 * @method setSelectionRange | |
| 422 * @param {number} selectionStart | |
| 423 * @param {number} selectionEnd | |
| 424 * @param {String} selectionDirection (optional) | |
| 425 */ | |
| 426 setSelectionRange: function(selectionStart, selectionEnd, selectionDirecti
on) { | |
| 427 this.$.input.setSelectionRange(selectionStart, selectionEnd, selectionDi
rection); | |
| 428 }, | |
| 429 | |
| 430 /** | |
| 431 * Forwards to the internal input element, not implemented for multiline. | |
| 432 * | |
| 433 * @method setRangeText | |
| 434 * @param {String} replacement | |
| 435 * @param {number} start (optional) | |
| 436 * @param {number} end (optional) | |
| 437 * @param {String} selectMode (optional) | |
| 438 */ | |
| 439 setRangeText: function(replacement, start, end, selectMode) { | |
| 440 if (!this.multiline) { | |
| 441 this.$.input.setRangeText(replacement, start, end, selectMode); | |
| 442 } | |
| 443 }, | |
| 444 | |
| 445 /** | |
| 446 * Forwards to the internal input, not implemented for multiline. | |
| 447 * | |
| 448 * @method stepDown | |
| 449 * @param {number} n (optional) | |
| 450 */ | |
| 451 stepDown: function(n) { | |
| 452 if (!this.multiline) { | |
| 453 this.$.input.stepDown(n); | |
| 454 } | |
| 455 }, | |
| 456 | |
| 457 /** | |
| 458 * Forwards to the internal input, not implemented for multiline. | |
| 459 * | |
| 460 * @method stepUp | |
| 461 * @param {number} n (optional) | |
| 462 */ | |
| 463 stepUp: function(n) { | |
| 464 if (!this.multiline) { | |
| 465 this.$.input.stepUp(n); | |
| 466 } | |
| 467 }, | |
| 468 | |
| 469 get willValidate() { | |
| 470 return this.$.input.willValidate; | |
| 471 }, | |
| 472 | |
| 473 get validity() { | |
| 474 return this.$.input.validity; | |
| 475 }, | |
| 476 | |
| 477 get validationMessage() { | |
| 478 return this.$.input.validationMessage; | |
| 479 }, | |
| 480 | |
| 481 /** | |
| 482 * Forwards to the internal input / textarea element and updates state. | |
| 483 * | |
| 484 * @method checkValidity | |
| 485 * @return {boolean} | |
| 486 */ | |
| 487 checkValidity: function() { | |
| 488 var r = this.$.input.checkValidity(); | |
| 489 this.updateValidity_(); | |
| 490 return r; | |
| 491 }, | |
| 492 | |
| 493 /** | |
| 494 * Forwards to the internal input / textarea element and updates state. | |
| 495 * | |
| 496 * @method setCustomValidity | |
| 497 * @param {String} message | |
| 498 */ | |
| 499 setCustomValidity: function(message) { | |
| 500 this.$.input.setCustomValidity(message); | |
| 501 this.updateValidity_(); | |
| 502 } | |
| 503 | |
| 504 }); | |
| 505 </script> | |
| 506 | |
| 507 </polymer-element> | |
| OLD | NEW |