0

I have 2 v-select dropdown(Countries and States) that get filled in with data from database. For example, I'm trying to select a Country(CANADA) from the 1st v-select dropdown and I want the second v-select to show only CANADA states. I'm using VUEX STORE to fetch data from my Laravel backend API.

// VUEX STORE
import Axios from "axios";

export default {
namespaced: true,

//*******STATE*******//
state: {
   countries: [],
   states: []
},

//*********MUTATIONS**********//
SET_COUNTRIES(state, countries) {
  state.countries = countries;
},

SET_STATE(state, states) {
  state.states = states;
}
//********ACTIONS******//
actions: {
  async loadCountries({ commit }) {
    let response = await Axios.get("/dashboard/countries");
    let countries = response.data;
    countries.forEach(c => {
      c.state_ids = c.states.map(p => p.id);
    });
    console.log(response.data);
    commit("SET_COUNTRIES", countries);
  },

  async loadStates({ commit }) {
    let response = await Axios.get("/dashboard/states");
    let states = response.data;
    console.log(response.data);
    commit("SET_STATE", states);
  }
 }
};
 // CountryState.vue
<v-row>
      <v-col cols="4">
        <v-select
          v-model="selectedCountry"
          :items="countries"
          item-value="name"
          item-text="name"
          :label="$t('GENERAL.FORM.COUNTRY')"
          single-line
          return-object
        >
        </v-select>
      </v-col>
      <v-col cols="4">
        <v-select
          v-model="selectedState"
          :items="states"
          item-value="name"
          item-text="name"
          :label="$t('GENERAL.FORM.STATE')"
          single-line
          return-object
        >
        </v-select>
      </v-col>
      <v-col cols="4">
      <p>The selected Item is: {{ selectedCountry.name }}</p>
      <p>The selected Item is: {{ selectedState.name }}</p>
    </v-row>
<script>
import { mapState } from "vuex";

export default {
  data() {
    return {
      selectedCountry: [],
      selectedState: "",
      showScheduleForm: false
    };
  },

  computed: {
    ...mapState({
      countries: state => state.allCountries.countries,
      states: state => state.allCountries.states
    })
  },

  mounted() {
    this.$store.dispatch("allCountries/loadCountries");
    this.$store.dispatch("allCountries/loadStates");
  }
};
</script>

Country Data in state look like this

{"id":1,"name":"Canada","short_code":"CA","states":[{"id":7,"name":"Ontario","country_id":1},{"id":8,"name":"Minnetoba","country_id":1},{"id":9,"name":"Columbia","country_id":1}],"state_ids":[7,8,9]}

States Data in state look like this

{"id":7,"name":"Ontario","country_id":1,"country":{"id":1,"name":"Canada","short_code":"CA"}}

1 Answer 1

2

You could trigger a function to filter states onChange. Your v-select then displays a list of states depending on the selected country.

Step 1: add filter method

  methods: {
    filterStates(country) {
      this.selectedState = "";
      this.filteredStates = this.states.filter(state => state.country_id === country.id);
    }
  },

Step 2: trigger onChange of country

@change="filterStates"

Step 3: display filtered states

 :items="filteredStates"

Putting it together

<v-row>
      <v-col cols="4">
        <v-select
          v-model="selectedCountry"
          :items="countries"
          item-value="name"
          item-text="name"
          :label="$t('GENERAL.FORM.COUNTRY')"
          single-line
          return-object
          @change="filterStates"
        >
        </v-select>
      </v-col>
      <v-col cols="4">
        <v-select
          v-model="selectedState"
          :items="filteredStates"
          item-value="name"
          item-text="name"
          :label="$t('GENERAL.FORM.STATE')"
          single-line
          return-object
        >
        </v-select>
      </v-col>
      <v-col cols="4">
      <p>The selected Item is: {{ selectedCountry.name }}</p>
      <p>The selected Item is: {{ selectedState.name }}</p>
    </v-row>
<script>
import { mapState } from "vuex";

export default {
  data() {
    return {
      selectedCountry: [],
      selectedState: "",
      showScheduleForm: false,
      filteredStates: []
    };
  },

  computed: {
    ...mapState({
      countries: state => state.allCountries.countries,
      states: state => state.allCountries.states
    })
  },
  methods: {
    filterStates(country) {
      this.selectedState = "";
      this.filteredStates = this.states.filter(state => state.country_id === country.id);
    }
  },
  mounted() {
    this.$store.dispatch("allCountries/loadCountries");
    this.$store.dispatch("allCountries/loadStates");
  }
};
</script>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.