0

I have the following in my Messages.vue file:

<div class="msg" v-for="(msg, index) in messages" :key="index">
    <p class="msg-index">[{{index}}]</p>
    <p class="msg-subject" v-html="msg.subject"></p>
    <p class="msg-body" v-html="msg.body"></p>
    <input type="submit" @click="deleteMsg(msg.pk)" value="Delete" />
    <input type="submit" @click="EditMsg(msg.pk)" value="Edit" />
</div>
<script>
export default {
  name: "Messages",
  data() {
    return {
      subject: "",
      msgBody: "",
      messages: [],
    };
  },
  mounted() {
    this.fetchMessages();
  },
  ....

I want msg-subject and msg-body to change to input HTML elements, so the user can edit and submit them to be updated. I'm not really sure what's the best way to achieve this kind operation with VueJS.

Constantin Chirila
  • 1,979
  • 2
  • 19
  • 33
zerohedge
  • 3,185
  • 4
  • 28
  • 63

1 Answers1

1
<template>
  <div>
      <div class="msg" v-for="msg in messages" :key="msg.id">
          <p class="msg-index">[{{  msg.id }}]</p>
          <p class="msg-subject" v-text="msg.subject" 
            v-show="!msg.editing"></p>
          <input type="text" name="msg-subject"
            v-model="msg.subject" v-show="!!msg.editing">
          <p class="msg-body" v-text="msg.body" 
            v-show="!msg.editing"></p>
          <input type="text" name="msg-body" v-model="msg.body"
            v-show="!!msg.editing">
          <button @click="deleteMsg(msg.id)"> Delete </button>
          <button @click="editMsg(msg.id)"> Edit </button>
      </div>
  </div>
</template>




<script>
... // your usual component code
data(){
    return{
        messages:{
            ...
            editing:false,
                }
        }
    },
methods: {
    EditMsg(id){
    this.editing = true;
    // you can do a direct axios ajax or fetch to edit the updated value
    },
    deleteMsg(id){
    // you can do a direct axios ajax or fetch to delete value
    }

}
... // remaining component code
</script>

side notes:

1 => it is not advised to use index as key, index has different uses, you can read about using Index as a key is an anti-pattern here.

Hamza Mohamed
  • 1,373
  • 1
  • 12
  • 28
  • Thanks for the answer and effort Hamza. I see two potential problems with this: 1. This will toggle the editing flag for ALL message elements, right? I want only the relevant message to transform. 2. I don't think `msg.body` can be passed to an AJAX call because it returns NULL when I console.log it. (perhaps I should write a separate `message` component (see my edits) – zerohedge Oct 03 '18 at 06:51
  • my bad, for number 1, if you can add `editing` boolean the object directly and amend the `v-show="!!msg.editing"` that would be better IMHO, however if that is not possible, I shall update the answer now, for number 2, you can add validators before sending the ajax if the users didnt update the values. – Hamza Mohamed Oct 03 '18 at 08:18
  • 1
    I've tried doing exactly this, Hamza, but it's not working. I'm posting a separate question for that because it includes more relevant details and a different implementation. – zerohedge Oct 03 '18 at 08:20
  • @zerohedge if you would like, we can join a chat room and finish it – Hamza Mohamed Oct 03 '18 at 08:30
  • That would be great. But before, you can have a look at my new question which should give you more details about my issue → https://stackoverflow.com/questions/52622907/vue-js-html-element-show-if-not-toggling-changes – zerohedge Oct 03 '18 at 08:34