Home > Back-end >  creating sub section in vuejs not working
creating sub section in vuejs not working

Time:10-30

I am working on vuejs application that require creating of section and subsection

I tried creating subsection by clicking on the add sub section but it is giving me error

Uncaught TypeError: sections[1] is undefined

Template

This is template that displays the sections and subsection on the page

<div v-if="sections.length > 0 ">
                    <div  v-for="(section, index) in sections" :key="index">
                    <div><input type="text" placeholder="Enter Section Title" v-model="section.title" ></div>
                        <div  v-for="(sub_section, index) in section.sub_sections" :key="index">
                            <div >
                                <input type="text" placeholder="Enter Sub Section Title" v-model="sub_section.title"  >
                            <div >
                                <label for="">
                                    <div>
                                        <input type="file" @change="uploadFile( $event )" name="" id="">
                                        Upload File
                                    </div>
                                    <img src="@/assets/images/upload.png" alt="">
                                </label>
                                    
                            </div>
                        </div>
                        <div >
                            <div >
                                <img :src="sub_section.url"  alt="">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <button @click="addSubSection" >
                Add Sub Section
            </button>
            <button @click="addSection" >
                Add Section
            </button>

javascript

This is the javascript(vue) that stores the form on array and displays them.

export default {
  name: 'CreateCourse',
  setup(){
      const sections = reactive([{'title': '', 'sub_sections': [{'title': '', 'file': '', 'url': ''}]}]);
  const addSection = () => {
            sections.push({"title": "", 'sub_sections': [{'title': '', 'file': '', 'url': ''}]});
        }
        const addSubSection = () => {
            
            sections[1].sub_sections.push({"title": "", 'file': '', 'url': ''});
        }

        const uploadFile = (e) => {
            console.log(e.target.files[0]);
            sections[1].sub_sections[1].file = e.target.files[0];
            sections[1].sub_sections[1].url = URL.createObjectURL(sections[1].sub_sections[1].file);
        }
    return {
        sections
    }
  }
}

How do I solve this problem?

CodePudding user response:

You need to return functions from setup function, and pass index to addSubSection function:

<script>
import { reactive } from "vue";
  
export default {
  name: 'CreateCourse',
  setup(){
    const sections = reactive([{'title': '', 'sub_sections': [{'title': '', 'file': '', 'url': ''}]}]);
    const addSection = () => {
      sections.push({"title": "", 'sub_sections': [{'title': '', 'file': '', 'url': ''}]});
    }
    const addSubSection = (idx) => {   
      sections[idx].sub_sections.push({"title": "", 'file': '', 'url': ''});
    }
    const uploadFile = (e, idx, i) => {
      console.log(e.target.files[0]);
      sections[idx].sub_sections[i].file = e.target.files[0];
      sections[idx].sub_sections[i].url = URL.createObjectURL(sections[idx].sub_sections[i].file);
    }
    return { sections, addSection, addSubSection, uploadFile }
  }
}
</script>
<template>
  <div v-if="sections.length > 0 ">
    <div class="__course-sub-section" v-for="(section, index) in sections" :key="index">
      <div>
        <input type="text" placeholder="Enter Section Title" v-model="section.title" class="section-title form-control x_focus">
      </div>
      <div class="__upload-section d-flex justify-content-between align-items-center" v-for="(sub_section, idx) in section.sub_sections" :key="idx">
        <div class="d-flex">
          <input type="text" placeholder="Enter Sub Section Title" v-model="sub_section.title"  class="section-title form-control x_focus">
          <div class="__choose">
            <label for="">
              <div>
                <input type="file" @change="uploadFile( $event , index, idx)" name="" id="">
                Upload File
              </div>
              <img src="" alt="">
            </label>
          </div>
        </div>
        <div class="__sub-section-image">
          <div class="placeholder">
            <img :src="sub_section.url"  alt="">
          </div>
        </div>
      </div>
      <button @click="addSubSection(index)" class="app_button primary_btn d-flex mt-4">
        Add Sub Section
      </button>
      <button @click="addSection" class="app_button primary_btn d-flex mt-4">
        Add Section
      </button>
    </div>
  </div>
</template>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Try this:

const sections = reactive([
      { title: "", sub_sections: [{ title: "", file: "", url: "" }] },
      { title: "", sub_sections: [{ title: "", file: "", url: "" }] },
]);
  • Related