Commit 57b12f9e authored by Alfonso Rafael Solis Rangel's avatar Alfonso Rafael Solis Rangel
Browse files

Implementacion de filtros tipo excel

parent c71a7c9b
Loading
Loading
Loading
Loading
+135 −17
Original line number Diff line number Diff line
<div id="contextMenu" class="hidden fixed z-50 bg-white border border-gray-300 rounded-md shadow-lg py-2 w-40">
    <button id="verBtn" class="w-full text-left px-4 py-2 hover:bg-gray-100">Ver contacto</button>
    <button id="editarBtn" class="w-full text-left px-4 py-2 hover:bg-gray-100">Editar</button>
    <button id="eliminarBtn" class="w-full text-left px-4 py-2 text-red-600 hover:bg-red-100">Eliminar</button>
</div>

<x-layout.default>

    <script src="/assets/js/simple-datatables.js"></script>
@@ -26,7 +32,22 @@
            <div class="overflow-x-auto">
                <table id="myTable" class="min-w-full table-auto whitespace-nowrap divide-y divide-gray-200 border border-gray-300 rounded-md shadow-sm text-sm text-left">
                    <thead class="bg-gray-100 text-gray-700 uppercase tracking-wider font-semibold">
                        <!-- encabezados -->
                        <tr>
                            <th>Profesión</th>
                            <th>Nombre completo</th>
                            <th>Cargo</th>
                            <th>Descripción del cargo</th>
                            <th>Grupos</th>
                            <th>Subgrupos</th>
                        </tr>
                        <tr class="filter-row">
                            <th><input type="text" class="filter-input" placeholder="Filtrar..." /></th>
                            <th><input type="text" class="filter-input" placeholder="Filtrar..." /></th>
                            <th><input type="text" class="filter-input" placeholder="Filtrar..." /></th>
                            <th><input type="text" class="filter-input" placeholder="Filtrar..." /></th>
                            <th><input type="text" class="filter-input" placeholder="Filtrar..." /></th>
                            <th><input type="text" class="filter-input" placeholder="Filtrar..." /></th>
                        </tr>
                    </thead>
                    <tbody class="divide-y divide-gray-200">
                        <!-- filas -->
