Implementing a Vue v-for loop based on a condition with the help of

As I work on creating a form, I've come across a challenging issue for which I have yet to find a solution. The problem involves a Vuex data on Vehicles Make and Model of the vehicle. Essentially, when a make is selected, I need the form to dynamically populate the models associated with that selected make.

Here's what I have tried so far:

cars.js - (vuex module)

const state = {
  make: [
   {
    name: 'Audi',
    carid: '1',
    models: [
     {
     modelid: '1.1',
     name: 'A7',
     },
     {
     modelid: '1.2',
     name: 'A8',
     },
    ],
   },
   {
   name: 'BMW',
   carid: '2',
   models: [
    {
    modelid: '2.1',
    name: '5 Series',
    },
    {
    modelid: '2.2',
    name: '7 Series',
    },
   ],
   },
 ],
}

Cars.vue

<template>
<div class="labelos">
              <div class="label-name">
                <h4>Car make:</h4>
              </div>
              <div class="label-body">
                <label for="car-make">
                  <select v-model="selectedType" name="carmake" required>
                    <option value=""></option>
                    <option  v-for="(cars, index) in cars.make" :key="index" :value="cars.carid">{{ cars.name }}</option>
                  </select>
                </label>
              </div>
            </div>
            <div class="labelos">
              <div class="label-name">
                <h4>Car model:</h4>
              </div>
              <div class="label-body">
                <label for="car-model">
                  <select>
                    <option value=""></option>
                    <option v-for="(model, index) in cars.make" :key="index" :value="cars.carid">{{ model.carid }}</option>
                  </select>
                </label>
                Model:
              </div>
            </div>
    </template>
<script>
import { mapState } from 'vuex';
export default {
  name: 'cars',
  data() {
    return {
      selectedType: '',
      selectedCity: '',
    };
  },
  methods: {

  },
  components: {
    Headers,
    Footers,
  },
  computed: {
    ...mapState([
      'cities', 'cars',
    ]),
  },
};
</script>

As seen in the first label loop through makes, the selected car make is saved as selectedType. I am seeking a solution to dynamically load the second dropdown based on this selection. For instance, if carid 1 is selected, the list should populate with car models available under that specific carid.

I look forward to any insights or suggestions as I am currently stuck without a solution. This is the progress I have made thus far.

Cheers

Answer №1

To dynamically display model options based on the selected make type, you can create a computed property in Vue.js. This property will return model options based on the value of the selected make type, and it will automatically update whenever the selected make changes:

models() {
  if (this.selectedType) {
    return this.cars.make.find((car) => car.carid === this.selectedType).models;
  }
}

Here's an example of how it can be implemented:

const store = new Vuex.Store({
  state: {
    cars: {
      make: [{
        name: 'Audi',
        carid: '1',
        models: [
          { modelid: '1.1', name: 'A7' },
          { modelid: '1.2', name: 'A8' },
        ]
      }, {
        name: 'BMW',
        carid: '2',
        models: [
          { modelid: '2.1', name: '5 Series' },
          { modelid: '2.2', name: '7 Series' }
        ],
      }]
    }
  }
})


