mafortis
mafortis

Reputation: 7128

Append html in vue component

I need to append m returned data when axios got success but it only appends some part of my code,

Screenshot

When I click save it supposed to print back my saved data in input fields again with different button for update. but it only prints labels

one

Code

HTML

<template>
  <div>
    <div class="variationData"></div>
  </div>
</template>

script

    export default {
      data() {
            return {
                variationParents: [
                    {
                        name: '',
                        type: ''
                    }
                ],
                variationChilds: [
                    {
                        name: ''
                    }
                ],
              }
     },
     methods: {
        addVariants(e) {
            e.preventDefault();
            axios.post('/api/admin/variations/store', {
                childs: this.variationChilds,
                parent: this.variationParents,
            })
            .then(res => {
                console.log(res);
                this.isLoading = false;

                // print back saved data
                $(res.data.data).each(function(_, i){
                    $(i).each(function(__, ii){
                        var row = `<el-col :span="24" style="margin-top:15px;">
                            <el-form-item label="Variation Name">
                                <el-col :span="12" style="margin-top:15px;">
                                    <el-input placeholder="Please input your variation name" value="${i.name}" class="input-with-select"></el-input>
                                    </div>
                                </el-col>

                                <el-col class="line text-center" :span="3">Variation Value(s)</el-col>
                                <el-col :span="9" style="margin-top:15px;">
                                    <el-input value="${ii.name}" placeholder="Please input your variation value" class="input-with-select"></el-input>
                                </el-col>


                                <el-col :span="24" style="margin-top:15px;">
                                    <el-button type="primary" native-type="submit">Update Variations</el-button>
                                </el-col>
                            </el-form-item>
                        </el-col>`;
                        $('.variationData').html(row);
                    });
                });
                //
            })
            .catch(error => {
                console.log(error);
            })
        },
      },
    }

any idea?

Update

here is how my saved data is returning

one

and here is what i get based on Qonvex620 answer

two

Issues

with provided answer of Qonvex620 i get this issues

  1. Only first saved data will append and for second time etc. it returns [Vue warn]: Missing required prop: "value"
  2. I need to loop child elements of saved data in append as well

Current code

HTML

<div class="variationData">
    <template v-for="(item, index) in savedVariations" >
        <div :key="index">
            <el-col :span="12" style="margin-top:15px;">
                <!-- parent -->
                <el-input :value="item.name" placeholder="Please input your variation name" class="input-with-select">
                    <el-select slot="prepend" placeholder="Select">
                        <el-option label="Text" :value="item.type"></el-option>
                        <el-option label="Text Area" :value="item.typerea"></el-option>
                        <el-option label="Boolean" :value="item.typean"></el-option>
                    </el-select>
                </el-input>
            </el-col>

            <el-col class="line text-center" :span="3">Variation Value(s)</el-col>
            <el-col :span="9" style="margin-top:15px;">
                <!-- child's -->
                <el-input :value="item.name" placeholder="Please input your variation value" class="input-with-select">
                </el-input>
            </el-col>
        </div>
    </template>
</div>

Script

data() {
  return {
    savedVariations: [],
  }
},
methods: {
  addVariants(e) {
                e.preventDefault();
                axios.post('/api/admin/variations/store', {
                    childs: this.variationChilds,
                    parent: this.variationParents,
                })
                .then(res => {
                    console.log(res);
                    this.isLoading = false;

                    //
                    this.savedVariations= res.data.data
                    //
                })
                .catch(error => {
                    console.log(error);
                })
  },
}

Update 2

I have managed to loop my childs data as well but one issue still remained: if i add second set of data in will override first appended data instead of add below/above it

three

Code

<div class="variationData">
    <template v-for="(item, index) in savedVariations" >
        <div :key="index">
            <el-col :span="12" style="margin-top:15px;">
                <!-- parent -->
                <el-input :value="item.name" placeholder="Please input your variation name" class="input-with-select">
                </el-input>
            </el-col>

            <el-col class="line text-center" :span="3">Variation Value(s)</el-col>
            <el-col :span="9" style="margin-top:15px;">
                <template v-for="(itemm, indexx) in item.children" >
                    <div :key="indexx">
                        <!-- child's -->
                        <el-input :value="itemm.name" placeholder="Please input your variation value" class="input-with-select">
                        </el-input>
                    </div>
                </template>
            </el-col>
        </div>
    </template>
</div>

idea?

Update 3 - SOLVED

My remained issue (multiple append "on each time save) solved with this code:

.then(res => {
    this.savedVariations.push(res.data.data);
})

four

Upvotes: 0

Views: 602

Answers (2)

Qonvex620
Qonvex620

Reputation: 3972

Declare a variable on your data like below

data() {
  return {
     rows: []
  }
}

now in your axios script you can do this in success return

axios.get('/admin/price/fetch_roomtypes').then(res => {
     this.rows= res.data.data
}) 

and in your html like this

<div class="variationData">
    <template v-for="(item, index) in row">
       <el-col :span="24" style="margin-top:15px;" :key="index">
           ...
           ...
       </el-col>
    </template>
</div>

To loop the variation values of the parent you need to access it, see code below

<div class="variationData">
        <template v-for="(item, index) in row">
           <el-col :span="24" style="margin-top:15px;" :key="index">
                <div v-for="values in item.variation_values">   // variations values, just change it using your template you used. just an idea
                       ...
                       ...
                </div>
           </el-col>
        </template>
    </div>

so in you case you must structure you data like this code below,

data() {
      return {
         variants: [
               {
                  name: '',
                  values: []
               }
         ]
      }
    }

now when you append new variation it will like this

addVariants() {
   this.variants.push(
      name: 'test'
      values: [5, 10, 3]
  )

}

Upvotes: 2

artikandri
artikandri

Reputation: 180

From what I'm seeing, the button is not rendered because you are not using native HTML elements, but custom Vue element (el-col, el-button, el-input, etc). If you want to populate the HTML with custom element, I suggest you rendering the element with v-for as per Qonvex620's answer, or directly use HTML native elements just like below.

$(res.data.data).each(function(_, i){
                    $(i).each(function(__, ii){
                        var row = `<div :span="24" style="margin-top:15px;">...
                                    <input placeholder="Please input your variation name" value="${i.name}" class="input-with-select">...
                                    <input value="${ii.name}" placeholder="Please input your variation value" class="input-with-select">


                                ...
                                    <button type="submit">Update Variations</button>...
                            </div>
                        </div>`;
                        $('.variationData').html(row);
                    });
                });

But really, rendering the HTML like Qonvex620's answer is much better. You can maximize Vue's full functionality that way.

Upvotes: 0

Related Questions