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.

11
  • Possible duplicate of How to do databind two way in v-html? Commented Oct 2, 2018 at 21:32
  • @HamzaMohamed no it’s not. Commented Oct 3, 2018 at 4:33
  • so let me get that straight, you are trying to change <p> to have an <input> tag when when user click it or click another button? and the input to be stored so it can be sent through the form? Commented Oct 3, 2018 at 5:18
  • When the user clicks another button, yes sir. The input needs to be sent in a POST request so yeah. Commented Oct 3, 2018 at 5:19
  • got it, but i got something that is not clear yet, that should be in html not text? the user should see and add html tags? or edit without tags? Commented Oct 3, 2018 at 5:23

1 Answer 1

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.

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

5 Comments

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)
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.
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 if you would like, we can join a chat room and finish it
That would be great. But before, you can have a look at my new question which should give you more details about my issue → stackoverflow.com/questions/52622907/…

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.