@@ -44,6 +65,20 @@
    <link rel="stylesheet" href="/assets/css/jquery.toast.css">
    <script src="/assets/js/jquery.toast.js"></script>

    <script>
        function showAlert() {
            return Swal.fire({
                icon: 'warning',
                title: '¿Estás seguro?',
                text: "¡No podrás revertir esto!",
                showCancelButton: true,
                confirmButtonText: 'Eliminar',
                cancelButtonText: 'Cancelar',
                padding: '2em',
            });
        }
    </script>

    <script>
        const contactos = @json($contactos);
        const data = contactos.map(contacto => {
@@ -51,22 +86,9 @@

            return [renderParameter(contacto.profesion?.abreviatura), [contacto.nombre, contacto.ap_paterno, contacto.ap_materno].filter(Boolean).join(' '), renderParameter(contacto.cargo?.nombre),
            renderParameter(contacto.cargo_desc), renderParameter(contacto.grupos.map(grupo => grupo.nombre).join(', ')), 
            renderParameter(contacto.subgrupos.map(subgrupo => subgrupo.nombre).join(', ')), renderActions(contacto.id)];
            renderParameter(contacto.subgrupos.map(subgrupo => subgrupo.nombre).join(', '))];
        });

        function renderActions(id) {
            return `
                <div class="flex space-x-2">
                    <a href="/contactos/${id}/ver" class="btn btn-primary btn-sm">Ver contacto</a>
                    <form action="{{ route('contacto.destroy', '') }}/${id}" method="POST" class="inline-block">
                        @csrf
                        @method('DELETE')
                        <button type="submit" class="btn btn-danger btn-sm">Eliminar</button>
                    </form>
                    <a href="/contactos/${id}/editar" class="btn btn-primary btn-sm">Editar</a>
                </div>`;
        }

        function renderParameter(parametro) {
            if(parametro === null || parametro === undefined || parametro === ""){
                return `Sin información`;
@@ -97,13 +119,13 @@ function personalizarPaginacion() {
        document.addEventListener('DOMContentLoaded', () => {
            datatable = new simpleDatatables.DataTable('#myTable', {
                data: {
                    headings: ['Profesión', 'Nombre completo', 'Cargo', 'Descripción del cargo', 'Grupos', 'Subgrupos', 'Acciones'],
                    headings: ['Profesión', 'Nombre completo', 'Cargo', 'Descripción del cargo', 'Grupos', 'Subgrupos'],
                    data: data
                },
                perPage: 10,
                perPageSelect: [10, 20, 30, 50, 100],
                columns: [{
                        select: [0, 1, 2, 3, 4, 5, 6],
                        select: [0, 1, 2, 3, 4, 5],
                        sensitivity: 'base',
                        sort: 'asc'
                    },
@@ -117,6 +139,33 @@ function personalizarPaginacion() {
                    noRows: "No hay filas para mostrar",
                    info: "Mostrando {start} a {end} de {rows} filas",
                },
                tableRender: (_data, table, type) => {
                    if (type === "print") {
                        return table;
                    }
                    const tHead = table.childNodes[0];
                    const filterHeaders = {
                        nodeName: "TR",
                        childNodes: tHead.childNodes[0].childNodes.map(
                            (_th, index) => ({
                                nodeName: "TH",
                                childNodes: [
                                    {
                                        nodeName: "INPUT",
                                        attributes: {
                                            class: "datatable-input filter-input w-full px-2 py-1 border rounded",
                                            type: "search",
                                            "data-columns": `[${index}]`,
                                            placeholder: "Filtrar..."
                                        }
                                    }
                                ]
                            })
                        )
                    };
                    tHead.childNodes.push(filterHeaders);
                    return table;
                }
            });

            datatable.on("datatable.init", () => {
@@ -164,6 +213,19 @@ function personalizarPaginacion() {
                document.querySelector(".datatable-pagination-list").classList.add("flex", "items-center", "justify-center", "space-x-1");
            });

            datatable.on('datatable.init', () => {
                const filterInputs = document.querySelectorAll('.filter-input');
                filterInputs.forEach((input, colIndex) => {
                    input.addEventListener('input', function() {
                        datatable.columns().each((column, i) => {
                            if (i === colIndex) {
                                column.search(this.value);
                            }
                        });
                    });
                });
            });

            datatable.on("datatable.page", () => setTimeout(personalizarPaginacion, 0));
            
        });
@@ -194,5 +256,61 @@ function showToast(message, heading, icon) {
                @endforeach
            @endif
        });

        

        let selectedContactoId = null;

        document.addEventListener('DOMContentLoaded', function() {
            document.querySelectorAll('#myTable tbody tr').forEach(tr => {
                tr.addEventListener('contextmenu', function(e){
                    e.preventDefault();

                    const rowIndex = Array.from(tr.parentNode.children).indexOf(tr);
                    selectedContactoId = contactos[rowIndex]?.id;

                    const menu = document.getElementById('contextMenu');
                    menu.style.left = `${e.pageX}px`;
                    menu.style.top = `${e.pageY}px`;
                    menu.classList.remove('hidden');
                });
            });

            document.addEventListener('click', function(e){
                const menu = document.getElementById('contextMenu')
                if(!menu.contains(e.target)){
                    menu.classList.add('hidden');
                }
            })

            document.getElementById('verBtn').addEventListener('click', function() {
                if (selectedContactoId) {
                    window.location.href = `/contactos/${selectedContactoId}/ver`;
                }
            });
            document.getElementById('editarBtn').addEventListener('click', function() {
                if (selectedContactoId) {
                    window.location.href = `/contactos/${selectedContactoId}/editar`;
                }
            });
            document.getElementById('eliminarBtn').addEventListener('click', function() {
                if (selectedContactoId) {
                    showAlert().then((result) => {
                        if (result.isConfirmed) {
                            // Crea un formulario y envíalo
                            const form = document.createElement('form');
                            form.method = 'POST';
                            form.action = `/contactos/${selectedContactoId}`;
                            form.innerHTML = `
                                @csrf
                                @method('DELETE')
                            `;
                            document.body.appendChild(form);
                            form.submit();
                        }
                    });
                }
            });
        });
    </script>
</x-layout.default>
 No newline at end of file