1

I've got some form data that I display using a readonly input that is styled to look like plain text. When users click an edit button, they can then edit the inputs and either save or cancel.

My issue is obviously that when a user clicks cancel, the data they entered into the input remains (even though it isn't saved to the DB). I'm trying to figure out a way to reset the input to its initial data. I'm aware of this answer, but it doesn't seem to work because the data is fetched on creation.

This fiddle is similar except for the fact that the data in the real app comes from an axios call. The equivalent call is essentially:

  fetch() {
      axios.get(this.endpoint)
        .then(({data}) => {
          this.name = data.data;
        });
    }

Annoyingly, the fiddle actually works. However in my actual implementation it doesn't. The only difference with the app is that the data is an array.

How can I make this work?

This fiddle represents what my code actually does.

4
  • It's probably a reactivity thing. Can you give Vue.set(Example, 'data', this.initialData) a try? Commented Mar 25, 2018 at 22:55
  • Even when picking up from an axios call, works fine: jsfiddle.net/acdcjunior/z60etaqf/15 Commented Mar 25, 2018 at 22:59
  • Are you using v-model="data"? Commented Mar 25, 2018 at 23:04
  • I realised I missed out that I'm using a list. Here's a more accurate fiddle: jsfiddle.net/z60etaqf/21 Commented Mar 25, 2018 at 23:08

2 Answers 2

1

In the code:

  data: () => ({
    endpoint: 'https://reqres.in/api/users',
    users: [],
    initialData: []
  }),
  //...
    edit: function(index) {
      this.users[index].disabled = false
      this.initialData = this.users
    },
    reset: function(index) {
      this.users[index].disabled = true
      this.users = this.initialData
    }

Since users and initialData are arrays, you must use index when you access them.

So, at first sight, the change would be from:

  this.initialData = this.users

To

  this.initialData[index] = this.users[index]

But this won't work. Since this.users[index] is an object, whenever you change it, it will change what this.initialData[index] holds, since they are both just pointing to the same object. Another problem is that when you set it like that, the initialData won't be reactive, so you must use Vue.set().

Another thing, since you just want to reset the first_name property (the one you use at <input v-model="user.first_name" >), you should then assign user[].first_name to initialData[index].

Considering those changes to edit(), in the reset() method, the addition of [index] and of the .first_name field are enough. Final code:

edit: function(index) {
  this.users[index].disabled = false
  Vue.set(this.initialData, index, this.users[index].first_name);
},
reset: function(index) {
  this.users[index].disabled = true
  this.users[index].first_name = this.initialData[index]
}

JSFiddle: https://jsfiddle.net/acdcjunior/z60etaqf/28/



Note: If you want to back up the whole user (not just first_name) you will have to clone it. An change the order of the disabled property:

edit: function(index) {
  Vue.set(this.initialData, index, {...this.users[index]});
  this.users[index].disabled = false
},
reset: function(index) {
    Vue.set(this.users, index, this.initialData[index]);
}

JSFiddle here. In the example above the clone is created using the spread syntax.

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

1 Comment

OK great - I'll need to do the clone to make this work. Thanks!
0

Input is immediately updating the model. If you want to do something like edit and save you have to take a copy and edit that. I use lodash clone to copy objects then update the fields back when save is clicked. (of course sending message to server.)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.