简体   繁体   中英

How to make a <select> tag in html only shows some data depending on another <select> tag using Vue.js

I'm displaying two <select> elements. The second <select> is disabled depending on the <option> selected on the first <select> . The problem is when I select an <option> on the first <select> , I want the data shown on the second <select> to be changed. For example, if I select District 1 on the first <select> , I want to see john and mary as options in the second <select> , but if I select District 2 , I want josef and charles . Consider that I'm doing this on Laravel and using Vue.

I have done the first part using Vue, disabling the second <select> depending on what has been chosen on the first <select> (only third option on the first <select> will enable the second <select> ):

https://jsfiddle.net/vowexafm/122/

Template:

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<div id="app">
  <select @change="treat">
    <option value="District1">District 1</option><!--disable 2nd select-->
    <option value="District2">District 2</option><!--disable 2nd select-->
    <option value="District3">District 3</option><!--enable 2nd select-->
  </select>
  <br><br>
  <select :disabled="isDisabled">
    <option>cds 1</option>
    <option>cds 2</option>
    <option>cds 3</option>
  </select>
</div>

Script:

new Vue({
  el:'#app',
  data: {
    isDisabled: true,
  },
  methods: {
    treat: function(e) {
      if (e.target.options.selectedIndex == 0 || 
          e.target.options.selectedIndex == 1) {
        return this.disable();
      }

      if (e.target.options.selectedIndex != 0 && 
          e.target.options.selectedIndex != 1) {
        return this.enable();
      }
    },
    enable: function() {
      return this.isDisabled = false; // enables second select
    },
    disable: function() {
      return this.isDisabled = true; // disables second select
    }
  },
});

Now the solution I want,for example: if i'I select District 1 on the first , I want to see john and mary as options in the second , but if I select District 2, I want to see josef and charles on the second .

Populate data object from laravel to have the options for the second select in it and a value for the current selected index from the first select

data: {
  secondSelect: [
    ['john', 'mary'],
    ['josef', 'charles']
  ],
  currentIndex: 0
}

Define a computed property that returns the values for the second select depending on currentIndex

computed: {
  persons () {
    return this.secondSelect[parseInt(this.currentIndex)]
  }
}

Generate the second select using the computed property persons and use v-model to capture currentIndex .

<div id="app">
 <select @change="treat" v-model="selectedIndex">
  <option value="0">District 1</option><!--diable-->
  <option value="1">District 2</option><!--diable-->
  <option value="2">District 3</option><!--unable-->
 </select>
 <br><br>
 <select :disabled="isDisabled">
  <option v-for="option in persons" :value="option">{{option}}</option>
 </select>
</div>

now the solution I want,for example if i select 'District 1 'on the first i want to see 'john' and 'mary' as options in the second , but if I select 'District 2' i want to see 'josef' and 'charles' on the second .

is that whats in your mind?

 new Vue({ el:'#app', data:{ district:'-1', options:{ 'District1':false, 'District2':false, 'District3':false }, }, methods:{ getOptions(){ axios.get('https://jsonplaceholder.typicode.com/users',{district:this.district}).then(res=> this.options[this.district]=res.data) } } }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <div id="app"> <select v-model="district" @change="getOptions()"> <option value="-1" selected disabled hidden>choose a district</option> <option value="District1">District 1</option> <option value="District2">District 2</option> <option value="District3">District 3</option> </select> <br><br> <select v-if="options[district]"> <option v-for="option in options[district]">{{option.name}}</option> </select> </div> 

edit:

after your comment, i edited this answer so now its fetching the data from some api.

to fetch the options from a db, you first have to create an api for your app, and when the request comes out of your vue client side - the server will retrieve rows from the db, do some caculations based on the parameters you sent in the request, and bring back a json data array.

(i wont cover the server side now - thats completely off-topic. but you can easily google for 'laravel json response')

in this snippet, i used some example json api, just to show you how its done on the client side:

i use v-if to cause late- rendering of the second select. it will be rendered only after i get the options, via axios (a very common npm package used to make ajax requests in modern js frameworks).

im also registering an event listener to the change event of the first select - to make my ajax request and populate my options every time the disrict changes (i used a default option to avoid unneeded requests)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM