Group information with Vue

Asked

Viewed 180 times

-1

Hello! I’m studying And at the same time trying to apply what I’m learning in a project.

A difficulty has arisen. I have a list of checkboxes with the brands of the vehicles, when I click will load the models of the selected brands, and I wish that when loading the models come the brand name first and below the models.

Ex:

Chevrolet

  • Onix
  • Cousin

FORD

  • Goal
  • Golf
<template>
  <div>  
    <div v-show="marcas.length">
      <h5>Marcas de interesse</h5>
      <hr>
      <div class="form-group form-check">
        <div v-for="m in marcas">
          <input name="cliente_interessado[marca][]" class="form-check-input" type="checkbox" :value="m.id" v-on:click="clickMarca(m.id)" >
          <label class="form-check-label">{{ m.nome }}</label>
        </div>
      </div>      
    </div>

    <div v-if="loading">Carregando...</div>        

    <div v-show="modelos.length">
      <br>
      <h5 >Modelos de interesse</h5>
      <hr>
      <div class="form-group form-check">
        <div v-for="m in modelos">          
          <input name="cliente_interessado[modelo][]" class="form-check-input" type="checkbox" :value="m.id" >
          <label class="form-check-label">{{ m.marca }} - {{ m.nome }}</label>
        </div>
      </div>      
    </div>
  </div>
</template>

<script>  
  import axios from 'axios';

  export default {      
    data() {          
      return {        
        marcas: [],
        modelos: [],        
        checkedNames: [],
        loading: false,
      }      
    },    
    created() {          
      axios.get('/api/marcas').then(response => (this.marcas = response.data.data))
    },
    methods: {
      clickMarca(value) {       
        if (this.checkedNames.find(item => item === value)) {
          var pos = this.checkedNames.indexOf(value);
          this.checkedNames.splice(pos, 1);
        } else {
          this.checkedNames.push(value)
        }

        this.loading = true

        axios.get('/api/modelos/' + "[" + this.checkedNames.toString() + "]")
          .then(response => (this.modelos = response.data.data))
          .finally(() => this.loading = false)        
      }     
    }
  }
</script>

Como está hoje

  • cannot create the templates inside the tags object?

1 answer

1


Hello you can create an array tags_templates, initially with the tag_id and empty templates.

...
    {
       "marca_id" : 1,
       "modelos" : []
    },
...

By clicking on the brand you search your api for templates and apply to templates. And do a v-for on the models below the brand. Below is the suggested code and a link to jsfiddle.

Note that I simulated the return of your api with arrays, it may return different values, so you will have to adapt the code according to your api.

Example running on jsfiffle

Imagem do resultado

<template>
    <div>
      <div v-if="loading">Carregando...</div>
      <div v-show="marcas.length">
        <h5>Marcas de interesse</h5>
        <hr>
        <ul class="form-group form-check">
          <li v-for="m in marcas">
            <input :id="'marcaId' + m.id" name="cliente_interessado[marca][]" class="form-check-input" type="checkbox" :value="m.id" v-on:change="clickMarca(m.id, $event)">
            <label :for="'marcaId' + m.id" class="form-check-label">{{ m.nome }}</label>
            <div v-if="loading">Carregando...</div>
            <ul class="form-group form-check">
              <li v-for="md in marcasModelo(m.id)">
                <input :id="'modeloId' + md.id" name="cliente_interessado[modelo][]" class="form-check-input" type="checkbox" :value="md.id">
                <label :for="'modeloId' + md.id" class="form-check-label">{{ md.nome }}</label>
              </li>
            </ul>
          </li>
        </ul>
      </div>
    </div>
  </template>


<script>
import axios from "axios";

export default {
  data() {
    return {
      marcas: [],
      marcas_modelos: [],
      loading: false
    };
  },
  created() {
    this.loadMarcas();
  },
  methods: {
    loadMarcas() {
      //axios.get('/api/marcas').then(response => (this.marcas = response.data.data))
      //Simulando a chamada de marcas, aqui sua api devolverá as marcas e atribuirá a this.marcas...
      this.marcas = [
        {
          id: 1,
          nome: "CHEVROLET"
        },
        {
          id: 2,
          nome: "FIAT"
        }
      ];
      let self = this;
      this.marcas.forEach(function(value) {
        self.marcas_modelos.push({
          marca_id: value.id,
          modelos: []
        });
      });
    },
    loadModelos(marca_id) {
      //this.loading = true
      //axios.get('/api/modelos/' + "[" + this.checkedNames.toString() + "]")
      //.then(response => (this.modelos = response.data.data))
      //.finally(() => this.loading = false)
      //Simulando a chamada de modelos, aqui sua api deverá devolver os modelos conforme a marca_id...
      let modelos = [
        {
          id: 1,
          marca_id: 1,
          nome: "PRISMA"
        },
        {
          id: 2,
          marca_id: 1,
          nome: "ONIX"
        },
        {
          id: 3,
          marca_id: 2,
          nome: "SIENA"
        },
        {
          id: 4,
          marca_id: 2,
          nome: "PALIO"
        }
      ];
      // esse filter provavelmente não será necessário, sua api irá devolver somente o que você precisar.
      return modelos.filter(function(modelo) {
        return modelo.marca_id == marca_id;
      });
    },
    clickMarca(value, event) {
      let isCheched = event.target.checked;
      let modelos = [];
      if (isCheched) {
        modelos = this.loadModelos(value);
      }
      let marcaIndex = this.marcas_modelos.findIndex(x => x.marca_id == value);
      this.marcas_modelos[marcaIndex].modelos = modelos;
    },
    marcasModelo(marca_id) {
      let marcaIndex = this.marcas_modelos.findIndex(
        x => x.marca_id == marca_id
      );
      if (this.marcas_modelos[marcaIndex])
        return this.marcas_modelos[marcaIndex].modelos;
      return [];
    }
  }
};
</script>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.