This is my code i'm trying to get the sum from input values .
It works fine when i enter numbers but as soon as i clear any input field i get total as NaN. i know using parseInt for number value is troubling , but if i'm not using parseInt it appends number instead of getting doing Sum on input Values .
I want to solve it ? why NaN is coming and how to make this code error free .. don't want to use if else for NaN or IsNan please suggest practical approach --
<template>
<div>
<form #submit.prevent="submit" autocomplete="off">
<div class="form-group d-flex mt-3">
<label for="zero" class="p-2 bg-info text-white redius-5">0</label>
<input style="width:100px;" min="0" class="form-control" name="zero" id="zero" v-model.number="zero" #click="doSum" v-model="fields.zero" oninput="validity.valid||(value=''); " />
<div v-if="errors && errors.zero" class="text-danger">{{ errors
.zero[0] }}</div>
<label for="one" class="p-2 bg-info text-white">1</label>
<input style="width:100px;" min="0" type="number" class="form-control" name="one" v-model.number="one" id="one" #click="doSum" v-model="fields.one" oninput="validity.valid||(value=''); "/>
<div v-if="errors && errors.one" class="text-danger">{{ errors.one[0] }}</div>
<label for="two" class="p-2 bg-info text-white">2</label>
<input style="width:100px;" min="0" type="number" class="form-control" name="two" v-model.number="two" id="two" #click="doSum" v-model="fields.two" oninput="validity.valid||(value=''); " />
<div v-if="errors && errors.two" class="text-danger">{{ errors.two[0] }}</div>
</div>
Total = {{ Bettotal }}
</form>
</div>
<script>
export default {
props: ['game_id', 'userId', 'this.rows'],
mounted() {
console.log('Component mounted.')
},
data() {
return {
timestamp: 0,
selectedGame: {},
gamesinfo: [],
zero:0,
one:0,
two:0,
Bettotal:0,
gamex: this.gameId,
rows: [],
count: 0,
fields: {},
errors: {},
success: false,
loaded: true,
};
},
doSum: function () {
this.Bettotal = parseInt(this.zero) + parseInt(this.one) + parseInt(this.two);
// if (isNaN(this.Bettotal)) this.Bettotal = 0;
return this.Bettotal;
},
};
In your total() method instead of
acc += parseInt(row.value)
try:
acc += (row.value - 0)
I think that simple hack should work because it will convert it to number when you subtract zero from empty string.
ok i have added a validator and now its not giving me NaN
oninput="this.value = Math.abs(this.value);
Related
I have a reactive array that I am trying to determine the best way to handle. It's a standard add/remove but one of the 3 fields that is part of that add/remove section updates one of the others. 1 field is a service the other is the quantity of that service and the third totals the service price + quantity = that field price.
I am having issues working on the indexing and I can't wrap my head around it.
relavent HTML
<div class="col-span-6 gap-4">
<div class="grid grid-cols-6 gap-6" v-for="(service, index) in form.services" :key="index">
<div class="col-span-3 gap-4">
<Label for="service" value="Service" :class="[form.zip_codes == '' ? disableLabel : '']"/>
<v-select label="serviceData" :options="servicesData" v-model="service[index]"
:disabled="form.zip_codes == ''"
class="mt-1 block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm">
</v-select>
<InputError :message="form.errors.services" class="mt-2"/>
</div>
<div class="col-span-1 gap-4">
<Label for="quantity" value="Quantity" :class="[form.zip_codes == '' ? disableLabel : '']"/>
<Input id="quantity" v-model="service.quantity" type="number" class="mt-1 block w-full"
:disabled="form.zip_codes == ''"
autocomplete="phone_2"
#change="calculatePrice($event.target.value, service[index], index)"/>
<InputError :message="form.errors.quantity" class="mt-2"/>
</div>
<div class="col-span-2 gap-4">
<Label for="price" value="Price"/>
<Input id="price" v-model="servicePrice[index]" type="text" class="mt-1 block w-full" disabled
:disabled="form.zip_codes == ''"
autocomplete="phone_2"/>
<InputError :message="form.errors.quantity" class="mt-2"/>
</div>
<SecondaryButton #click="removeService(index)">Remove</SecondaryButton>
</div>
<div class="pt-5">
<SecondaryButton
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing"
type="button"
#click="addServices()"
>
Add Services
</SecondaryButton>
</div>
my main focus is calculatePrice()
defineProps({
zip_codes: Object,
appointment_types: Array,
servicesData: Object
})
const servicePrice = reactive([])
const calculatePrice = (quantity, service, index) => {
servicePrice.push( Math.round((quantity * service.price) * 100) / 100);
}
As you can see I can push a new value to it but I am not sure how to set it to the correct index. I tried servicePrice[index] but it just returns -1.
Ref or Recative are instantaneous changing values.
You can watch the relevant fields with watch, if there is a change, you can make the calculation.
watch(() => servicePrice.value ,() => {
servicePrice.value = Math.round((quantity * service.price) * 100) / 100;
})
I got the problem in making program for my company, the concept is you can input mark (nilai) for every sector based on kriteria of the mark you had to fill and it has 5 kriteria. the problem is I have to separate the kriteria based on the kriteria name and when I try the array cant be shown
<template>
<div class="space-x-4 sm:-my-px sm:ml-1 sm:flex">
<jet-button #click="getKriteria1">P1</jet-button>
<jet-button #click="getKriteria2">P2</jet-button>
<jet-button #click="getKriteria3">P3</jet-button>
<jet-button #click="getKriteria4">P4</jet-button>
<jet-button #click="getKriteria5">P5</jet-button>
</div>
<div class="mt-4">
<div class="space-x-4 sm:-my-px sm:ml-1 sm:flex" v-if="session === 1" :v-for="(kriteria, index) in kriteria1.data" :key="kriteria.id">
<label>{{kriteria.sub_kriteria}} : </label>
<jet-input type="number" class="mt-1 block w-3/4" placeholder="Nilai"
ref="nilai"
v-model="form.nilai[index]"
#keyup.enter="create" />
<jet-input-error :message="form.errors.nilai" class="mt-2" />
</div>
</div>
</template>
can you guys help me why the kriterias i get cant be show, in the console i can see the kriteria is read and has field but when i try to call it with props it cant be shown and cant be convert to kriteria1
<script>
props: {
penilaians: Array,
kriterias:Array,
},
data() {
return {
session:1,
kriteria1:[],
kriteria2:[],
kriteria3:[],
kriteria4:[],
kriteria5:[],
form:this.$inertia.form({
nilai:[],
foto:[],
status:[],
rekomendasi:[]
}),
}
},
methods:{
getKriteria1(){
this.session = 1;
this.kriteria1 = kriterias;
for(let index=0;index<=kriterias.length;index++){
if(kriterias[index].nama === 'P1'){
this.kriteria1[index].id = kriterias[index].id;
this.kriteria1[index].nama = kriterias[index].nama;
this.kriteria1[index].sub_kriteria = kriterias[index].sub_kriteria;
}
}
},
}
</script>
i erase the component and import in purpose because it will not affect the question i think
the main idea is to filter the 'kriteria' field to spesific values so i made the filter with getKriteria 1 so i can get 'nilai' form for the 'kriteria'
method:{
getKriteria1(){
this.session = 1;
var kriteria = this.kriterias;
var j=0;
for(var i=0;i<= kriteria.length;i++){
if(kriteria[i].nama == 'P1'){
this.kriteria1[j] = kriteria[i];
j++;
}
}
},
}
this is the jetstream template of the program :
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="space-x-4 sm:-my-px sm:ml-1 sm:flex" :v-on:show ="getPenilaianId()">
<jet-button v-on:click.prevent="getKriteria1()" >P1</jet-button>
<jet-button v-on:click.prevent="getKriteria2()" >P2</jet-button>
<jet-button v-on:click.prevent="getKriteria3()" >P3</jet-button>
<jet-button v-on:click.prevent="getKriteria4()" >P4</jet-button>
<jet-button v-on:click.prevent="getKriteria5()" >P5</jet-button>
</div>
<div class="mt-4">
<div v-if="session === 1">
<div v-for="item in kriteria1" :key="item.id" :v-on:show="getKriteriaId(item.id-1)">
<div v-if="item === null"> Tidak ada Kriteria </div>
<label>{{item.nama}} - {{item.sub_kriteria}}</label>
<jet-input type="number" class="mt-1 block w-3/4" placeholder="Nilai"
ref="nilai"
v-model="form.nilai[item.id-1]"
#keyup.enter="create" />
<jet-input-error :message="form.errors.nilai" class="mt-2" />
</div>
</div>
</div>
I am new to vue, I found some examples but I could not reproduce in my situation.
I have some inputs user will fill out and once it clicks the button, the information will populate a list of items. I am trying to crete < li > with a OrderListItem component. But I am getting this error:
runtime-core.esm-bundler.js?5c40:217 Uncaught ReferenceError: machines is not defined
at eval (OrderListItem.vue?fb66:14)
Here is the form
<template>
<div>
<div class="flex flex-col mb-4 md:w-full m-1">
<label for="planter_model_id">Planter</label>
<select v-model="registration.planter_model_id" name="planter_model_id">
<option disabled selected>Planter</option>
<option v-for="planter in planters" :key="planter" :value="planter.id">{{planter.brand.name}} {{planter.name }}</option>
</select>
</div>
<div class="flex flex-col mb-4 md:w-full m-1">
<label class=" for="lines">Lines</label>
<Input v-model="registration.lines" type="number" name="lines" />
</div>
<Button type="button" #click="addItemOrder">Add</Button>
</div>
<div>
<ul>
<OrderListItem :machines="machines" />
</ul>
<div>
</template>
Here is my code
export default {
components: {
OrderListItem,
Button,
},
props: {
planters:{
type:Array,
required: true
},
},
data() {
return {
machines: [], //this what I wish to be passed to OrderListItem component
registration:{
lines:null,
planter_model_id:null,
},
}
},
methods:{
addItemOrder(){
let item = {}
item.planter_model_id = this.registration.planter_model_id
item.lines = this.registration.lines
this.machines.push(item)
}
}
};
And here is my OrderListItem component that I created on another file:
<template>
<li v-for="machine in machines" :key="machine">
<div class="flex-initial w-3/5">
<p>Planter: {{machine.planter_model_id}}</p>
<p>Lines: {{machine.lines}}</p>
</div>
</li>
</template>
<script>
export default {
name: 'OrderListItem',
props:{
machines,
}
}
</script>
I don’t know if it is relevant but I am using vue3 and laravel.
I am very newbie here and from what I learned I think if machines array was a prop I would be able to access it on my component. But I will dynamically add a and remove itens from machines array and I think props receive data from server so It should not be declared there, that why I declared inside data().
Thanks =)
You should define the prop by adding its type and default value :
export default {
name: 'OrderListItem',
props:{
machines:{type:Array,default:()=>[]},
}
}
I am using vue-select in my project along with tabulator. I was able to fetch data from json file and view it. But when selecting the options i get an error saying " Component emitted event "option:selecting" but it is neither declared in the emits option nor as an "onOption:selecting" prop. ". I could not resolve this error after multiple try. Below is the code.
**<template>
<form>
<div class="container h-25 w-10/12 mx-auto pb-3 border 2 border-gray-300 flex flex-col rounded-md items-left bg-gray-100" >
<label class="px-3 py-1 w-10/12 text-xs text-black font-medium">Employee</label>
<div class="px-2">
<v-select v-model="Selected" multiple :options="options" label="Employee" placeholder="---SELECT---" class="style-chooser"></v-select>
</div>
<!-- <span>Selected: {{ Employee_Id }}</span> -->
</div>
</form>
<!-- <ul><li v-for="item in datas" :key="item.Employee">{{ item.Employee }}</li></ul> -->
</template>
<script>
import dataset from './dataset.json'
export default {
data(){
return {
openCard: false,
Selected: ""
}
},
computed: {
options: () => dataset
},
methods:{
open(){
this.openCard = ! this.openCard
},
},
}
</script>**
Your help is highly appreciated la.
I'm trying to clone a select2 list and 2 text areas, but it's working only for the first clone, and I don't understand why..any new eye will certainly help !
(the cloning is OK, but the select2 is not applied to the 3rd clone)
HTML part
<fieldset>
<div id="test">
<div>
<label>Tool Name : </label>
<select class="toollist" name="FSR_tool_id[]" style="width: 350px" />
<option></option>
<option value="1" >bla 1</option>
</select>
<input type="Button" value="ADD ANOTHER TOOL" class="AddTool">
<label>Service Scope</label>
<textarea rows="5" style="width:99%" name="FSR_servicescope[]" class="validate[required]" />
</textarea>
</br>
<label>Service Description</label>
<textarea rows="10" style="width:99%" name="FSR_servicedesc[]" class="validate[required]" />
</textarea><hr>
</div>
</div>
<input type="hidden" value="0" id="countertool">
</fieldset>
JS part (I call jquery and select 2 before, of course)
$('#test .toollist').select2({ //apply select2 to my element
placeholder: "Search your Tool",
allowClear: true
});
$("input[type='button'].AddTool").live('click',
function() {
var index = $(this).closest('div').index();
if (index > 0) {
$(this).closest('div').remove();
} else {
$('#test .toollist').select2('destroy');
//we have to destroy the select2 before cloning
var $div = $(this).closest('div').clone(true);
$div.find('input.AddTool').val("DELETE THIS TOOL");
//to replace the button "add" by another "delete"
var $input = $div.find('input.exp');
var index = $('input#countertool').val();
var id = 'exp' + index;
index++;
$('input#countertool').val(index);
$input.attr('id', id).data('index', index);
$(this).closest('#test').append($div);
//then, we re-apply select2 to the lists
$('#test .toollist').select2({
placeholder: "Search your tool !",
allowClear: true
});
};
});
Any idea of my mistake ?
Thanks a lot in advance !
See this fiddle: http://jsfiddle.net/omugbdm1/3/ it's a bit of a mashup of code but should do the trick.
<div id="test">
<div id="tooltest0" class="tooltest0">
<label>Tool Name :</label>
<select class="toollist" name="FSR_tool_id[]" id="FSR_tool_id0" style="width: 350px" />
<option></option>
<option value="1">bla 1</option>
</select>
</div>
<div id="tool-placeholder"></div>
<div>
<input type="button" value="Add another" />
</div>
</div>
and
$('.toollist').select2({ //apply select2 to my element
placeholder: "Search your Tool",
allowClear: true
});
$('input[type=button]').click(function () {
$('.toollist').select2("destroy");
var noOfDivs = $('.tooltest0').length;
var clonedDiv = $('.tooltest0').first().clone(true);
clonedDiv.insertBefore("#tool-placeholder");
clonedDiv.attr('id', 'tooltest' + noOfDivs);
$('.toollist').select2({ //apply select2 to my element
placeholder: "Search your Tool",
allowClear: true
});
});