OLD | NEW |
1 | 1 |
2 (function() { | 2 (function() { |
3 | 3 |
4 Polymer({ | 4 Polymer({ |
5 | 5 |
6 is: 'paper-input-container', | 6 is: 'paper-input-container', |
7 | 7 |
8 enableCustomStyleProperties: true, | |
9 | |
10 properties: { | 8 properties: { |
11 | 9 |
12 /** | 10 /** |
13 * Set to true to disable the floating label. | 11 * Set to true to disable the floating label. The label disappears when th
e input value is |
| 12 * not null. |
14 */ | 13 */ |
15 noLabelFloat: { | 14 noLabelFloat: { |
16 type: Boolean, | 15 type: Boolean, |
17 value: false | 16 value: false |
18 }, | 17 }, |
19 | 18 |
20 /** | 19 /** |
| 20 * Set to true to always float the floating label. |
| 21 */ |
| 22 alwaysFloatLabel: { |
| 23 type: Boolean, |
| 24 value: false |
| 25 }, |
| 26 |
| 27 /** |
21 * The attribute to listen for value changes on. | 28 * The attribute to listen for value changes on. |
22 */ | 29 */ |
23 attrForValue: { | 30 attrForValue: { |
24 type: String, | 31 type: String, |
25 value: 'bind-value' | 32 value: 'bind-value' |
26 }, | 33 }, |
27 | 34 |
28 /** | 35 /** |
29 * Set to true to auto-validate the input value. | 36 * Set to true to auto-validate the input value when it changes. |
30 */ | 37 */ |
31 autoValidate: { | 38 autoValidate: { |
32 type: Boolean, | 39 type: Boolean, |
33 value: false | 40 value: false |
34 }, | 41 }, |
35 | 42 |
36 /** | 43 /** |
| 44 * True if the input is invalid. This property is set automatically when t
he input value |
| 45 * changes if auto-validating, or when the `iron-input-valid` event is hea
rd from a child. |
| 46 */ |
| 47 invalid: { |
| 48 observer: '_invalidChanged', |
| 49 type: Boolean, |
| 50 value: false |
| 51 }, |
| 52 |
| 53 /** |
37 * True if the input has focus. | 54 * True if the input has focus. |
38 */ | 55 */ |
39 focused: { | 56 focused: { |
40 readOnly: true, | 57 readOnly: true, |
41 type: Boolean, | 58 type: Boolean, |
42 value: false | 59 value: false |
43 }, | 60 }, |
44 | 61 |
45 _addons: { | 62 _addons: { |
46 type: Array, | 63 type: Array, |
47 value: function() { | 64 value: function() { |
48 return []; | 65 return []; |
49 } | 66 } |
50 }, | 67 }, |
51 | 68 |
52 _inputHasContent: { | 69 _inputHasContent: { |
53 type: Boolean, | 70 type: Boolean, |
54 value: false | 71 value: false |
55 }, | 72 }, |
56 | 73 |
57 _inputIsInvalid: { | |
58 type: Boolean, | |
59 value: false | |
60 }, | |
61 | |
62 _inputSelector: { | 74 _inputSelector: { |
63 type: String, | 75 type: String, |
64 value: 'input,textarea,.paper-input-input' | 76 value: 'input,textarea,.paper-input-input' |
65 }, | 77 }, |
66 | 78 |
67 _boundOnFocus: { | 79 _boundOnFocus: { |
68 type: Function, | 80 type: Function, |
69 value: function() { | 81 value: function() { |
70 return this._onFocus.bind(this); | 82 return this._onFocus.bind(this); |
71 } | 83 } |
72 }, | 84 }, |
73 | 85 |
74 _boundOnBlur: { | 86 _boundOnBlur: { |
75 type: Function, | 87 type: Function, |
76 value: function() { | 88 value: function() { |
77 return this._onBlur.bind(this); | 89 return this._onBlur.bind(this); |
78 } | 90 } |
79 }, | 91 }, |
80 | 92 |
| 93 _boundOnInput: { |
| 94 type: Function, |
| 95 value: function() { |
| 96 this._onInput.bind(this) |
| 97 } |
| 98 }, |
| 99 |
81 _boundValueChanged: { | 100 _boundValueChanged: { |
82 type: Function, | 101 type: Function, |
83 value: function() { | 102 value: function() { |
84 return this._onValueChanged.bind(this); | 103 return this._onValueChanged.bind(this); |
85 } | 104 } |
86 } | 105 } |
87 | 106 |
88 }, | 107 }, |
89 | 108 |
90 listeners: { | 109 listeners: { |
91 'addon-attached': '_onAddonAttached', | 110 'addon-attached': '_onAddonAttached', |
92 'input': '_onInput' | 111 'iron-input-validate': '_onIronInputValidate' |
93 }, | 112 }, |
94 | 113 |
95 get _valueChangedEvent() { | 114 get _valueChangedEvent() { |
96 return this.attrForValue + '-changed'; | 115 return this.attrForValue + '-changed'; |
97 }, | 116 }, |
98 | 117 |
99 get _propertyForValue() { | 118 get _propertyForValue() { |
100 return Polymer.CaseMap.dashToCamelCase(this.attrForValue); | 119 return Polymer.CaseMap.dashToCamelCase(this.attrForValue); |
101 }, | 120 }, |
102 | 121 |
103 get _inputElement() { | 122 get _inputElement() { |
104 return Polymer.dom(this).querySelector(this._inputSelector); | 123 return Polymer.dom(this).querySelector(this._inputSelector); |
105 }, | 124 }, |
106 | 125 |
107 ready: function() { | 126 ready: function() { |
108 this.addEventListener('focus', this._boundOnFocus, true); | 127 this.addEventListener('focus', this._boundOnFocus, true); |
109 this.addEventListener('blur', this._boundOnBlur, true); | 128 this.addEventListener('blur', this._boundOnBlur, true); |
110 this.addEventListener(this._valueChangedEvent, this._boundValueChanged, tr
ue); | 129 if (this.attrForValue) { |
| 130 this._inputElement.addEventListener(this._valueChangedEvent, this._bound
ValueChanged); |
| 131 } else { |
| 132 this.addEventListener('input', this._onInput); |
| 133 } |
111 }, | 134 }, |
112 | 135 |
113 attached: function() { | 136 attached: function() { |
114 this._handleInput(this._inputElement); | 137 this._handleValue(this._inputElement); |
115 }, | 138 }, |
116 | 139 |
117 _onAddonAttached: function(event) { | 140 _onAddonAttached: function(event) { |
118 this._addons.push(event.target); | 141 this._addons.push(event.target); |
119 this._handleInput(this._inputElement); | 142 this._handleValue(this._inputElement); |
120 }, | 143 }, |
121 | 144 |
122 _onFocus: function() { | 145 _onFocus: function() { |
123 this._setFocused(true); | 146 this._setFocused(true); |
124 }, | 147 }, |
125 | 148 |
126 _onBlur: function() { | 149 _onBlur: function() { |
127 this._setFocused(false); | 150 this._setFocused(false); |
128 }, | 151 }, |
129 | 152 |
130 _onInput: function(event) { | 153 _onInput: function(event) { |
131 this._handleInput(event.target); | 154 this._handleValue(event.target); |
132 }, | 155 }, |
133 | 156 |
134 _onValueChanged: function(event) { | 157 _onValueChanged: function(event) { |
135 this._handleInput(event.target); | 158 this._handleValue(event.target); |
136 }, | 159 }, |
137 | 160 |
138 _handleInput: function(inputElement) { | 161 _handleValue: function(inputElement) { |
139 var value = inputElement[this._propertyForValue] || inputElement.value; | 162 var value = inputElement[this._propertyForValue] || inputElement.value; |
140 var valid = inputElement.checkValidity(); | 163 |
| 164 if (this.autoValidate) { |
| 165 var valid; |
| 166 if (inputElement.validate) { |
| 167 valid = inputElement.validate(value); |
| 168 } else { |
| 169 valid = inputElement.checkValidity(); |
| 170 } |
| 171 this.invalid = !valid; |
| 172 } |
141 | 173 |
142 // type="number" hack needed because this.value is empty until it's valid | 174 // type="number" hack needed because this.value is empty until it's valid |
143 if (value || inputElement.type === 'number' && !valid) { | 175 if (value || (inputElement.type === 'number' && !inputElement.checkValidit
y())) { |
144 this._inputHasContent = true; | 176 this._inputHasContent = true; |
145 } else { | 177 } else { |
146 this._inputHasContent = false; | 178 this._inputHasContent = false; |
147 } | 179 } |
148 | 180 |
149 if (this.autoValidate) { | 181 this.updateAddons({ |
150 this._inputIsInvalid = !valid; | 182 inputElement: inputElement, |
151 } | 183 value: value, |
| 184 invalid: this.invalid |
| 185 }); |
| 186 }, |
152 | 187 |
153 // notify add-ons | 188 _onIronInputValidate: function(event) { |
154 for (var addon, i = 0; addon = this._addons[i]; i++) { | 189 this.invalid = this._inputElement.invalid; |
155 // need to set all of these, or call method... thanks input type="number
"! | 190 }, |
156 addon.inputElement = inputElement; | 191 |
157 addon.value = value; | 192 _invalidChanged: function() { |
158 addon.invalid = !valid; | 193 if (this._addons) { |
| 194 this.updateAddons({invalid: this.invalid}); |
159 } | 195 } |
160 }, | 196 }, |
161 | 197 |
162 _computeInputContentClass: function(noLabelFloat, focused, _inputHasContent,
_inputIsInvalid) { | 198 /** |
| 199 * Call this to update the state of add-ons. |
| 200 * @param {Object} state Add-on state. |
| 201 */ |
| 202 updateAddons: function(state) { |
| 203 for (var addon, index = 0; addon = this._addons[index]; index++) { |
| 204 addon.update(state); |
| 205 } |
| 206 }, |
| 207 |
| 208 _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused,
invalid, _inputHasContent) { |
163 var cls = 'input-content'; | 209 var cls = 'input-content'; |
164 if (!noLabelFloat) { | 210 if (!noLabelFloat) { |
165 if (_inputHasContent) { | 211 if (alwaysFloatLabel || _inputHasContent) { |
166 cls += ' label-is-floating'; | 212 cls += ' label-is-floating'; |
167 if (_inputIsInvalid) { | 213 if (invalid) { |
168 cls += ' is-invalid'; | 214 cls += ' is-invalid'; |
169 } else if (focused) { | 215 } else if (focused) { |
170 cls += " label-is-highlighted"; | 216 cls += " label-is-highlighted"; |
171 } | 217 } |
172 } | 218 } |
173 } else { | 219 } else { |
174 if (_inputHasContent) { | 220 if (_inputHasContent) { |
175 cls += ' label-is-hidden'; | 221 cls += ' label-is-hidden'; |
176 } | 222 } |
177 } | 223 } |
178 return cls; | 224 return cls; |
179 }, | 225 }, |
180 | 226 |
181 _computeUnderlineClass: function(focused, _inputIsInvalid) { | 227 _computeUnderlineClass: function(focused, invalid) { |
182 var cls = 'underline'; | 228 var cls = 'underline'; |
183 if (_inputIsInvalid) { | 229 if (invalid) { |
184 cls += ' is-invalid'; | 230 cls += ' is-invalid'; |
185 } else if (focused) { | 231 } else if (focused) { |
186 cls += ' is-highlighted' | 232 cls += ' is-highlighted' |
187 } | 233 } |
188 return cls; | 234 return cls; |
189 }, | 235 }, |
190 | 236 |
191 _computeAddOnContentClass: function(focused, _inputIsInvalid) { | 237 _computeAddOnContentClass: function(focused, invalid) { |
192 var cls = 'add-on-content'; | 238 var cls = 'add-on-content'; |
193 if (_inputIsInvalid) { | 239 if (invalid) { |
194 cls += ' is-invalid'; | 240 cls += ' is-invalid'; |
195 } else if (focused) { | 241 } else if (focused) { |
196 cls += ' is-highlighted' | 242 cls += ' is-highlighted' |
197 } | 243 } |
198 return cls; | 244 return cls; |
199 } | 245 } |
200 | 246 |
201 }); | 247 }); |
202 | 248 |
203 })(); | 249 })(); |
OLD | NEW |