new Vue({
  el: '#app',
  store,
  data() {
    return {
      selectedType: '',
    };
  },
  computed: {
    ...Vuex.mapState(['cars']),
    models() {
      if (this.selectedType) {
        return this.cars.make.find((car) => car.carid === this.selectedType).models;
      }
    }
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
<div id="app">
  <h4>Car make:</h4>
  <select v-model="selectedType" name="carmake" required>
    <option value=""></option>
    <option  v-for="(cars, index) in cars.make" :key="index" :value="cars.carid">{{ cars.name }}</option>
  </select>

  <h4>Car model:</h4>
  <select>
    <option value=""></option>
    <option v-for="(model, index) in models" :key="index" :value="model.modelid">{{ model.name }}</option>
  </select>
</div>

Answer №2

Here's a practical demonstration using the provided data:

const vehicleData = {
  makers: [
    {
      name: 'Audi',
      carid: '1',
      models: [
       {modelid: '1.1', name: 'A7'},
       {modelid: '1.2', name: 'A8'}
      ]
    }, {
      name: 'BMW',
      carid: '2',
      models: [
        {modelid: '2.1',  name: '5 Series'},
        {modelid: '2.2',  name: '7 Series'}
      ]
    }
  ]
}

new Vue({
  el: '#app',
  data: {
    vehicleData: vehicleData,
    selected: 0
  },
  computed: {
    models () {
      var maker = this.vehicleData.makers.find(m => m.carid === this.selected)
      return maker ? maker.models : []
    }
  }
})
<div id="app">
  <select v-model="selected">
    <option value="0" selected>Choose maker</option>
    <option
      v-for="maker in vehicleData.makers"
      :key="maker.carid"
      :value="maker.carid"
    >{{ maker.name }}</option>
  </select>
  <br>
  <select>
    <option value="0" selected>Select model</option>
    <option
      v-for="model in models"
      :key="model.modelid"
      :value="model.modelid"
    >{{ model.name }}</option>
  </select>
</div>

<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ed9b9888addfc3d8c3de">[email protected]</a>/dist/vue.min.js"></script>

If possible, consider changing 'modelid' to simple integers like 1, 2, etc. Also, if applicable and known, modifying the data structure by separating makers and models into distinct arrays/objects might be beneficial.

Answer №3

If you're looking for a solution to a specific task, check out this plugin: vue-dependon. It may not have been updated in a while, but exploring its source code could provide insight into how it functions.

UPDATE:
To address your task, focus on the source code and pay special attention to the loadOptions function and the code block between lines 83 and 105. Customize this code to suit your requirements.

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

The Vue Select component retrieves the ID value from the selected array

I have been using the Vue Select component and have been working tirelessly all day trying to extract the value id from the selected array. <v-select multiple label="name" :on-change="consoleCallback" :options="option" :value.sync="option.id" :value="i ...

The Adonis 5 build failed to transfer the environment file to the designated build directory

During my experience with Adonis 5 in production, I consistently encountered an issue where the .env file failed to copy into the build folder when I attempted to run `npm run build`. Is this still considered a bug in the system? ...

Issue with the Bootstrap carousel jQuery plugin

Hi everyone, I need some help with creating a multiple items bootstrap carousel. I keep getting an error message that says "#Carousel".carousel is not a function TypeError: "#Carousel".carousel is not a function. Can anyone guide me on how to fix this issu ...

Return to the previous URL after executing window.open in the callback

I need help redirecting the callback URL back to the parent window that initially called window.open. Right now, the callback URL opens inside the child window created by the parent. Here's the scenario: The Parent Window opens a child window for aut ...

Condition for button functionality

I have a Submit button that, when pressed, triggers the onSubmit function. <b-form @submit.stop.prevent="handleSubmit(onSubmit)"> ... <b-button type="submit" >Submit</b-button> <script lang="ts ...

Creating a smooth fading effect for an element within a react component

I am currently working on implementing a fade out warning/error message (styled with Bootstrap) in a React component, however, I am encountering some challenges with the timing of the fade-out effect. Up to this point, the fade out effect is functioning c ...

Retrieve the entire Vuetify component from v-autocomplete

Is there a way to retrieve the entire array element of an Autocomplete item in order to store it in Vuex without needing to store each individual item separately (e.g. first name, middle initial, last name)? I am referencing a similar question that was pre ...

How can you automatically show the current time upon entering a page using React Native?

Is there a way to automatically display the current time when a user enters the page? I currently have code that only shows the current time when the TouchableOpacity is pressed, but I want it to update automatically as soon as the user arrives on the Ne ...

Trigger $q manually in AngularJS

My understanding of $q in AngularJS is that it runs every time I refresh my page, similar to using a function in ng-init. Here is the code for $q.all that I have: $q.all([$scope.getCart(), $scope.getCategory(), $scope.getMenu(), $scope.getRestaurant()]). ...

Combining a Python backend with an HTML/CSS/JS user interface for desktop applications: the perfect synergy?

Is it possible to seamlessly combine Python code with HTML/CSS/JS to develop desktop applications? For instance, I want to create a function in Python that displays "Hello World!" and design a visually appealing user interface using HTML/CSS/JS. How can I ...

Continuously receiving the value of undefined

I am currently working on a JavaScript Backbone project and I have declared a global object as follows: window.App = { Vent: _.extend({}, Backbone.Events) } In the initialize function, I have done the following: initialize: function () { window.App ...

Adjust the size of the event bar on the FullCalendar resourceTimeline view

In my implementation of FullCalendar v6, I am displaying 6 months worth of data in the calendar, with each slot representing a one-month period. The issue I am facing is that when creating an event spanning 10 days, it currently takes up the entire width o ...

Is there a way to enclose an element with two other elements using JavaScript/jQuery

Is it possible to create a wrapping element for content located between two existing elements? Here's a code snippet to illustrate: <p> Some text some text <span class="foo">some more text</span> additional text. </p> <p> ...

Vue Project Encounters Issues with router-link and router-view in the Boilerplate Setup

After using the command vue create to set up a new Vue project with Babel, TypeScript, Router, and Unit Testing, I proceeded to install axios via npm. With no additional modifications made, I attempted to run the application by navigating to the src direc ...

Node.js frequently returns null with its url methods

I'm having some trouble getting node.js to display the HTTP request properties in the browser. I've tried printing the properties of the request URL, but they either show up as null or don't display at all. Below is the code for the server ( ...

The construction of the Gatsby site encountered a major obstacle

I've been facing challenges while trying to build my Gatsby site. Whenever I run 'gatsby develop' in the console, my app starts without any issues. However, when I attempt to build it, I encounter errors like the ones shown below. Does anyon ...

Ways to retrieve form information from a POST request

I received a POST request from my payment gateway with the following form data: Upon trying to fetch the data using the code snippet below, I encountered errors and gibberish content: this.http .post<any>('https://xyz.app/test', { ti ...

Combining array elements into sets of n

I am facing a challenge with an array manipulation task. let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]; My goal is to divide this array into a specified number of smaller arrays such that each new array contains the same number of elements ...

Determining the Width of a DIV Dynamically with CSS or LESS Depending on the Number of Siblings

One of my challenges involves a parent DIV with a width set to 100%. Dynamically, this parent DIV is filled with numerous children DIVs. I am trying to calculate and assign their widths using only the calc method in CSS or LESS. This is because the flex ...

How can a debounce function be customized to work on multiple instances of the same Vue.js component autonomously?

I am encountering an issue with two Vue components that each have a "save to disk" call triggered on every change of data. These components utilize a mixin to load the data, and they save into separate files in order to function independently (each trigger ...