0👍
Your main problem is that you are using an input with type="text"
. The result of this is a string. When you start your application, the state of your component is initialised to what you set as data, which makes wall_length
and wall_height
numbers. The moment you change one of the inputs, the type of these variables changes to a `string.
Due to how javascript works, it will now do string concatenation instead of adding two numbers. It will then convert it back to a number for dividing by whatever this.selected
is. The result is that instead of doing dividing 40 + 3 = 43 by this.selected
, you are dividing “40” + 3 = 403 by this.selected
. Notice the typeof
checks I added behind the inputs to showcase this.
new Vue({
el: "#app",
data: {
title: "Калькулятор шпалер",
wall_length: 40,
wall_height: 3,
weight: [0.53, 1.05],
rapport: 0,
length: 10.05,
selected: 0.53,
polotno_for_room: 0,
polotno_rulon: 0,
result: 0
},
methods: {
calc: function() {
this.polotno_for_room = (this.wall_length + this.wall_height) / this.selected;
this.polotno_rulon = this.length / (this.wall_height + 0.10);
this.result = Math.ceil(this.polotno_for_room / this.polotno_rulon);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>{{title}}</h1>
<form v-on:submit.prevent>
<span>Довжина стіни, м:</span><br>
<input class="length" type="text" name="length" v-model.text.trim="wall_length"> {{ typeof wall_length }}<br>
<span>Висота стіни, м:</span><br>
<input class="heigth" type="text" name="heigth" v-model.text.trim="wall_height"> {{ typeof wall_height }}<br>
<hr>
<span>Ширина рулона, м:</span><br>
<select v-model="selected">
<option v-for="key in weight" :value="key">{{key}}</option>
</select><br>
<span>Довжина рулона, м:</span><br>
<input class="length_roll" type="text" name="length_roll" v-model.text.trim="length" maxlength="5"><br>
<span>Повтор малюнка (рапорт), см:</span><br>
<input class="rapport" type="text" name="rapport" v-model.text.trim="rapport"><br><br>
<input type="submit" value="Порахувати" v-on:click="calc">
</form>
<span>{{result}} рулонів шпалер</span>
</div>
One of your options is to use parseFloat(..)
liberally. It will make sure you are using only numbers in your calculation.
new Vue({
el: "#app",
data: {
title: "Калькулятор шпалер",
wall_length: 40,
wall_height: 3,
weight: [0.53, 1.05],
rapport: 0,
length: 10.05,
selected: 0.53,
polotno_for_room: 0,
polotno_rulon: 0,
result: 0
},
methods: {
calc: function() {
this.polotno_for_room = (parseFloat(this.wall_length) + parseFloat(this.wall_height)) / parseFloat(this.selected);
this.polotno_rulon = parseFloat(this.length) / (parseFloat(this.wall_height) + 0.10);
this.result = Math.ceil(parseFloat(this.polotno_for_room) / parseFloat(this.polotno_rulon));
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>{{title}}</h1>
<form v-on:submit.prevent>
<span>Довжина стіни, м:</span><br>
<input class="length" type="text" name="length" v-model.text.trim="wall_length"><br>
<span>Висота стіни, м:</span><br>
<input class="heigth" type="text" name="heigth" v-model.text.trim="wall_height"><br>
<hr>
<span>Ширина рулона, м:</span><br>
<select v-model="selected">
<option v-for="key in weight" :value="key">{{key}}</option>
</select><br>
<span>Довжина рулона, м:</span><br>
<input class="length_roll" type="text" name="length_roll" v-model.text.trim="length" maxlength="5"><br>
<span>Повтор малюнка (рапорт), см:</span><br>
<input class="rapport" type="text" name="rapport" v-model.text.trim="rapport"><br><br>
<input type="submit" value="Порахувати" v-on:click="calc">
</form>
<span>{{result}} рулонів шпалер</span>
</div>