13

I am working on Vue js and having an issue editing a field. When I click on a field to edit it, all the editable fields become active. Here is my code.

 export default {
        props: ['profileHeight'],

        data() {
            return {
                User: User,
                isEditing: false,
                form:{
                    name:'',
                    email: '',
                },
            };
        },

        mounted() {
        },

        methods: {
            activateInEditMode() {
                this.isEditing = true
            },
            deActivateInEditMode() {
                this.isEditing = false
            }
        }
    }
 <span>Profile settings</span>
                        <p>Full name<span v-on:click="activateInEditMode" v-show="!isEditing">{{User.state.auth.name}}</span>
                            <span v-show="isEditing" >
                             <input v-model="form.name" type="text" class="form-control" >
                            </span>
                        </p>

                        <p>E-mail<span>{{User.state.auth.email}}</span>
                            <span v-show="isEditing" >
                             <input v-model="form.email" type="text" class="form-control" >
                            </span>
                        </p>

enter image description here

4
  • You used same v-model="form.name" for both!! Change it to different! Commented Jul 12, 2017 at 6:39
  • Also take form:{ name:'', email: '' } in data() Your problem solved!:) Commented Jul 12, 2017 at 6:49
  • @HirenGohel not really, because it checks isEditing variable and shows all the fields. Commented Jul 12, 2017 at 6:55
  • Ok, but you need to define this for edit! I know issue not solved with define this! Commented Jul 12, 2017 at 6:57

3 Answers 3

15

Try using focus and blur methods to show/hide form elements! Hope this helps!

                            
new Vue({
  el: '#app',
  data(){
    return {
      user : {
        name: '',
        email: ''
      },
      editField : ''
    }
  },
  methods : {
    focusField(name){
      this.editField = name;
    },
    blurField(){
      this.editField = '';
    },
    showField(name){
      return (this.user[name] == '' || this.editField == name)
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
  <h1>Profile settings</h1>
  <label for="user-name">Full name</label>
  <div class="field">
    <span class="field-value" v-show="!showField('name')" @click="focusField('name')">{{user.name}}</span>
    <input v-model="user.name" v-show="showField('name')" id="user-name" type="text" class="field-value form-control" @focus="focusField('name')" @blur="blurField">
  </div>
  
  <label for="user-email">Email address</label>
  <div class="field">
    <span class="field-value" v-show="!showField('email')" @click="focusField('email')">{{user.email}}</span>
    <input v-model="user.email" v-show="showField('email')" type="email" class="field-value form-control" @focus="focusField('email')" @blur="blurField">
  </div>
</div>

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

3 Comments

looking for an optimum solution so that I don't need to create computed properties, form may have 10 fields so I need to create 10 computed properties?
You can define method instead. Take a look to edited example
If we don't make any changes to the text, it doesn't get closed on blur
13

There are are dozens of ways to do this. I might recommend a component.

console.clear()

Vue.component("editable",{
  props:["label", "value"],
  template:`
  <p>
    {{label}} 
    <span @click="editing=true" v-show="!editing">
      {{value}}
    </span>
    <span v-show="editing" >
      <input :value="value"
             @input="$emit('input', $event.target.value)"
             @keydown.enter="editing=false"
             type="text" 
             class="form-control" >
    </span>
  </p>
  `,
  data(){
    return {
      editing: false,
    }
  }
})

const User = {
  name: 'bob',
  email: '[email protected]'
}

new Vue({
  el:"#app",

  data() {
    return {
      form: User
    };
  },
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <span>Profile settings</span>
  <editable label="Full name" v-model="form.name"></editable>
  <editable label="E-mail" v-model="form.email"></editable>
  <br>
  {{form}}
</div>

Comments

7

I have written a component for this, I call it Click-to-Edit.

What it does:

  • Supports v-model
  • Saves changes on clicking elsewhere and on pressing Enter

ClickToEdit.vue:

<template>
  <div>
    <input type="text"
           v-if="edit"
           :value="valueLocal"
           @blur.native="valueLocal = $event.target.value; edit = false; $emit('input', valueLocal);"
           @keyup.enter.native="valueLocal = $event.target.value; edit = false; $emit('input', valueLocal);"
           v-focus=""
             />
        <p v-else="" @click="edit = true;">
          {{valueLocal}}
        </p>
    </div>
</template>

<script>
  export default {

  props: ['value'],

  data () {
  return {
      edit: false,
      valueLocal: this.value
    }
  },

  watch: {
    value: function() {
      this.valueLocal = this.value;
    }
  },

  directives: {
    focus: {
      inserted (el) {
        el.focus()
      }
    }
  }

}
</script>

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.