1

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">&times;</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">&times;</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 ** introducir la descripción de la imagen aquí

señalo que se ve que la datatable recibe la respuesta

** Como se ve con los selects sin comentar **

introducir la descripción de la imagen aquí

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

4
  • versión de laravel? Commented el 19 jun. 2023 a las 16:19
  • es la version 8
    – miguelex
    Commented el 20 jun. 2023 a las 6:05
  • dentro del nested blade ( el form ) podes probar un par de cosas: reemplazar el @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 ). Commented el 20 jun. 2023 a las 13:09
  • Lo he probado y no he conseguido que vaya aun. Sigo probando combinaciones varias, auqnue la mas obvia, que seria ver si funciona con un solo select, no se me ha ocurrido hasta esta mañana
    – miguelex
    Commented el 21 jun. 2023 a las 6:00

1 respuesta 1

0

El problema que estás experimentando podría estar relacionado con el orden en el que se cargan los scripts y las dependencias en tu vista Blade. Puedes intentar hacer algunos cambios en tu código para solucionarlo:

Asegúrate de que las secciones @section('css') y @section('js') se cierren correctamente utilizando @endsection. Actualmente, tienes dos @section('css') y falta un @endsection en tu código.

Reorganiza el orden en el que se cargan los scripts en tu sección @section('js'). Primero, carga jQuery y moment.js antes de cargar los otros scripts. Debería verse así:

@section('js')
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.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>
        // ... tu código JavaScript ...
    </script>
@endsection

Verifica si tienes los scripts necesarios en tu vista principal. Parece que estás utilizando el paquete adminLTE, así que asegúrate de haber agregado los enlaces a los estilos y scripts requeridos en tu archivo de diseño principal (adminlte::page).

Asegúrate de que las rutas utilizadas en tu vista ({{ route('empleado.list') }} y '/provincia/${this.value}/ciudades') estén correctamente definidas en tus archivos de rutas (web.php).

Siguiendo estos pasos, deberías poder solucionar el problema y hacer que tu tabla y modal funcionen correctamente. Si aún tienes dificultades, asegúrate de verificar la consola del navegador para ver si hay algún error adicional que pueda estar afectando el funcionamiento de tu código.

2

¿No es la respuesta que buscas? Examina otras preguntas con la etiqueta o formula tu propia pregunta.