0

I am using "moneyFormat" filter for formatting the currency value. It's formatting the values which is defined already. I want to format the dynamic values. Hence I have called the filter function through a method called "displayValue", but I am getting error

Image

and the given input field also not updated.

Here is my code :

<template>
    <b-card>
        <div class="panel-body" id="app">
            <table class="table table-hover">
                <thead>
                    <tr>
                        <th style="width: 20px;">No.</th>
                        <th style="width: 330px;">Description</th>
                        <th style="width: 130px;" class="text-right">Charges</th>
                        <th style="width: 130px;">Total</th>
                        <th style="width: 130px;"></th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(row, index) in rows" :key="row.qty">
                        <td>
                            {{ index +1 }}
                        </td>
                        <td>

                        <select name="" id="" class="form-control" v-model="row.billChgDesc">
                            <option v-for="option in billChgDescOpt" v-bind:value="option.value" 
                                :key="option.value"> {{ option.text }} 
                            </option>
                        </select>
                        </td>

                                <td> 
                                  <input @input="displayValue" class="form-control text-right" type="text" v-model="row.charges"  data-type="currency" v-validate="'required'" :name="'charges' + index">
                                     <span v-show="vErrors.has('charges' + index)" class="is-danger">{{ vErrors.first('charges' + index) }}</span>
                                <td>
                                    <input class="form-control text-right" :value="row.qty * row.charges | moneyFormat" number readonly />
                                    <input type="hidden" :value="row.qty * row.charges * row.tax / 100"  number/>
                                </td>

                                <td>
                                    <button class="btn btn-primary btn-sm" @click="addRow(index)"><i class="fa fa-plus"></i></button>
                                    <button class="btn btn-danger btn-sm" @click="removeRow(index)"><i class="fa fa-minus"></i></button>
                                </td>
                            </tr>
                </tbody>
                <tfoot>
                    <tr>
                        <td colspan="3" class="text-right">DELIVERY</td>
                        <td colspan="1" class="text-right"><input class="form-control text-right" v-model="delivery" number/></td>
                        <td></td>
                    </tr>
                </tfoot>
            </table>

        </div>
    </b-card>
</template>

<script>
import Vue from 'vue'
import accounting from 'accounting'

export default {

filters:{
moneyFormat: function (val){
     if (val > 0) {
            return accounting.formatMoney(val, " ₹ ", 2, ",", ".");
        }
}
},
   data: function () {
    return {
        billChgDescOpt: [
            { value: '', text: 'Select' },
            { value: 'M', text: 'Maintenance Fee'},
            { value: 'W', text: 'Water Charges'},
            { value: 'P', text: 'Penalty Fee'},
            ],
        rows: [
            {qty: 5, billChgDesc: '', charges: 55.20, tax: 10},
            {qty: 19, billChgDesc: '', charges: 1255.20, tax: 20},
        ],
        grandtotal: 0,
        delivery: 40
    }

  },
    computed: {
        total: function () {
            var t = 0;
            $.each(this.rows, function (i, e) {
                t += accounting.unformat(e.total, ",");
            });
            return t;
        },
        taxtotal: function () {
            var tt = 0;
            $.each(this.rows, function (i, e) {
                tt += accounting.unformat(e.tax_amount, ",");
            });
            return tt;
        }
    },
    methods: {

        addRow: function (index) {
            try {
                this.rows.splice(index + 1, 0, {});
            } catch(e)
            {
                console.log(e);
            }
        },
        removeRow: function (index) {
            this.rows.splice(index, 1);
        },
        displayValue:function (e) {
            var value = e.target.value
         var a = this.filters.moneyFormat(value);
         return a;
        }
    }
}
</script>

<style lang="scss" scoped>
.is-danger{
  color:  RED;
}
</style>
1
  • Did you solve your problem? It works? If yes, mark an answer as valid in order to mark as resolved and keep S.O clean. If no, try updating the question and we will try to help you. Commented Jun 12, 2018 at 10:57

2 Answers 2

1

You could use:

this.$options.filters.moneyFormat(value)

Check: https://v2.vuejs.org/v2/api/#vm-options

For global filters, first set:

Vue.prototype.$filters = Vue.options.filters

And then:

this.$filters.foo

Edit:

Looking closer your code, you are not using the filter as a Vue filter and only calling from one point (a method) instead of calling inline from HTML, maybe it's better that the method itself returns the value of the input, like:

displayValue: function (e) {
    var val = e.target.value
    if (val > 0) {
       return accounting.formatMoney(val, " ₹ ", 2, ",", ".");
    }
} 

Did it work? Or the same error is shown? If yes, can you paste the error?

Hope it helps!

Sign up to request clarification or add additional context in comments.

7 Comments

Yeah it's working. But the value is not reflecting inside the input element [Iam using "return a " for reflecting the updated value]
And I have tried " var a = this.$options.filters.moneyFormat(value); this.$emit('input', a) " this too
As you are binding the row.charges in the input, try changing this variable value in the method, like: this.row.charges = this.$options.filter.moneyFormat(value). I think this way will update the value without a return. Or in the e.target.value directly.
I did. If I give like this, " this.row.charges = this.$options.filter.moneyFormat(value) ", it's throwing the same error again
I tried ur "displayValue" function instead of filter function, but samething happened again and the error is " Illegal return statement "
|
0

As it's been said, if you want to use the filter, you need to do this.$options.filters.moneyFormat(value)

What you're trying to achieve it's rendered the moneyFormat inside an input and the value displayed is the v-model. It's this one you have to format.
So you can initialize a new data property filled with each row.charges formatted on mounted:

data: function () {
  return {
    rows: [
      //...
    ],
    currentCharges: []
  }
},

mounted() {
  this.rows.forEach(row => {
    let formattedCharges = this.$options.filters.moneyFormat(row.charges)
    this.currentCharges.push(formattedCharges)
  })
},

and use this data to fulfill your inputs:

<tr v-for="(row, index) in rows">
  <td> 
    <input v-model="currentCharges[index]" @input="displayValue($event, index)">
  <td>

To keep the current row.charges updated, reassign it when the v-model updates:

methods: {
  displayValue:function (e, index) {
    // the target value is a string like this " ₹ 55.20"
    // split it and convert the last element to Float type
    let arrValue = e.target.value.split(" ")
    let parseValue = parseFloat(arrValue[arrValue.length -1])

    // reassign the row.charges with the new float value
    this.rows[index].charges = parseValue
  }
},

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.