When using v-for with v-if, only the parent elements will be duplicated

I need to dynamically display form elements retrieved from my database.

{
 "name":  "Checkbox",
 "order": 1,
 "type":  "checkbox"
},
{
 "name":  "Dropdown",
 "order": 2,
 "type":  "dropdown"
},
{
 "name":  "Radio Buttons",
 "order": 3,
 "type":  "radio"
}

Here's my approach to generating the elements while maintaining their order:

<template v-for="question in questions">
  <div v-if="question.type == 'checkbox'">
    <el-checkbox></el-checkbox>
  </div>

  <div v-if="question.type == 'dropdown'">
    <el-dropdown></el-dropdown>
  </div>
</template>

This method works well and keeps the order intact.

However, I have some complex elements that I don't want to duplicate using v-for. Instead, I want the inner elements to be duplicated.

For instance:

<el-form-item class="u-m-b-0" v-if="question.type == 'radio'">
    <div class="radio-input__container">
        <input type="radio" name="option" value="First Option"></input>
        <input type="radio" name="option" value="Second Option"></input>
        <input type="radio" name="option" value="Third Option"></input>
    </div>
    <div class="radio-inputs">
        <el-radio></el-radio>
    </div>
</el-form-item>

The current implementation duplicates everything, which is not desired.

An ideal solution would look like this:

<el-form-item class="u-m-b-0" v-if="question.type == 'radio'">
    <div class="radio-input__container">
        <div class="radio-input__label">Option A</div>
        <div class="radio-input__label">Option B</div>
        <div class="radio-input__label">Option C</div>
    </div>
    <div class="radio-inputs">
        <el-radio v-for="question in questions.questions"
            v-if="question.type == 'radio'"
            :key="question.id" v-model="answers[question.id]"
            class="radio-input__item">
        </el-radio>
    </div>
</el-form-item>

Unfortunately, this approach doesn't work as expected. Removing the template loop for individual elements would disrupt the order. Any suggestions on how to solve this?

Any ideas or solutions are greatly appreciated.

Answer №1

If you're looking to group adjacent elements in a list into a table, one way to achieve this is by creating a computed property in Vue that handles the grouping without altering the original data structure. This modified version of the database will merge consecutive table questions into a single object. Here's an example implementation:

computed: {
//...
  groupedQuestions(){
    return this.questions.reduce(function(grouped, current){
      if(current.type !== 'table'){
        return grouped.concat(current);
      }
      else {
        let last = grouped.pop();

        if(last.type !== 'table'){
          Object.assign({}, current, {questions: [current]});
          return grouped.concat(last).concat(current);
        }
        else {
          last.questions.push(current);
          return grouped.concat(last);
        } 
      }
    }, []);
  }
}

You can then use this computed property in your template like so:

<template v-for="question in groupedQuestions">
  <div v-if="question.type == 'text'">
    <el-input></el-input>
  </div>

  <div v-if="question.type == 'wysiwyg'">
    <el-input></el-input>
  </div>

  <el-form-item class="u-m-b-0" v-if="question.type == 'table'">
    <div class="table-3-col__container">
        <div class="table-3-col__title">Year</div>
        <div class="table-3-col__title">Employer</div>
        <div class="table-3-col__title">Job Title</div>
    </div>
    <div class="table-3-col__inputs">
        <el-input v-for="question in question.questions"
            :key="question.id" v-model="answers[question.id]"
            class="table-3-col__input">
        </el-input>
    </div>
  </el-form-item>
</template>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Modify the flashVars in flowplayer using swfObject to switch videos

I am currently implementing a cross-browser solution to play .mp4 video files and I need to ensure compatibility with IE8 and newer versions. The approach I am using is referenced from Dev-Metal and so far, everything has been successfully configured and i ...

Update the content of the document element by assigning it a lengthy string

I'm utilizing JQuery to dynamically assign content to a div element. The content has numerous lines with specific spacing, so this is the approach I am taking: document.getElementById('body').innerHTML = "Front-End Developer: A <br/> ...

Vue.js and Firestore will only update variables that do not have empty string values

