0
votes

Been searching for a while for this issue, now I work to select all checkboxes:

1.- When the checkbox labeled as "Seleccionar Todos" is checked, must check all current checkboxes.

2.- If the checkbox "Seleccionar todos" is checked but user unchecks any checkbox aside of "Seleccionar todos", it must deactivate select all checkbx

Tickets.vue (This file creates the table I need, here is where I need help)

<template>
  <v-card class="elevation-5 pa-3">
    <div>
    <v-checkbox color="primary" @change="selectall()" :id="`todos`" :label="`Seleccionar Todo`" :checked="booleanValue" :val="'FALSE'" ref="todos"/>
    </div>
    <v-data-table
        ref="data_table"
        :headers="configuracion.configClientes.encabezados"
        expand
        rows-per-page-text="Filas por página"
        :rows-per-page-items="[10, 20, 55, { text: 'Todas', value: -1 }]"
        :no-results-text="'No se han encontrado tickets'"
        :item-key="configuracion.configClientes.itemKey"
        v-model="seleccion"
        :configuracion="configuracion.configClientes"
        :items="cat_clientes.catalogo"
    >
      <template slot="headerCell" slot-scope="props">
          <span>
            {{ props.header.text }}
          </span>
      </template>

      <template slot="items" slot-scope="props">
        <tr>
          <td
              v-for="columna in configuracion.configClientes.encabezados"
              v-if="columna.value !== '$acciones'"
              :key="keyUUID()"
          >
            {{ formatearColumna( props.item, columna ) }}

          </td>
          <td> 
            <v-checkbox :val="items.FOLIO" v-model="props.items" color="primary" @change="changeCheckbox(props.item.FOLIO)"/>
            </td>
        </tr>
      </template>

      <template slot="no-data">
        <v-alert :value="true" color="warning" icon="warning">
          {{ configuracion.mensajeVacia ? configuracion.mensajeVacia : 'No hay tickets' }}
        </v-alert>
      </template>
    </v-data-table>
  </v-card>
</template>

