forked from quasarframework/quasar
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNumeric.vue
More file actions
128 lines (123 loc) · 2.74 KB
/
Numeric.vue
File metadata and controls
128 lines (123 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<template>
<div
class="q-numeric textfield row inline items-center"
:class="{disabled: disable, readonly: readonly, 'has-error': hasError}"
>
<i @click="__setByOffset(-1)">remove</i>
<input
class="no-style auto q-input-field"
type="number"
v-model.number="model"
pattern="[0-9]*"
@blur="__updateValue"
@keydown.up="__updateValue"
@keydown.down="__updateValue"
@keydown.enter="__updateValue"
@keydown.esc="model = value"
:disabled="disable"
:readonly="readonly"
:style="{width: width}"
tabindex="0"
:step="step"
:min="min"
:max="max"
>
<i @click="__setByOffset(1)">add</i>
</div>
</template>
<script>
export default {
props: {
value: {
required: true
},
step: {
type: Number,
default: 1
},
min: Number,
max: Number,
readonly: Boolean,
disable: Boolean,
maxDecimals: {
type: Number,
default: 0
}
},
watch: {
value () {
this.model = this.value
}
},
data () {
return {
model: this.value
}
},
computed: {
hasMin () {
return this.has(this.min)
},
hasMax () {
return this.has(this.max)
},
hasError () {
return (
this.has(this.model) &&
(
(this.hasMin && this.model < this.min) ||
(this.hasMax && this.model > this.max)
)
)
},
width () {
return (this.has(this.model) ? ('' + this.model).length : 1) * 0.7 + 'em'
}
},
methods: {
has (val) {
return typeof val !== 'undefined'
},
__normalize (value) {
if (!this.has(value)) {
value = this.hasMin ? this.min : 0
}
if (this.hasMin && value < this.min) {
return this.min
}
else if (this.hasMax && value > this.max) {
return this.max
}
return parseFloat(this.maxDecimals ? parseFloat(value).toFixed(this.maxDecimals) : value)
},
__updateValue () {
this.$nextTick(() => {
this.model = this.__normalize(this.model)
if (!this.disable && !this.readonly && this.value !== this.model) {
this.$emit('input', this.model)
}
})
},
__setByOffset (direction) {
if (this.disable || this.readonly) {
return
}
let newValue
if (!this.has(this.model)) {
newValue = this.__normalize(0)
}
else {
newValue = this.model + direction * this.step
if (this.hasMin && newValue < this.min && this.model === this.min) {
return
}
if (this.hasMax && newValue > this.max && this.model === this.max) {
return
}
}
this.model = newValue
this.__updateValue()
}
}
}
</script>