I'm trying to write the code for price input. The task should be simple, but something doesn't work.. I have a Vue project and I need user to enter the price in input field, where the price should be filling form the last char. Example: start value "00.00"; when user enter "1" then value became "00.01", when user add "4" then value became "00.14", when add 2 then "01.42".
The code is kind of works, but just inputted number staying in input field, even if I add event.target.value = ""
;
new Vue({
el: '#app',
data: {
price: '00.00'
},
methods: {
handleKeyDown(event) {
const key = event.key;
const validKeys = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
if (!validKeys.includes(key)) {
event.preventDefault();
return;
}
const newPrice = this.price.replace('.', '') + key;
const parsedPrice = parseFloat(newPrice);
if (isNaN(parsedPrice) || parsedPrice > 9999) {
event.preventDefault();
return;
}
const priceWithDecimal = (parsedPrice / 100).toFixed(2);
this.price = "0" + priceWithDecimal;
// event.target.value = "";
console.log(this.price);
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<div id="app">
<input type="text" v-model="price" @keydown="handleKeyDown">
</div>
You can watch
the price
value for changes instead.
const
parseValue = (v) => parseInt(v.trim().replace(/\./g, ''), 10),
formatValue = (v) => (v / 100).toFixed(2).replace(/^(\d)(?=\.)/, '0$1');
new Vue({
el: '#app',
data: {
price: '00.00'
},
watch: {
price(newValue, oldValue) {
const parsed = parseValue(newValue);
this.price = !isNaN(parsed) ? formatValue(parsed) : oldValue;
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<div id="app">
<input type="number" v-model="price" step="0.01">
</div>