6 abril, 2025
Select dinámicos en Laravel solo con JS
Para implementar select dependientes en Laravel necesitamos tres modelos, la API nativa Fetch de Javascript para realizar la peticiones mediante promesas.

Suscríbete a nuestro canal en Youtube
Suscríbirse¿Cómo implementar select dependientes en Laravel?
En este caso programaremos un ejemplo de Selects dependientes de tres niveles con la API Fetch de JS y Laravel. Para ello, antes se usaba comunmente Jquery, hoy en dia contamos con una solución nativa que requiere de menos líneas de código y la mayoría de navegadores modernos ya lo soportan. Entonces:
- Solo usaremos Javascript donde vamos a consumir la API Fetch para inflar los select dinámicamente.
- El framework Laravel - PHP para el desarrollo de aplicaciones web
- HTML y CSS para maquetar es decir aplicar diseño a la vista.
Estructura de la Base de Datos
Asumiremos que tienes las tablas:
categories
(id, name)subcategories
(id, category_id, name)products
(id, subcategory_id, name)
Modelos y Relaciones
Define las relaciones en los modelos:
php
// Category.php
public function subcategories() {
return $this->hasMany(Subcategory::class);
}
// Subcategory.php
public function category() {
return $this->belongsTo(Category::class);
}
public function products() {
return $this->hasMany(Product::class);
}
// Product.php
public function subcategory() {
return $this->belongsTo(Subcategory::class);
}
Rutas (routes/web.php)
Crea rutas: web y para las peticiones AJAX:
php
Route::get('categories', [FrontController::class,'getCategories']);
Route::get('/subcategories/{category}', [FrontController::class, 'getSubcategories']);
Route::get('/products/{subcategory}', [FrontController::class, 'getProducts']);
Controladores
Crea los métodos para devolver datos en formato JSON:
php
public function getCategories(){
$categories = Category::all();
return view('categoria', compact("categories"));
}
public function getSubcategories(Category $category){
return response()->json($category->subcategories);
}
public function getProducts(Subcategory $subcategory) {
return response()->json($subcategory->products);
}
Vista Blade (HTML + JavaScript)
Crea el formulario con selects dependientes:
blade
<h1 class="text-3xl underline p-5 text-center">SELECT DEPENDIENTES</h1>
<div class="flex justify-center">
<div class="grid grid-cols-3 w-3/4 gap-10">
<select id="category" class="border rounded-lg p-2">
<option value="">Selecciona una categoría</option>
@foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
@endforeach
</select>
<select id="subcategory" class="border rounded-lg p-2" disabled>
<option value="">Selecciona una subcategoría</option>
</select>
<select id="product" class="border rounded-lg p-2" disabled>
<option value="">Selecciona un producto</option>
</select>
</div>
</div>
JavaScript (Vanilla JS)
Agrega el script para manejar las dependencias:
javascript
document.getElementById('category').addEventListener('change', function() {
const categoryId = this.value;
const subcategorySelect = document.getElementById('subcategory');
const productSelect = document.getElementById('product');
// Resetear selects
subcategorySelect.innerHTML = '<option value="">Selecciona una subcategoría</option>';
subcategorySelect.disabled = true;
productSelect.innerHTML = '<option value="">Selecciona un producto</option>';
productSelect.disabled = true;
if (categoryId) {
// Cargar subcategorías
fetch(`/subcategories/${categoryId}`)
.then(response => response.json())
.then(data => {
subcategorySelect.innerHTML = data.map(item =>
`<option value="${item.id}">${item.name}</option>`
).join('');
subcategorySelect.disabled = false;
});
}
})
document.getElementById('subcategory').addEventListener('change', function() {
const subcategoryId = this.value;
const productSelect = document.getElementById('product');
// Resetear productos
productSelect.innerHTML = '<option value="">Selecciona un producto</option>';
productSelect.disabled = true;
if (subcategoryId) {
// Cargar productos
fetch(`/products/${subcategoryId}`)
.then(response => response.json())
.then(data => {
productSelect.innerHTML = data.map(item =>
`<option value="${item.id}">${item.name}</option>`
).join('');
productSelect.disabled = false;
});
}
});document.getElementById('category').addEventListener('change', function() {
const categoryId = this.value;
const subcategorySelect = document.getElementById('subcategory');
const productSelect = document.getElementById('product');
// Resetear selects
subcategorySelect.innerHTML = '<option value="">Selecciona una subcategoría</option>';
subcategorySelect.disabled = true;
productSelect.innerHTML = '<option value="">Selecciona un producto</option>';
productSelect.disabled = true;
if (categoryId) {
// Cargar subcategorías
fetch(`/subcategories/${categoryId}`)
.then(response => response.json())
.then(data => {
subcategorySelect.innerHTML = data.map(item =>
`<option value="${item.id}">${item.name}</option>`
).join('');
subcategorySelect.disabled = false;
});
}
})
document.getElementById('subcategory').addEventListener('change', function() {
const subcategoryId = this.value;
const productSelect = document.getElementById('product');
// Resetear productos
productSelect.innerHTML = '<option value="">Selecciona un producto</option>';
productSelect.disabled = true;
if (subcategoryId) {
// Cargar productos
fetch(`/products/${subcategoryId}`)
.then(response => response.json())
.then(data => {
productSelect.innerHTML = data.map(item =>
`<option value="${item.id}">${item.name}</option>`
).join('');
productSelect.disabled = false;
});
}
});document.getElementById('category').addEventListener('change', function() {
const categoryId = this.value;
const subcategorySelect = document.getElementById('subcategory');
const productSelect = document.getElementById('product');
// Resetear selects
subcategorySelect.innerHTML = '<option value="">Selecciona una subcategoría</option>';
subcategorySelect.disabled = true;
productSelect.innerHTML = '<option value="">Selecciona un producto</option>';
productSelect.disabled = true;
if (categoryId) {
// Cargar subcategorías
fetch(`/subcategories/${categoryId}`)
.then(response => response.json())
.then(data => {
subcategorySelect.innerHTML = data.map(item =>
`<option value="${item.id}">${item.name}</option>`
).join('');
subcategorySelect.disabled = false;
});
}
})
document.getElementById('subcategory').addEventListener('change', function() {
const subcategoryId = this.value;
const productSelect = document.getElementById('product');
// Resetear productos
productSelect.innerHTML = '<option value="">Selecciona un producto</option>';
productSelect.disabled = true;
if (subcategoryId) {
// Cargar productos
fetch(`/products/${subcategoryId}`)
.then(response => response.json())
.then(data => {
productSelect.innerHTML = data.map(item =>
`<option value="${item.id}">${item.name}</option>`
).join('');
productSelect.disabled = false;
});
}
});
¿Cómo funciona?
- Al seleccionar una categoría , se hace una petición GET a
/subcategories/{category}
para obtener las subcategorías asociadas. - Al seleccionar una subcategoría , se hace una petición GET a
/products/{subcategory}
para obtener los productos. - Los selects se habilitan/deshabilitan según la selección anterior.
Leido 17776 veces | 10 usuarios
Descarga del código fuente Laravel de Select dinámicos en Laravel solo con JS
Accede al código fuente esencial de nuestra aplicación en formato ZIP ó TXT. Ideal para desarrolladores que desean personalizar o integrar nuestra solución.
Opciones de descarga
- Usuarios Registrados: Inicia sesión para descarga inmediata.
- Nuevos Usuarios: Regístrate y descarga.
Cuestionario de 15 preguntas sobre la implementación de selects dependientes en Laravel
Aquí tienes un cuestionario de 15 preguntas en formato JSON basado en el contenido proporcionado sobre la implementación de selects dependientes en Laravel :