Creando un sistema CRUD con Vue y Laravel 18/23

serie-crud-js

18- Trabajando con los select

En este post nos dedicaremos a resolver dos problemas que se nos presentan.

Primero que nada recordar que estamos trabajando con el alta del Empleado y que debemos elegir un cargo asociado a un departamento. Esto hace que tengamos que tener un select para cada cosa.

  • El primer problema es: Departamentos sin cargos.

Si el empleado debe elegir un cargo de un apartamento seria innecesario poner departamentos sin cargos.

Para hacer esto modificaremos levemente el queryController. Tenemos este código:

'departures' => Departure::all(),

y lo cambiaremos por:

'departures' => Departure::with('positions')->get(),

Con este cambio logramos que en el array de departures de la respuesta ajax se incluya la relación de cada departamentos con los cargos correspondientes, en otras palabras me devuelve todos los departamentos con sus respectivas posiciones.

Tenemos código en openmodal employee / create.

Solo modificaremos las siguientes lineas:

this.idFilterDeparture = 0;
this.filterDeparture = [];
this.idFilterPosition = 0;
this.filterPosition = [];

y las cambiaremos por

this.filterDeparture = [];
this.filterPosition = [];
let me = this;
this.departures.map(function (x) {
    if (x.positions.length) {
        if (me.filterDeparture.indexOf(x)) me.filterDeparture.push(x);
    }
});
if (this.filterDeparture.length) {
    this.idFilterDeparture = this.filterDeparture[0].id;
    this.filterPosition = this.filterDeparture[0].positions;
    this.idFilterPosition = this.filterDeparture[0].positions[0].id;
} else {
    this.idFilterDeparture = 0;
    this.idFilterPosition = 0;
    this.filterPosition = [];
}

Las 3 primeras lineas son sencillas. Miremos las siguientes

this.departures.map(function (x) {
    if (x.positions.length) {
        if (me.filterDeparture.indexOf(x)) me.filterDeparture.push(x);
    }
});

Con Map recorremos los elementos del array uno a uno. Este  elemento es el x en el parámetro de la función.

Lo siguiente es comprobar si el array de positions asociado tiene elementos (un departamento sin cargos tendrá un array vacío)

Si lo tiene pasamos a la siguiente linea que hacemos dos cosas

if (me.filterDeparture.indexOf(x)) me.filterDeparture.push(x);

Primero comprobamos que el array no tenga ya el valor y si no lo tiene lo agregamos al array del select

if (this.filterDeparture.length) {
    this.idFilterDeparture = this.filterDeparture[0].id;
    this.filterPosition = this.filterDeparture[0].positions;
    this.idFilterPosition = this.filterDeparture[0].positions[0].id;
}

En este if comprobamos que después del filtro halla por lo menos un departamento elegido. De ser así hacemos 3 cosas.

  • Elegimos el primer id para que el select tenga ese valor seleccionado.
  • El siguiente select lo rellenamos con los cargos del primer departamento
  • Por ultimo elegimos por defecto el primer cargo del select de cargos.

Ahora tenemos los departamentos que tienen cargos y los cargos del primer departamento elegidos.

  • Segundo problema que debemos solucionar es rellenar los cargos correspondientes a los departamentos cuando el select cambie.

Aqui volveremos a una característica de Vue que vimos antes: watch.

Con watch estaremos atentos a los cambios del select a traves de la variable idFilterDeparture. El watch actual esta asi

watch: {
    modalGeneral: function (value) {
        if (!value) this.allQuery();
    }
},

Y lo cambiaremos a

watch: {
    modalGeneral: function (value) {
        if (!value) this.allQuery();
    },
    idFilterDeparture: function (value) {
        let me = this;
        this.filterDeparture.map(function (x) {
            if (x.id === value) {
                me.filterPosition = x.positions;
                me.idFilterPosition = me.filterPosition[0].id;
            }
        });
    }
},

Miremos el código nuevo. Cuando idFilterDeparture cambie de valor la función recibirá el valor en value.

Ese es el valor del id elegido así que hacemos un map del array y buscamos la coincidencia. Cuando la encontramos actualizamos el array filterPosition con el array de los cargos relacionado del departamento elegido y  actualizamos el valor de idFilterPosition para que quede elegido el primer valor del select.

Con esto ya hemos cumplido la mision del post de forma rapida y sencilla. No me canso en insistir en que no es necesario tocar el DOM ni los elementos HTML para obtener el resultado buscado.

Código:  Github

Proximo Post: Validaciones. Mensajes de error del back.

Comparte este artículo

Entra en la discusión y deja tu comentario

Veces