<script>
  import { mapActions, mapGetters } from 'vuex';
  /* mixins */
  import { mixins_generales } from "../Mixins/generales";
  import { formatos } from "../Mixins/formatos";

  export default {
    mixins: [mixins_generales, formatos],

    props: {
      configuracion: {
        type: Object,
        default: () => {
          return {
        configClientes: {
          seleccionable: true,
          itemKey: 'id',
          editable: true,
          eliminable: true,
          buscable: true,
          expandible: true,
          labelBusqueda: 'Buscar ticket',
          mensajeVacia: 'No hay tickets',
          encabezados: [
            {text: 'Folio', value: 'FOLIO', align: 'left'},
            {text: 'Fecha', value: 'FECHA', align: 'left'},
            {text: 'Hora', value: 'HORA', align: 'left'},
            {text: 'Sub-Total', value: 'SUBTOTAL', align: 'left'},
            {text: 'IVA', value: 'IVA', align: 'left'},
            {text: 'Total', value: 'TOTAL', align: 'left'},
            {text: 'Procesar', value: '$acciones', align: 'left'}
          ]
        },
        clienteSeleccionado: null,
      };
        }
      },
      items: {
        type: Array,
        default: () => []
      }
    },

    data() {

      return {
          checked:false,
        seleccion: [],
        todos:[],
        booleanValue:false
      };
    },
    computed: {
      ...mapGetters([
        'cat_clientes'
      ]),
    },
    methods: {
              ...mapActions([
        'LLENAR_CAT_CLIENTES',
        'AGREGAR_CAT_CLIENTE',
        'QUITAR_CAT_CLIENTE',
        'MARCAR_CAT_CLIENTES_CONSULTADO'
      ]),
          handleInput(e) {
      console.log("handleInput in App :: ", e);
      this.formattedValue = e;
    },
      onClick(props) {
        if (this.configuracion.expandible) {
          props.expanded = !props.expanded;
        }
      },

      onEditar(item) {
        this.$emit('editar', item);
      },

      onEliminar(item) {
        this.$emit("eliminar", item);
      },

      formatearColumna(item, encabezado) {
        if (item[encabezado.value]) {
          if (encabezado.formato) {
            if (encabezado.formato === 'moneda') {
              return this.formatearMoneda(item[encabezado.value]);
            }
          }

          return item[encabezado.value];
        }
        return 'N/A';
      },

      override_genPagination() {
        const that = this.$refs.data_table;
        that.genPagination = () => {
          let pagination = '–';

          if (that.itemsLength) {
            const stop = that.itemsLength < that.pageStop || that.pageStop < 0
              ? that.itemsLength
              : that.pageStop;

            pagination = that.$scopedSlots.pageText
              ? that.$scopedSlots.pageText({
                pageStart: that.pageStart + 1,
                pageStop: stop,
                itemsLength: that.itemsLength
              })
              : `${that.pageStart + 1}-${stop} de ${that.itemsLength}`;
          }

          return that.$createElement('div', {
            'class': 'datatable__actions__pagination'
          }, [pagination]);
        }
      },
            cargar() {
        this.MOSTRAR_LOADING('Obteniendo tickets');
        const url = this.g_url + '/php/catalogos/obtenertickets.php';

        this.$http.get(url)
          .then(response => {
            const respuesta = response.data;
            console.log('[Tickets](cargar)', response);

            if (!this.RespuestaSinErrores(respuesta, 'Ha ocurrido un error en el servidor al obtener los tickets')) {
              return;
            }

            // actualizar el state con el catálogo y mostrar al usuario
            this.MOSTRAR_SNACKBAR({texto: 'Tickets cargados', color: 'success', arriba: true, derecha: true});
            this.LLENAR_CAT_CLIENTES(respuesta.conceptos.catalogo);
            this.todos = respuesta.todos;
            this.MARCAR_CAT_CLIENTES_CONSULTADO();
          }, error => {
            this.MostrarErrorConexion(error);
          });
      },
 changeCheckbox(item)
 {
   let aux = 0;
   this.booleanValue = false;

   if(this.seleccion.length == 0)
   {
     //Array Vacio
     this.seleccion.push(item);
   }else{
     for(var i=0;i < this.seleccion.length;i++)
     {
       if(this.seleccion[i] == item)
       {
         //Existe en array
         this.seleccion.splice(this.seleccion.indexOf(item), 1);
         aux = 1;
         break;
       }
     }
     if(aux==0)
     {
       this.seleccion.push(item);
     }
   }
   console.log(this.seleccion);
 },
 toggleAll() {
  this.items.forEach((props, items) => {
    this.$set(this.props.items, "value", !this.selectDeselectAll);
  });
},
 toFol()
 {
   let istodos = document.getElementById("todos").checked;
   let fol = "";
   if(this.seleccion.length == 0 && istodos == false)
    {
      this.MOSTRAR_SNACKBAR({texto: 'No ha elegido tickets para facturar', color: 'error'});
      return false;
    }

    if(istodos == true)
    {
      return this.todos;
    }else{
      return this.seleccion;
    }
 }
    },//Fin metodos

    mounted() {
      this.override_genPagination();
    },
          created() {
      if (!this.cat_clientes.consultado) {
        this.cargar();
      }
    },
    watch: {
      seleccion(valor) {
        this.$emit('seleccion', valor);
      }
    }
  }
</script>

I am taking as example this url https://makitweb.com/check-uncheck-all-checkboxes-with-vue-js/ & @Robin ZecKa Ferrari answer with no luck (Since his example is quite different to my code needs but its a help)

EDIT: Current approach uses Robin ZecKa Ferrari answer but it only ticks Seleccionar todos but not ALL checkboxes

1

1 Answers

1
votes

Please next time try to share a smaller code with us, try to isolate your problem.

Here I use watch to trigger a function each time the value change on select/deselect all button.

Take a look also to this.$set, it's important to use it to keep data reactive. Do not mutate data directly like this.options[index].value = newValue. More information about Reactivity in Depth : https://vuejs.org/v2/guide/reactivity.html

View it on CodeSandBox: https://codesandbox.io/s/checkdeselect-all-bu0p4

<template>
  <div class="hello">
    <input type="checkbox" v-model="selectDeselectAll">Select/deselect All
    <ul>
      <li v-for="(option, index) in options" :key="'option'+index">
        <input type="checkbox" v-model="options[index].value">
        {{option.label}}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      selectDeselectAll: false,
      options: [
        { label: "option 1", value: false },
        { label: "option 2", value: false },
        { label: "option 3", value: false }
      ]
    };
  },
  watch: {
    selectDeselectAll: function(newValue) {
      this.options.forEach((option, index) =>
        // it's important to use $set to allow Reactivity in Depth
        // See: https://vuejs.org/v2/guide/reactivity.html
        this.$set(this.options[index], "value", newValue)
      );
    }
  }
};
</script>