Ale
Ale

Reputation: 1052

How to replace a placeholders from a text with input fields and bind them with v-model with Vue.js

I'm building an exam page with test questions. The questions are from "fill in the gaps" type. I got the questions from ajax request. The questions are simple text with specific placeholders for the places where the "fill in the gap" should be. The questions can have one or more "fill in the gap".

Here is an example: The apples are {green} or {red}, some times {yellow}.

This should be converted to <p>The apples are <input type='text' v-model='gap1'> or <input type='text' v-model='gap2'>, some times <input type='text' v-model='gap3'>.

So far I have managed to use them in my component with a computed value:

computed: {
    addGapsField () {
        let reg = /\{.*?\}/g
        let mtch = ''
        let text = this.question

        // loop through each match
        while((mtch = reg.exec(text)) !== null) {
            text = text.replace(mtch[0],"<input type='text'>")
        }
        return text 
    }
}

How can I bind a v-model to this dynamically generate input fields. Or is there any other way around (v-model is not the necessary solution i'm looking for, I'm not much familiar with what other options do Vue.js has).

Upvotes: 4

Views: 1327

Answers (1)

Sovalina
Sovalina

Reputation: 5609

You can possibly split your question into an array and iterate with a v-for inside the template (but you need to use <span> for an inline display)

new Vue({
  el: "#app",
  data: {
    question: "The apples are {green} or {red}, some times {yellow}.",
    gaps: [],
    last: ''
  },
  computed: {
    addGapsField () {
      let reg = /\{.*?\}/g
      let text = this.question.split(reg)
      text.forEach((part, i) => {
        this.gaps.push('gap' + (i+1))
      })
      this.last = text.pop()
      return text
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>

<div id="app">
  <span v-for="(part, index) in addGapsField">
    {{ part }}<input v-model="gaps[index]">
  </span>
  <span>{{ last }}</span>
</div>

Upvotes: 2

Related Questions