MSC
MSC

Reputation: 3386

Vue resets INPUT field when setting it to disabled

Why does Vue reset a text input field when setting it to disabled? This doesn't happen with plain Javascript, and doesn't happen with a textarea.

var app = new Vue({
  el: '.container',
  data: {
  	disabled: false,
  	fn: "John",
  	ln: "Smith",
  	com: "My comment here..."
  },
  methods: {
  	vue_disable() {
  		this.disabled = !this.disabled;
  	}	
  }
});

function js_disable() {
  document.getElementById("first_name").disabled = !document.getElementById("first_name").disabled;
  document.getElementById("comment").disabled = !document.getElementById("comment").disabled;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="container">
  <h1>Vue disable fields</h1>
  
  <p>22 Aug 2019</p>
  
  <p>Why does an INPUT text field reset when I set the field to disabled with Vue? It doesn't happen with pure Javascript, and doesn't happen with a TEXTAREA.</p>
  
  <p>Type something new into the the First Name field then click the first button. The value you entered disappears and the original value is substituted.<p>

<form>
  <div class="form-group">
    <label>First Name</label>
      <input type="text" class="form-control" id="first_name" :disabled="disabled" :value="fn"/>
  </div>
  <div class="form-group">
    <label>Last name</label>
    <input type="text" class="form-control" id="last_name" :value="ln"/>
  </div>
  <div class="form-group">
    <label>Comment</label>
    <textarea rows="4" class="form-control" id="comment" v-html="com" :disabled="disabled">

      </textarea>
  </div>
  <p>
    <button type="button" class="btn btn-default" @click="vue_disable">Disable / Enable 'First Name' and 'Comment' fields with Vue</button>
  </p>
</form>
    <p>
      <button type="button" class="btn btn-default" onclick="js_disable()">Disable / Enable 'First Name' and 'Comment' fields with Javascript</button>
  </p>

</div>

https://codepen.io/MSCAU/pen/jONVRRj

Upvotes: 2

Views: 1541

Answers (1)

adiga
adiga

Reputation: 35261

Use v-model instead of :value

From the documentation:

Use the v-model directive to create two-way data bindings on form input, textarea, and select elements.

value attribute just sets the initial value for the input.

Vue adds getter/setters using Object.defineProperty to all the properties inside data. When a dependency’s setter is triggered, it notifies the watcher, and re-renders the component (documentation). Since you changed disabled property, entire component re-rendered and value is set to the whatever is in data

var app = new Vue({
  el: '.container',
  data: {
    disabled: false,
    fn: "John",
    ln: "Smith",
    com: "My comment here..."
  },
  methods: {
    vue_disable() {
      this.disabled = !this.disabled;
    }
  }
});

function js_disable() {
  document.getElementById("first_name").disabled = !document.getElementById("first_name").disabled;
  document.getElementById("comment").disabled = !document.getElementById("comment").disabled;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="container">
    <p>
      <form>
        <div class="form-group">
          <label>First Name</label>
          <input type="text" class="form-control" id="first_name" :disabled="disabled" v-model="fn" />
        </div>
        <div class="form-group">
          <label>Last name</label>
          <input type="text" class="form-control" id="last_name" v-model="ln" />
        </div>
        <div class="form-group">
          <label>Comment</label>
          <textarea rows="4" class="form-control" id="comment" v-html="com" :disabled="disabled">
      </textarea>
        </div>
        <p>
          <button type="button" class="btn btn-default" @click="vue_disable">Disable / Enable 'First Name' and 'Comment' fields with Vue</button>
        </p>
      </form>
      <p>
        <button type="button" class="btn btn-default" onclick="js_disable()">Disable / Enable 'First Name' and 'Comment' fields with Javascript</button>
      </p>

</div>

Upvotes: 3

Related Questions