Tengo una vista en laravel que contiene una datatable que muestra el listado de empleados que tengo en la BD. Hasta aqui funciona todo bien.
En dicha vista tengo añadido un boton que abre un modal para insertar nuevos empleados. La clave del asunto es que ese modal (que contiene dentro una vista parcial con los campos del formulario) tiene dos selects dinamicos que se pueblan mediante peticiones ajax. La cosa es que si comento tanto a los selects como a las peticiones, todo funciona perfectamente, se me muestra la tabla con sus datos y al darle al boton se muestra el modal correctamente. Pero si los descomento, no se muestra nada de la tabla, aunque el modal si que funciona bien. Encima la consola no muestra ningun error, lo que si que no muestra que haya recibido la respuesta a la peticion para rellenar la tabla. Dejo a continuacion codigos y capturas para que se entienda mejor:
Index.blade.php
@extends('adminlte::page')
@section('title', 'Empleados')
@section('content_header')
<a class="btn btn-success btn-sm float-right" data-toggle="modal" data-target="#miModal" title="Añadir empleado">
<i class="fas fa-user-plus"></i>
</a>
<h1>Lista de empleados</h1>
@stop
@section('content')
@if (session('info'))
<div class="alert alert-success">
{{ session('info') }}
</div>
@endif
<div class="card">
<div class="card-body">
<table class="table table-striped table-hover empleado">
<thead>
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Apellidos</th>
<th>DNI/NIE</th>
<th>Direccion</th>
<th>Ciudad</th>
<th>Código postal</th>
<th>Foto</th>
<th>Situación</th>
<th>Acciones</th>
<th>Ver</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="modal fade" id="miModal" tabindex="-1" role="dialog" aria-labelledby="smallModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-success">
<h3 class="modal-title">Añadir empleado</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="smallBody">
<div>
<div class="card">
<div class="card-body">
{!! Form::open(['route' => 'admin.empleados.store']) !!}
@include('admin.empleados.partials.form')
{!! Form::submit('Añadir empleado', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="smallModal" tabindex="-1" role="dialog" aria-labelledby="smallModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header bg-primary">
<h3 class="modal-title">Fotografía actual</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="smallBody">
<div>
<!-- the result to be displayed apply here -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
@stop
@section('css')
@section('css')
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/dataTables.bootstrap5.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.4.1/css/responsive.dataTables.min.css">
@stop
@section('js')
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/dataTables.bootstrap5.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.4.1/js/dataTables.responsive.min.js"></script>
<script>
$(document).on('click', '#smallButton', function(event) {
event.preventDefault();
let href = $(this).attr('data-attr');
$.ajax({
url: href,
beforeSend: function() {
$('#loader').show();
},
// return the result
success: function(result) {
console.log(result);
$('#smallModal').modal("show");
$('#smallBody').html(result).show();
},
complete: function() {
$('#loader').hide();
},
error: function(jqXHR, testStatus, error) {
console.log(error);
alert("Page " + href + " cannot open. Error:" + error);
$('#loader').hide();
},
timeout: 8000
})
});
$(function () {
var table = $('.empleado').DataTable({
responsive: true,
autoWidth: false,
processing: true,
serverSide: true,
"language": {
"lengthMenu": "Ver _MENU_ registros por página",
"zeroRecords": "No se encuentra ningún registro",
"info": "Mostrando página _PAGE_ de _PAGES_",
"infoEmpty": "No existen registros disponibles",
"infoFiltered": "(filtrado de _MAX_ registros totales)",
'search': "Buscar:",
'paginate' : {
'next': "Siguiente",
'previous': "Anterior"
}
},
ajax: "{{ route('empleado.list') }}",
columns: [
{data: 'id', name: 'id'},
{data: 'nombre', name: 'nombre'},
{data: 'apellidos', name: 'apellidos'},
{data: 'dni', name: 'dni'},
{data: 'direccion', name: 'direccion'},
{data: 'ciudadNombre', name: 'ciudadNombre'},
{data: 'codigoPostal', name: 'codigoPostal', className: 'text-center'},
{
data: 'cara_id',
name: 'cara_id',
render: function (data, type, row) {
if (row.cara_id > 0) {
return '<span class="badge badge-success">Si</span>';
} else {
return '<span class="badge badge-danger">No</span>';
}
},
className: 'text-center'
},
{
data: 'tipo',
name: 'tipo',
render: function (data, type, row) {
if (row.tipo == "Alta") {
return '<span class="badge badge-success">Alta</span>';
} else if (row.tipo == "Baja") {
return '<span class="badge badge-danger">Baja</span>';
} else if (row.tipo == "Vacaciones") {
return '<span class="badge badge-info">Vacaciones</span>';
} else if (row.tipo == "Permiso") {
return '<span class="badge badge-warning">Permiso</span>';
}
},
className: 'text-center'
},
{
data: 'action',
name: 'action',
orderable: true,
searchable: true,
className: 'text-center'
},
{
data: null,
name: 'foto',
render: function (data, type, row) {
return '<a class="text-success" disabled title="Fotografía"><i class="fas fa-camera"></i></a>'
},
className: 'text-center'
}
]
});
});
</script>
@stop
form.blade.php
{{-- Esta es la vista parcial -- }}
<div class="form-group">
{!! Form::label('nombre', 'Nombre') !!}
{!! Form::text('nombre', null, ['class' =>'form-control', 'placeholder' => 'Introduzca el nombre del empleado']) !!}
@error('nombre')
<small class="text-danger">
{{ $message }}
</small>
@enderror
</div>
<div class="form-group">
{!! Form::label('apellidos', 'Apellidos') !!}
{!! Form::text('apellidos', null, ['class' =>'form-control', 'placeholder' => 'Introduzca los apellidos del
empleado']) !!}
@error('apellidos')
<small class="text-danger">
{{ $message }}
</small>
@enderror
</div>
<div class="form-group">
{!! Form::label('dni', 'DNI') !!}
{!! Form::text('dni', null, ['class' =>'form-control', 'placeholder' => 'Introduzca el DNI/NIE del empleado']) !!}
@error('dni')
<small class="text-danger">
{{ $message }}
</small>
@enderror
</div>
<div class="form-group">
{!! Form::label('fecha', 'Fecha de nacimiento') !!}
{!! Form::date('fecha', null, ['class' =>'form-control']) !!}
@error('fecha')
<small class="text-danger">
{{ $message }}
</small>
@enderror
</div>
<div class="form-group">
{!! Form::label('direccion', 'Dirección') !!}
{!! Form::text('direccion', null, ['class' =>'form-control', 'placeholder' => 'Introduzca la dirección del
empleado']) !!}
@error('direccion')
<small class="text-danger">
{{ $message }}
</small>
@enderror
</div>
<div class="form-group">
{!! Form::label('codigoPostal', 'Código Postal') !!}
{!! Form::number('codigoPostal', null, ['class' =>'form-control']) !!}
@error('codigoPostal')
<small class="text-danger">
{{ $message }}
</small>
@enderror
</div>
<div class="form-group">
<label for="provincia">Provincia:</label>
<select class="form-control" id="provincia" name="provincia">
<option value="">Seleccione una ciudad</option>
</select>
</div>
<div class="form-group">
<label for="ciudad">Ciudad:</label>
<select class="form-control" id="ciudad" name="ciudad">
<option value="">Seleccione una ciudad</option>
</select>
</div>
@section('js')
<script>
document.querySelector('select[name=provincia]').onchange = function () {
fetch(`/provincia/${this.value}/ciudades`)
.then(response => response.json())
.then(ciudades => {
let ciudadSelect = document.querySelector('select[name=ciudad]');
ciudadSelect.innerHTML = '';
ciudades.forEach(ciudad => {
let option = document.createElement('option');
option.value = ciudad.id;
option.text = ciudad.nombre;
ciudadSelect.add(option);
});
});
};
$(document).ready(function() {
$.get('/provincias', function(data) {
var options = '';
for (var i = 0; i < data.length; i++) { options +='<option value="' + data[i].id + '">' + data[i].nombre + '</option>' ;
} $('select[name="provincia" ]').html(options); }); });
</script>
@stop
** Como se ve con los selects comentados **
señalo que se ve que la datatable recibe la respuesta
** Como se ve con los selects sin comentar **
Se ve en este caso que no se carga ni la respuesta ni los scripts que se han importado
La verdad que he probado de todo y no lo consigo, a ver si alguien me hace el favor de decirme donde estoy equivocandome. Gracias
@stop
por un@show
o@yield
para que renderice la section. la otra es cambiarle el nombre a la section del form, los nombres de section se usan para poder configurar antes del render y puede que haya un conflicto cuando un blade esta dentro de otro blade (mas común en 5.x ).