2

In this code:

<button type="button @click="editing=true">Edit</button>
<form v-show="editing" @submit="onSubmit">
   <textarea v-model="text"></textarea>
</form>
<div> Current value: {{text}} </div>

new Vue({ //...
   data: {
     editing: false,
     text: 'initial value..'
   }
   methods: {
     onSubmit: function() { if (this.value.length < 5) alert("error") }
   }
}

How can I make sure that {{text}} displays only a validated value? Do I have to create two data members - one for the form and another for display? that will lead to some mess in my code (I have many large forms).
Maybe there is a v-model update hook for validation?
The point of this question - if it's possible to avoid having two data members.

2
  • When exactly does validation take place? On submit or on each key stroke? What has to be displayed inside {{text}} when data isn't valid? Last valid value? Commented Mar 3, 2018 at 22:24
  • In this example the validation is onsubmit, but I prefer to have the validation onchange. And yes, {{text}} should hold the last valid value (like the initial value). Commented Mar 3, 2018 at 22:32

2 Answers 2

4

v-model for a <textarea></textarea> translates to:

<textarea
    v-bind:value="text"
    v-on:input="text = $event.target.value">

So the answer to your last question is no, there's no hooks. You either don't use v-model by implementing something like the code above or use a second variable to save the last valid string as you were considering in the question. The latter could go as:

const app = new Vue({
  el: "#app",
  data: {
    editing: false,
    text: 'Initial value..',
    lastValid: 'Initial value..',
  },
  watch: {
    text(value) {
      if (value.length > 4) {
        this.lastValid = value;
      }
    },
  },
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <div>
    <form>
      <textarea v-model="text "></textarea>
    </form>
    <div> Current value (legth > 4): {{lastValid}} </div>
  </div>
</div>

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

Comments

2

You can save the last valid input (in this case length >= 5) and update it on every keydown event, then on the submit just send the last valid value stored

new Vue({
 el: '#app',
 data() {
  return {
   text: 'initial value..',
   lastValid: 'initial value..'
  }
 },
 methods: {
  submit() {
    alert(this.lastValid)
  },
  textChange($event) {
    let newText = $event.target.value
    this.lastValid = newText.length < 5 ? this.lastValid : newText
  }
 }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <form>
    <textarea v-model="text" @keydown="textChange"></textarea>
    <input type="submit" value="Send" @click="submit" />
  </form>
  {{ lastValid }}
</div>

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.