Christian Aldana
Christian Aldana

Reputation: 77

Input empty give 0

hopefully you can help me. I want that if input remains empty, it is assigned a value of 0. At the moment of loading my modal the value is 0, if my input is focused, 0 is deleted. If I go to the next input I do not want any input to remain empty

onFocus() {
    this.efectivo = '';
},
onFocus1() {
    this.tarjeta = '';
},
<td style="background-color: #CEECF5">
  <input name="txtd" @focus="onFocus1" v-bind:min="0" v-model="tarjeta" type="number">
</td>
<td style="background-color: #CEECF5">
  <input name="txte" @focus="onFocus2" v-bind:min="0" v-model="vales" type="number">
</td>

my 2 inputs

when writing with the numeric keyboard, the 0 remains at the beginning

Upvotes: 0

Views: 1861

Answers (2)

tao
tao

Reputation: 90188

As outlined in the documentation whenever you're tempted to use a watch, consider using a computed instead:

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  data: () => ({
    t: 0
  }),
  computed: {
    test: {
      get() {
        return Number(this.t)
      },
      set(val) {
        this.t = Number(val) || 0
      }
    }
  },
  methods: {
    onBlur() {
      this.$refs.test.value = this.test
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<div id="app">
  <input v-model="test"
         type="number"
         min="0"
         max="100"
         placeholder="0"
         ref="test"
         @blur="onBlur" />
  <pre v-html="{test}" />
</div>

The above follows the Store pattern (one source of truth), where data acts as a local store for your computed property.
If you use Vuex, you should (obviously) read test value from the store and commit the mutation in the setter.
If you're not using Vuex but still want to export your data prop so that external components can react to its change, you can use the shiny new Vue.observable(), added in v2.6:

Vue.config.devtools = false;
Vue.config.productionTip = false;

const store = Vue.observable({ test: 0 });

new Vue({
  el: '#app',
  computed: {
    test: {
      get() {
        return Number(store.test)
      },
      set(val) {
        store.test = Number(val) || 0
      }
    }
  },
  methods: {
    onBlur() {
      this.$refs.test.value = this.test
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<div id="app">
  <input v-model="test"
         type="number"
         min="0"
         max="100"
         placeholder="0"
         ref="test"
         @blur="onBlur" />
  <pre v-html="{test}" />
</div>

Now your store const can live in a different file, can be imported/exported and you can listen to its changes in any other component by using it inside a computed property.

Upvotes: 1

Sphinx
Sphinx

Reputation: 10729

From your description, it seems you'd like to implement one input can't be empty when lose focus, and if the value of the input is empty, you'd like to assign zero to it.

I think uses watch will be one option like below demo:

Updated: the value of the input will be one string,

So for first solution: if you'd like to trim the leading zero, uses the modifier=number of v-model like v-model.number='test1'.

For second solution: convert it to this.test2 = Number(this.test2) manually.

new Vue ({
  el:'#app',
  data () {
    return {
      test1:0, //uses v-model, actually :value and @input, @input will occurs when text content of input is changed
      test2: 0, //uses :value and @change, @change will occurs when lose focus or press 'enter/return',
    }
  },
  watch: {
    test1: function (newVal, oldVal) {
      if (newVal !== 0 && !newVal) this.test1 = 0
    },
    test2: function (newVal, oldVal) {
      if (newVal !== 0 && !newVal) this.test2 = 0
      this.test2 = Number(this.test2)
    }
  },
  methods: {
    updateTest2: function (e) {
      this.test2 = e.target.value
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
    <div class="container">
        Directly assign 0 when empty: <input v-model.number="test1" type="number">
        <pre>Test: {{test1}}</pre>
        Assign 0 if input is empty when loses focus:<input :value="test2" @change="updateTest2($event)" type="number">
        <pre>Test: {{test2}}</pre>
    </div>
</div>

Upvotes: 1

Related Questions