0
votes

I have an dynamic table where new row can be added as well as removed ,im populating text field values based on Onchange event of Select option ,For the first row i can populate the values but once i append a new row ,the old values of the past row gets removed.

export default {
    data() {
        return {
            //editmode:true,
            templatename: '',
            type: 'margin',
            games: {},
            fields: {},
            subs: {},
            rows: []
            // errors: {},
        }
    },

    components: {
        Datepicker,
        MinusIcon,
        PlusIcon,
        XCircleIcon
    },

    methods: {



        getexcercisesrepcount: function(event, dynamicrow) {
            var currentrow = dynamicrow;
            var excercise = event;
            const URL = baseurl + `api/getexcercisesrepcount/`
            axios({
                    method: 'post',
                    url: URL,
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    data: excercise
                })
                .then(response => {
                    var rowsdata = response.data;
                    var i = 0;

                    for (i; i < rowsdata.length; i++) {
                        var exid = rowsdata[i].id;
                        if (dynamicrow != null) {
                            var crval = $("#set" + currentrow).val(exid); //This is where i set value for the table row

                        }
                    }
                });

        },

        addRow: function() {

            var elem = document.createElement('tr');
            this.rows.push({

                workoutname: "",
                workoutcategory: "",
                set: "",
                rep: "",
                resttime: "",
                tempo: ""

            })

        },

        removeElement: function(index) {
            this.rows.splice(index, 1);
        },
    },
}

This is my table where i have added text fields as well as select option

<table class="border-collapse" style="width: 100%;" id="mytable">
    <tr>
        <th class="p-2 border border-solid d-theme-border-grey-light" width="25%">Workout</th>
        <th class="p-2 border border-solid d-theme-border-grey-light text-center" width="25%">Excercise</th>
        <th class="p-2 border border-solid d-theme-border-grey-light">Set</th>
        <th class="p-2 border border-solid d-theme-border-grey-light">Rep</th>
        <th class="p-2 border border-solid d-theme-border-grey-light">Rest time</th>
        <th class="p-2 border border-solid d-theme-border-grey-light">Tempo</th>
    </tr>
    <tr :id="'tr'+index" v-for="(row, index) in rows" :key="index">
        <td class="p-2 border border-solid d-theme-border-grey-light">
            <vs-select v-model="row.workoutname" v-validate="'required'" @change="getworkoutexcercises($event)" name="workoutname[]" :id="'wrkout'+index" class="w-full select-large" autocomplete>
                <vs-select-item :key="game.id" :value="game.id" :text="game.workoutname" v-for="game in games" class="w-full" />
            </vs-select>
        </td>
        <td class="p-2 border border-solid d-theme-border-grey-light">
            <vs-select v-model="row.workoutcategory" v-validate="'required'" @change="getexcercisesrepcount($event,index)" name="workoutcategory[]" :id="'wrkcat'+index" class="w-full select-large" autocomplete>
                <vs-select-item :key="game.id" :value="game.id" :text="game.subexname" v-for="game in subs" class="w-full" />
            </vs-select>
        </td>
        <td class="p-2 border border-solid d-theme-border-grey-light"><input type="text" class="form-control" v-validate="'required'" v-model="row.exsets" name="set[]" :id="'set'+index" value="" /></td>
        <td class="p-2 border border-solid d-theme-border-grey-light"><input type="text" class="form-control" v-validate="'required'" v-model="row.rep" name="rep[]" :id="'rep'+index" /></td>
        <td class="p-2 border border-solid d-theme-border-grey-light"><input type="text" class="form-control" v-validate="'required'" v-model="row.resttime" name="resttime[]" :id="'resttime'+index" /></td>
        <td class="p-2 border border-solid d-theme-border-grey-light"><input type="text" class="form-control" v-validate="'required'" v-model="row.tempo" name="tempo[]" :id="'tempo'+index" /></td>
        <a v-on:click="removeElement(index);" style="cursor: pointer">
            <x-circle-icon size="1.5x" class="custom-class" style="margin-left: 5px;margin-top: 15px;color:red;"></x-circle-icon>
        </a>
    </tr>
</table>
<button style="margin-top:15px;margin-bottom:15px;" class="button btn-primary" @click="addRow">Add row</button>
1

1 Answers

0
votes

You shouldn't create HTML in vue components, rather you should use the virtual DOM and things like v-for to create the HTML you want instead of doing it with createElement.

And in the case that you do use the v-dom and you run into a similar issue, you want to use key to uniquely tag each node so Vue knows what belongs with what.

But main point is that you shouldn't be manipulating the DOM directly from Vue functions ever. It's performance taxing and you lose the benefit of reactivity, as you have noticed.

Look into v-for and vue's documentation on rendering lists for what you are trying to achieve: https://vuejs.org/v2/guide/list.html