Bryant Tang
Bryant Tang

Reputation: 251

Vue - How to create interactive func for textarea and input field?

I have a textarea that is used to generate the input field group, but i wanna do a function is even I change the input field, the textarea also change the value. I already created the Vue js for textarea to input field but I cannot reverse. Any solution for this case?

Textarea

<v-row>
    <v-col cols="12" sm="6">
        <v-textarea
            v-model="groupTask"
            dense
            :hide-details="true"
            outlined
            label="Group Task"
        ></v-textarea>
    </v-col>
</v-row>

input field

<v-row v-for="(item, index) in tasks">
    <v-col cols="12" sm="4">
        <v-text-field
            dense
            :hide-details="true"
            outlined
            :label="'Group Task Number ('+ (index+1) + ')'"
            :name="tasksList[index]"
            v-model="item.number"
        ></v-text-field>
    </v-col>
    <v-col cols="12" sm="4">
        <v-text-field
            dense
            :hide-details="true"
            outlined
            :label="'Group Task Name ('+ (index+1) + ')'"
            :name="tasksList[index]"
            v-model="item.task"
        ></v-text-field>
    </v-col>
    <v-col cols="12" sm="4">
        <v-text-field
            dense
            :hide-details="true"
            outlined
            :label="'Group Task Price ('+ (index+1) + ')'"
            :name="tasksList[index]"
            v-model="item.price"
        ></v-text-field>
    </v-col>
</v-row>

Vue Code

<script>
export default {
    data() {
        return {
            tasks: [],
            groupTask: "",
            tasksList: [],
        };
    },
    watch: {
        groupTask: function(newValue, oldValue) {
            let data = newValue.split("\n");
            let item = Math.ceil(newValue.split("\n").length / 3);
            this.tasks = [];
            for (var loop = 0; loop < item; loop++) {
                let tmp = data.slice(loop * 3, loop * 3 + 3);
                this.tasks.push({
                    number: tmp[0],
                    task: tmp[1],
                    price: tmp[2]
                });
            }
        },
    },
    computed: {},
    methods: {},
    created() {}
};
</script>

That is what I want

Upvotes: 1

Views: 596

Answers (2)

s4k1b
s4k1b

Reputation: 3085

You can use getters and setters in a computed property and create interdependency between two varaibles.

There is no need for watchers

export default {
  data() {
      return {
          tasks: [],
          tasksList: [],
      };
  },
  computed: {
    groupTask: {
      get() {
        return this.tasksList.map(task => [task.number, task.task, tast.price]).flat().join("\n"); // your reverse code to generate groupTask string from tasksList array here
      },
      set(newVal) {
        let data = newValue.split("\n");
            let item = Math.ceil(newValue.split("\n").length / 3);
            this.tasks = [];
            for (var loop = 0; loop < item; loop++) {
                let tmp = data.slice(loop * 3, loop * 3 + 3);
                this.tasks.push({
                    number: tmp[0],
                    task: tmp[1],
                    price: tmp[2]
                });
            }
      }
    }
  }

You can learn more about computed properties and it's getters and setters from here https://v2.vuejs.org/v2/guide/computed.html#Computed-Setter

Upvotes: 1

Almas Dusal
Almas Dusal

Reputation: 663

You can use computed for groupTask and make textarea readonly or use item.task for v-model of textarea.

computed: {
    groupTask() {
        return item.task;
    }
}

Update: watch method:

watch:{
     'item.task': (newVal, oldVal) => {
         this.groupTask = newVal;
     }
 }

Upvotes: 0

Related Questions