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: "" }] },
]);