|
9 | 9 | v-model="amount" |
10 | 10 | v-if="!readOnly" |
11 | 11 | > |
12 | | - <span v-else ref="readOnly">{{ amount }}</span> |
| 12 | + <span |
| 13 | + v-else |
| 14 | + ref="readOnly" |
| 15 | + >{{ amount }}</span> |
13 | 16 | </template> |
14 | 17 |
|
15 | 18 | <script> |
16 | 19 | import accounting from 'accounting-js' |
17 | 20 |
|
18 | 21 | export default { |
19 | | - name: 'vue-numeric', |
| 22 | + name: 'VueNumeric', |
20 | 23 |
|
21 | 24 | props: { |
22 | 25 | /** |
23 | 26 | * Currency symbol. |
24 | 27 | */ |
25 | 28 | currency: { |
| 29 | + type: String, |
26 | 30 | default: '', |
27 | | - required: false, |
28 | | - type: String |
| 31 | + required: false |
29 | 32 | }, |
30 | 33 |
|
31 | 34 | /** |
32 | 35 | * Maximum value allowed. |
33 | 36 | */ |
34 | 37 | max: { |
| 38 | + type: Number, |
35 | 39 | default: Number.MAX_SAFE_INTEGER || 9007199254740991, |
36 | 40 | required: false, |
37 | | - type: Number |
38 | 41 | }, |
39 | 42 |
|
40 | 43 | /** |
41 | 44 | * Minimum value allowed. |
42 | 45 | */ |
43 | 46 | min: { |
| 47 | + type: Number, |
44 | 48 | default: Number.MIN_SAFE_INTEGER || -9007199254740991, |
45 | | - required: false, |
46 | | - type: Number |
| 49 | + required: false |
47 | 50 | }, |
48 | 51 |
|
49 | 52 | /** |
50 | 53 | * Enable/Disable minus value. |
51 | 54 | */ |
52 | 55 | minus: { |
| 56 | + type: Boolean, |
53 | 57 | default: false, |
54 | | - required: false, |
55 | | - type: Boolean |
| 58 | + required: false |
56 | 59 | }, |
57 | 60 |
|
58 | 61 | /** |
59 | 62 | * Input placeholder. |
60 | 63 | */ |
61 | 64 | placeholder: { |
62 | | - required: false, |
63 | | - type: String |
| 65 | + type: String, |
| 66 | + default: '', |
| 67 | + required: false |
64 | 68 | }, |
65 | 69 |
|
66 | 70 | /** |
67 | 71 | * Value when the input is empty |
68 | 72 | */ |
69 | 73 | emptyValue: { |
| 74 | + type: [Number, String], |
70 | 75 | default: '', |
71 | | - required: false, |
72 | | - type: [Number, String] |
| 76 | + required: false |
73 | 77 | }, |
74 | 78 |
|
75 | 79 | /** |
76 | 80 | * Number of decimals. |
77 | 81 | * Decimals symbol are the opposite of separator symbol. |
78 | 82 | */ |
79 | 83 | precision: { |
80 | | - required: false, |
81 | | - type: Number |
| 84 | + type: Number, |
| 85 | + default: 0, |
| 86 | + required: false |
82 | 87 | }, |
83 | 88 |
|
84 | 89 | /** |
85 | 90 | * Thousand separator type. |
86 | 91 | * Separator props accept either . or , (default). |
87 | 92 | */ |
88 | 93 | separator: { |
| 94 | + type: String, |
89 | 95 | default: ',', |
90 | | - required: false, |
91 | | - type: String |
| 96 | + required: false |
92 | 97 | }, |
93 | 98 |
|
94 | 99 | /** |
95 | 100 | * v-model value. |
96 | 101 | */ |
97 | 102 | value: { |
| 103 | + type: [Number, String], |
98 | 104 | default: 0, |
99 | | - required: true, |
100 | | - type: [Number, String] |
| 105 | + required: true |
101 | 106 | }, |
102 | 107 |
|
103 | 108 | /** |
104 | 109 | * Hide input and show value in text only. |
105 | 110 | */ |
106 | 111 | readOnly: { |
| 112 | + type: Boolean, |
107 | 113 | default: false, |
108 | | - required: false, |
109 | | - type: Boolean |
| 114 | + required: false |
110 | 115 | }, |
111 | 116 |
|
112 | 117 | /** |
113 | 118 | * Class for the span tag when readOnly props is true. |
114 | 119 | */ |
115 | 120 | readOnlyClass: { |
| 121 | + type: String, |
116 | 122 | default: '', |
117 | | - required: false, |
118 | | - type: String |
| 123 | + required: false |
119 | 124 | }, |
120 | 125 |
|
121 | 126 | /** |
122 | 127 | * Position of currency symbol |
123 | 128 | * Symbol position props accept either 'suffix' or 'prefix' (default). |
124 | 129 | */ |
125 | 130 | currencySymbolPosition: { |
| 131 | + type: String, |
126 | 132 | default: 'prefix', |
127 | | - required: false, |
128 | | - type: String |
| 133 | + required: false |
129 | 134 | } |
130 | 135 | }, |
131 | 136 |
|
@@ -179,6 +184,72 @@ export default { |
179 | 184 | } |
180 | 185 | }, |
181 | 186 |
|
| 187 | + watch: { |
| 188 | + /** |
| 189 | + * Watch for value change from other input with same v-model. |
| 190 | + * @param {Number} newValue |
| 191 | + */ |
| 192 | + valueNumber (newValue) { |
| 193 | + if (this.$refs.numeric !== document.activeElement) { |
| 194 | + this.amount = this.format(newValue) |
| 195 | + } |
| 196 | + }, |
| 197 | +
|
| 198 | + /** |
| 199 | + * When readOnly is true, replace the span tag class. |
| 200 | + * @param {Boolean} newValue |
| 201 | + * @param {Boolean} oldValue |
| 202 | + */ |
| 203 | + readOnly (newValue, oldValue) { |
| 204 | + if (oldValue === false && newValue === true) { |
| 205 | + this.$nextTick(() => { |
| 206 | + this.$refs.readOnly.className = this.readOnlyClass |
| 207 | + }) |
| 208 | + } |
| 209 | + }, |
| 210 | +
|
| 211 | + /** |
| 212 | + * Immediately reflect separator changes |
| 213 | + */ |
| 214 | + separator () { |
| 215 | + this.process(this.valueNumber) |
| 216 | + this.amount = this.format(this.valueNumber) |
| 217 | + }, |
| 218 | +
|
| 219 | + /** |
| 220 | + * Immediately reflect currency changes |
| 221 | + */ |
| 222 | + currency () { |
| 223 | + this.process(this.valueNumber) |
| 224 | + this.amount = this.format(this.valueNumber) |
| 225 | + }, |
| 226 | +
|
| 227 | + /** |
| 228 | + * Immediately reflect precision changes |
| 229 | + */ |
| 230 | + precision () { |
| 231 | + this.process(this.valueNumber) |
| 232 | + this.amount = this.format(this.valueNumber) |
| 233 | + } |
| 234 | + }, |
| 235 | +
|
| 236 | + mounted () { |
| 237 | + // Set default value props when placeholder undefined. |
| 238 | + if (!this.placeholder) { |
| 239 | + this.process(this.valueNumber) |
| 240 | + this.amount = this.format(this.valueNumber) |
| 241 | +
|
| 242 | + // In case of delayed props value. |
| 243 | + setTimeout(() => { |
| 244 | + this.process(this.valueNumber) |
| 245 | + this.amount = this.format(this.valueNumber) |
| 246 | + }, 500) |
| 247 | + } |
| 248 | +
|
| 249 | + // Set read-only span element's class |
| 250 | + if (this.readOnly) this.$refs.readOnly.className = this.readOnlyClass |
| 251 | + }, |
| 252 | +
|
182 | 253 | methods: { |
183 | 254 | /** |
184 | 255 | * Handle blur event. |
@@ -258,72 +329,6 @@ export default { |
258 | 329 | const toUnformat = typeof value === 'string' && value === '' ? this.emptyValue : value |
259 | 330 | return accounting.unformat(toUnformat, this.decimalSeparator) |
260 | 331 | } |
261 | | - }, |
262 | | -
|
263 | | - watch: { |
264 | | - /** |
265 | | - * Watch for value change from other input with same v-model. |
266 | | - * @param {Number} newValue |
267 | | - */ |
268 | | - valueNumber (newValue) { |
269 | | - if (this.$refs.numeric !== document.activeElement) { |
270 | | - this.amount = this.format(newValue) |
271 | | - } |
272 | | - }, |
273 | | -
|
274 | | - /** |
275 | | - * When readOnly is true, replace the span tag class. |
276 | | - * @param {Boolean} newValue |
277 | | - * @param {Boolean} oldValue |
278 | | - */ |
279 | | - readOnly (newValue, oldValue) { |
280 | | - if (oldValue === false && newValue === true) { |
281 | | - this.$nextTick(() => { |
282 | | - this.$refs.readOnly.className = this.readOnlyClass |
283 | | - }) |
284 | | - } |
285 | | - }, |
286 | | -
|
287 | | - /** |
288 | | - * Immediately reflect separator changes |
289 | | - */ |
290 | | - separator () { |
291 | | - this.process(this.valueNumber) |
292 | | - this.amount = this.format(this.valueNumber) |
293 | | - }, |
294 | | -
|
295 | | - /** |
296 | | - * Immediately reflect currency changes |
297 | | - */ |
298 | | - currency () { |
299 | | - this.process(this.valueNumber) |
300 | | - this.amount = this.format(this.valueNumber) |
301 | | - }, |
302 | | -
|
303 | | - /** |
304 | | - * Immediately reflect precision changes |
305 | | - */ |
306 | | - precision () { |
307 | | - this.process(this.valueNumber) |
308 | | - this.amount = this.format(this.valueNumber) |
309 | | - } |
310 | | - }, |
311 | | -
|
312 | | - mounted () { |
313 | | - // Set default value props when placeholder undefined. |
314 | | - if (!this.placeholder) { |
315 | | - this.process(this.valueNumber) |
316 | | - this.amount = this.format(this.valueNumber) |
317 | | -
|
318 | | - // In case of delayed props value. |
319 | | - setTimeout(() => { |
320 | | - this.process(this.valueNumber) |
321 | | - this.amount = this.format(this.valueNumber) |
322 | | - }, 500) |
323 | | - } |
324 | | -
|
325 | | - // Set read-only span element's class |
326 | | - if (this.readOnly) this.$refs.readOnly.className = this.readOnlyClass |
327 | 332 | } |
328 | 333 | } |
329 | 334 | </script> |
0 commit comments