How to use currency on type=Number when value is using computed data? - vue.js

Okay, so I have an input field with below code and wanting use decimals to look like 10,000 for 100000.
input#payment.form-control(type='number'
v-model='payment')
Payment for v-model is coming from computed data using mixin and updates new value using methods.
computed:{
get () { return this.NameOfMixin.payment },
set (value) {this.updateStore('payment', value)}
},
methods: {
updateStore(field, value) {
...
}
}
All the code above are working fine except now I want to display decimals and use a plain number for updating the store.
I have tried using creating methods to convert the value to decimals and v-money but nothing worked as I wished.

Related

Vue JS: Add number of available options in select drop down menu

I'm trying to display the number of options next to each item in a select drop-down menu. Like in the example.
My data is pulled from a JSON using AXIOS. Here is one line from an object in my array
"Data": {
"K": "Part Time, Full-time",
},
and the computed property which I'm attempting to create. It brings back a number but not the ones I would like. Can anyone help me out with this, please?
computed: {
feeCount() {
const feeResults = this.results.filter(
(result) => result.Data && result.Data.K
);
return feeResults.length;
},
}
Your problem is that "Part Time, Full-time" is a string, not an array, so you're getting the length of the string instead.
You can use result.Data.K.split(',') to generate an array then count the length from that.

Vuejs : How to not a boolean value in V-model?

I am getting value of options.customerdata.showbutton as true from an API, so now the switch is in on condition.
I want the switch to be in off, hence v-model="false" should be given. But
tried giving
v-model="!(options.customerdata.showbutton)"
does not work and shows error. How to achieve this?
<b-form-checkbox v-model="options.customerdata.showbutton" name="logo-display" switch >
</b-form-checkbox>
Model can't be expression (it must be reference to data/property)
Easiest way is define data and set it with negated value. But be aware that in this case your model is not change when customerdata is changed after component initialization.
data: {
return {
show: !this.options.customerdata.showbutton
}
}
If you need to store value back to options (or bound value to customerdata), you can use also computed property with setter/getter
computed {
show: {
get () {
!this.options.customerdata.showbutton
}
set (value) {
this.options.customerdata.showbutton = !value
}
}
}
For both case your bind it with
v-model="show"

Input field not reacting to data changes after being written to by a user

While creating a Vue.js application I have become stuck at a weird problem. I want to be able to manipulate an input field (think increment and decrement buttons and erasing a zero value on focus, so the user doesn't have to) and up until a user writes to the input field, everything is fine. After that, however, further changes in the data are no longer represented in the input field.
As I was sure I could not be the only one with this particular problem, I searched extensively, but had no luck. What baffles me the most is that everything works until the field is written to, since I can not really imagine why this would remove the data binding.
The following code should show the same behavior. It is an input field component, which is initialized with a zero value. On focus the zero gets removed. This works, until a user manually writes to the field after which zero values will no longer be removed, even though the focus method fires, the if-condition is met and the data in the amount-variable is changed.
Vue.component('item', {
data: function () {
return {
amount: 0
}
},
render: function (createElement) {
var self = this;
return createElement('input', {
attrs: {
//bind data to field
value: self.amount,
type: 'number'
},
on: {
//update data on input
input: function (event) {
self.amount = event.target.value;
},
//remove a zero value on focus for user convenience
focus: function (event) {
if (self.amount == 0 || self.amount == "0") {
self.amount = '';
}
}
}
})
}
})
I think you need to use domProps instead of attrs to make it reactive. But I would suggest you use vue's template syntax or if you insist on using the render function I would also suggest you to use JSX.

Computed properties on Vuex state array objects

This question may also be applicable to Vue in general, but I am using Vuex for my project.
I have an array of objects in my store for which I would like to have a calculated property.
To simplify, assume my store is as follows:
const state = {
numbers = [
{num: 2, multiplier: 3},
{num: 5, multiplier: 10},
{num: 1, multiplier: 6}
]
};
Now, I want a calculated property on each object of the numbers array, such that the result is num * multiplier (eg. 2*3 = 6, 5*10 = 50)
One solution is to make a calculated property that returns the numbers array, plus the calculated field... eg:
const getterrs = {
num_list(state){
const list = state.numbers
list.map(n=>{
n.value=n.num*n.multiplier;
);
return list;
}
}
That works, but it has a couple issues:
The array returned cannot be bound with v-model on the non-computed
fields
The entire array will be recalculated whenever any element in the
array is changed... I only want to recalculate the individual element
that changed.
Is that possible with Vue/Vuex?
You could do any computing of your store data in the component it is being used in. I would have your getter simply return the numbers array:
const getters = {
num_list(state){
return state.numbers;
}
}
Then in your component you can access numbers with the getter and use it how you want. So if you want to display the original array you could get it like this:
computed: {
num_list() {
return this.$store.getters.num_list
}
}
and display it in your template like this:
<p>Our first number is {{num_list[0].num}} and it's multiplier is {{num_list[0].num}}</p>
If you want to have the multiplication calculated as well you can have another computed property:
multiplied() {
return this.num_list[0].num*this.num_list[0].multiplier
}
and echo it in the template with {{multiplied}}.
Now it would make things a bit more flexible if you had a data element in your component that could be used as the index, or if you had a method instead of a computed property so you could pass a parameter. (You shouldn't pass parameters to computed property as I understand it). So your method of multiplied would be this:
multipliedMethod(index) {
return this.num_list[index].num*this.num_list[index].multiplier
}
Or if you want to show all the results you can iterate through your num_list with v-for and do any calculation on the fly:
<div v-for="(num, index) in num_list" :key="index">
<p>{{num.num*num.multiplier}}</p>
</div>

Vue.Js 2 Input formatting number

I have been struggling to get a number input to format numbers using vuejs2.
Migrating some view logic from asp.net core 2 to vue and I was using this:
<input asp-for="Model.LoanAmount" value="#(Model.LoanAmount > 0 ? Model.LoanAmount.ToString("N2") : String.Empty)" >
but that required me to reload that view onchange of the input.
I need a way to format number inputs with US format and 2 decimal places, (1,000,000.21) but to display nothing when the model value is zero or empty.
vue-numeric does ALMOST everything, but fails for me when I try to use a placeholder.
<vue-numeric v-model="vm.loanAmount" seperator="," placeholder=" " :precision="2" ></vue-numeric>
I tried using a space for placeholder because it crashes when I use an empty string.
This example displays 0.00 if zero or empty is inputted. I tried playing with the output-type and empty-value props.
I'm not wedded to vue-numeric but it is handy because I don't know of a more convenient solution.
You can achieve the formatting by simply using a computed property with separate getter and setter without the need for other dependencies.
computed: {
formattedValue: {
get: function() {
return this.value;
},
set: function(newValue) {
if (newValue.length > 2) {
newValue = newValue.replace(".", "");
this.value =
newValue.substr(0, newValue.length - 2) +
"." +
newValue.substr(newValue.length - 2);
} else {
this.value = newValue;
}
}
}
}
https://codesandbox.io/s/p7j447k7wq
I only added the decimal separator as an example, you'll have to add the , thousand separator in the setter for your full functionality.