Dynamic dependent dropdowns getting data from JSON in Vue.js3

Viewed 135

I have this scenario: I have to make 4 dropdown boxes in Vuejs with data coming from a JSON. The first 2 dropdown boxes are for selecting among a list of teams in a championship to compete against each other, and then there are 2 other following dropdown select boxes: one to select one of the two teams previously chosen in dropdown boxes 1 and 2, and the last one to choose one of the players of the team chosen in the select box number 3, which means the dropdown box number 4 is dependent on dropdown box number 3, and dropdown box number 3 is dependent on dropdown boxes 1 and 2.

To identify which players belong to which team, I'm using a team ID, which matches the team, much like a SQL foreign key, instead of making a players list inside each team list. The json basically looks like this:

data.json

{
  "teams": [
    {
      "id": 1,
      "name": "Team 1",
      "city": "Los Angeles",
    },
    {
      "id": 2,
      "name": "Team 2",
      "city": "Brussels",
    },
    {
      "id": 3,
      "name": "Team 3",
      "city": "London",
    }
  ],
  "players": [
    {
      "id": 1,
      "name": "John",
      "team_id": "3"
    },
    {
      "id": 2,
      "name": "Larry",
      "team_id": "3"
    },
    {
      "id": 3,
      "name": "Peter",
      "team_id": "1"
    },
    {
      "id": 4,
      "name": "Matt",
      "team_id": "2"
    }
  ],
}

Also, this JSON isn't static, as there's a whole CRUD application that inserts, edits and deletes teams and players.

My problem is that I can't figure out how can I make these dependent select boxes. So far, I think I managed to extract the teams' names list for the first 2 selects, but I don't know how can I make the 3rd select with only the 2 previously selected as its options, neither the 4th select boxes with the players of the team selected in select box 3.

Here's what I have so far:

<template>
  <h3>Matches</h3>

  <label class="form-label">House Team:</label>
  <select class="form-control">
    <option v-for="(team, index) in teams" :key="index">
      {{ team.name }}
    </option>
  </select>
  <label class="form-label">Visitor Team:</label>
  <select class="form-control">
    <option v-for="(team, index) in teams" :key="index">
      {{ team.name }}
    </option>
  </select>


  <h4>Points</h4>


   <div class="row">
    <div class="column">
      <div>Team</div>
      <select v-model="point.team">
        <option v-for="team in teams" :key="team">
          {{ team.name }}
        </option>
      </select>
    </div>
  </div>
  <div class="row">
    <div class="column">
      <div>Player</div>
      <select v-model="point.player">
        <option 
          v-for="player in filtered_team" 
          :key="player"
        >
          {{ player.name }}
        </option>
      </select>
    </div>
  </div>

  <button @click="savePoint" type="button" class="btn btn-primary">Score Point</button>

</template>

<script>
import json from '../fakeAPI/data.json'
import axios from "axios";

let newTeam = (max) => {
  let max_id = max || 0
  return{
        'id': max_id + 1,
        'name': "",
        'city': "",
      }
}

let newPlayer = (team_id,max) => {
  let max_id = max || 0
  return{
        'id': max_id + 1,
        'name': "",
        'team_id': team_id,
      }
}

let scorePoint = (max) => {
  let max_id = max || 0
  return{
        'id': max_id + 1,
        'team': "",
        'player': "",
      }
}

const URL_points = 'http://localhost:3000/points';
const URL_teams = 'http://localhost:3000/teams';
const URL_players = 'http://localhost:3000/players';

export default {
  name: 'Matches',
  components: {
    },
  data(){
    return{
      point: scorePoint(),
      matches: [],
      points: [],
      teams: [],
      players: [],
      team: '',
      player: '',
      listTeams: json.teams,
    }
  },
  computed: {
      filtered_team(){
          return this.players.filter(p => p.team_id === this.team.id)
      }
  },
  mounted() {
    axios.get(URL_points).then(({data}) => {
      this.points = data
      this.point = scorePoint(Math.max(...this.points.map(p => p.id)))
    })
    axios.get(URL_teams).then(({data}) => {
      this.teams = data
      this.team = newTeam(Math.max(...this.teams.map(t => t.id)))
    })
    axios.get(URL_players).then(({data}) => {
      this.players = data
      this.player = newPlayer({params: {team_id: this.team.id}}, Math.max(...this.players.map(x => x.id)));
    })

  }
}
</script>
1 Answers

you have to bind model box 1 and 2, then give a change event on box 3 where the event will call api with parameter values box 1 and 2

Related