Modify the variables that are not empty strings const state = reactive({ birthNumber: '', phoneNumber: '', DoctorName: '', DoctorPhone: '', }) db.collection(state.user.uid).doc( ...

Sorting a CountBy Array in VueJS with the help of lodash

Received the following JSON data: [{ "STATUS": "0500", "POSID": "..." }, { "STATUS": "1500", "POSID": "..." }, { "STATUS": "0500", "POSID": "..." }] Utilized lodash's countBy function to calculate the values: countData (data) { return _.countBy ...

What is the best way to connect depositors with withdrawers using Node.js?

I am in need of a matching-engine microservice for my application, where I have to establish a matching system between depositors and withdrawers. To achieve this, all the details of depositors and withdrawers are stored in a redis cache. With numerous req ...

What exactly happens when we use [0] in the expression $("#id")[0]?

I believe this code snippet involves an array index, but I'm unsure of the array it's referencing. It's commonly found in code similar to the following example: HTML: <canvas id = "id"> </canvas> JavaScript/jQuery: var canvas ...

The Next.js router translates query parameters into encoded format when using the router.push

I'm attempting to create a redirect using router.push in order to include a query string. However, when I try to pass a special character like a comma as part of the parameter value, it encodes my URL. Can you actually include ',' in a URL u ...

Triangles in Three.js fail to render

Here's the complete code snippet: http://jsfiddle.net/YzR33/ My goal is to create triangles and assign colors to each vertex. However, I'm encountering an issue where certain triangles are not being displayed when specific coordinates are set. ...

Substitute all instances of null bytes

I need to remove null bytes from a string. However, after replacing the null bytes \u0000 in the string let data = {"tet":HelloWorld.\u0000\u0000\u0000\u0000"} let test = JSON.parse(data).tet.replace("\u0000", ""); I always ...

Set the present month as the default value for the input type month in a vue.js application

Is there a way to populate the current month in an input type month in vue.js? I'm not sure how to go about it. Any suggestions? HTML: <input type="month" v-model="month"> JS: data() { return{ date: ...

What are the capabilities of an INNER JOIN query in Objection JS?

Here is the data model that I am working with: https://i.stack.imgur.com/g1T5i.jpg In this model, a User can be associated with multiple Projects, and a Project can have many Users. These relationships are managed through a join table called UserProjects. ...

Trouble with Bootstrap v4 toggle drop-down menu functionality detected in local environment, yet functions correctly when live on the

Today, I've encountered an issue with my Bootstrap v4 collapsible hamburger menu on my local XAMPP server. Interestingly, the menu works perfectly fine on my public website when the display is 768px wide in Chrome and Firefox. I have searched through ...

Implementing jQuery Validation Plugin for Form Fields including Textarea

I'm struggling a bit with understanding how to incorporate the jQuery Validation Plugin into my form submission process using Ajax: $(document).delegate("'#submit-quote'", "submit", function(){ var quoteVal = $(this).find('[nam ...

Guide to dynamically loading data using jquery-localize

Currently, I am utilizing the jquery-localize plugin to handle translation on my webpage. My query pertains to the possibility of dynamically loading JSON data (received from the server) instead of relying on pre-existing files. This approach would greatly ...

Error: The module "node_modules/react/index.js" does not export "default"

First time using Rollup to create a library and encountering an error with a basic button component when running rollup - c src/index.ts → dist/esm/index.js... [!] RollupError: "default" is not exported by "node_modules/react/index.js&qu ...

Requiring a landing page to be shown to each individual visitor

I am in the process of creating a landing page for an upcoming music release. I want to display this splash page every time a visitor lands on the home page, without setting the splash page as the base href. Would using JavaScript be the most effective m ...

Utilizing a GLTF asset as the main Scene element in a Three.js project

I'm struggling with incorporating a gltf model as the main scene in Three.js. Specifically, I have a gltf model of an apartment that I want to load from inside and not outside the apartment. I also need the controls to work seamlessly within the apart ...

Utilizing Vue.js to dynamically add a class through computed properties

As a beginner in Vue.js, I want to dynamically add or remove classes based on certain conditions. Specifically, I am trying to remove the success class when the total sum exceeds 25, but for some reason the color is not changing as expected. Can anyone p ...

The validationSchema function argument value in vee-validate@next is consistently observed to be undefined

I recently created a simple login form in Vue 3 and I'm currently attempting to validate it using the vee-validate@next composition API method. You can view the code on stackblitz: https://stackblitz.com/edit/vue-zauhqb However, I've encountered ...

The issue of Nuxt i18n routing not functioning properly with sub pages

After modifying my app to integrate with nuxt i18n, I encountered an issue where the translations only work when accessing routes directly. For example, http://localhost:3000/fr/step/1 My app has a structured layout where each step is represented by a di ...