Featured Post

Tablas Responsivas con Bootstrap 5 pc escritorio y dispositivos mobiles

 

Tabla Responsiva bootstrap 5 tabla categorias

vista tabla resolucion pantallas pc escritorio


vista tabla resolucion pantallas mobiles







Aquí tienes una versión simplificada que mantiene tu estructura actual pero la hace completamente responsiva:

html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tabla Responsiva</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .img-producto {
            width: 50px;
            height: 50px;
            object-fit: cover;
            border-radius: 4px;
        }
        
        /* Estilos para móviles */
        @media (max-width: 768px) {
            .table-responsive {
                border: 1px solid #dee2e6;
                border-radius: 0.375rem;
            }
            
            .mobile-hidden {
                display: none;
            }
            
            .mobile-product-card {
                border-bottom: 1px solid #dee2e6;
                padding: 1rem;
                background: white;
            }
            
            .mobile-product-card:last-child {
                border-bottom: none;
            }
            
            .mobile-product-info {
                display: flex;
                align-items: center;
                gap: 1rem;
                margin-bottom: 1rem;
            }
            
            .mobile-actions {
                display: flex;
                gap: 0.5rem;
                justify-content: center;
            }
            
            .mobile-actions .btn {
                flex: 1;
                max-width: 120px;
            }
        }
    </style>
</head>
<body>
    <!-- Vista Desktop (se muestra en pantallas grandes) -->
    <div class="d-none d-md-block">
        <div class="table-responsive">
            <table class="table table-striped table-hover align-middle">
                <thead class="table-dark">
                    <tr>
                        <th>Id</th>
                        <th>Imagen</th>
                        <th>Nombre</th>
                        <th>Accion</th>
                        <th>Accion</th>
                    </tr>
                </thead>
                <tbody id="tabla-productos">
                    <tr>
                        <td colspan="5" class="text-center">
                            <div class="spinner-border text-primary" role="status">
                                <span class="visually-hidden">Cargando...</span>
                            </div>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>

    <!-- Vista Mobile (se muestra en pantallas pequeñas) -->
    <div class="d-md-none" id="mobile-productos">
        <div class="table-responsive">
            <div class="text-center py-3">
                <div class="spinner-border text-primary" role="status">
                    <span class="visually-hidden">Cargando...</span>
                </div>
            </div>
        </div>
    </div>

    <script>
        let paginaActual = 1;
        let terminoBusqueda = '';
        let categoriaSeleccionada = '';

        function cargarProductos(pagina = 1, busqueda = '', categoria = '') {
            const tbody = document.getElementById('tabla-productos');
            const mobileContainer = document.getElementById('mobile-productos');
            
            // Mostrar loading en ambas vistas
            tbody.innerHTML = '<tr><td colspan="5" class="text-center"><div class="spinner-border text-primary"></div></td></tr>';
            mobileContainer.innerHTML = '<div class="text-center py-3"><div class="spinner-border text-primary"></div></div>';

            fetch('productos.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ busqueda, categoria, pagina })
            })
            .then(response => response.json())
            .then(data => {
                if (!data.productos || !Array.isArray(data.productos)) {
                    tbody.innerHTML = '<tr><td colspan="5" class="text-center text-muted">No hay productos</td></tr>';
                    mobileContainer.innerHTML = '<div class="text-center text-muted py-3">No hay productos</div>';
                    return;
                }

                // Renderizar vista Desktop
                tbody.innerHTML = data.productos.map(p => `
                    <tr>
                        <td>${p.id}</td>
                        <td>
                            <img src="fotos/${p.foto}" alt="${p.nombre}" class="img-producto"
                                 onerror="this.src='noimagen.png'">
                        </td>
                        <td>${p.nombre}</td>
                        <td>
                            <button class="btn btn-sm btn-outline-primary me-1" onclick="editarProducto(${p.id})">
                                Editar
                            </button>
                        </td>
                        <td>
                            <button class="btn btn-sm btn-outline-danger" onclick="eliminarProducto(${p.id})">
                                Eliminar
                            </button>
                        </td>
                    </tr>
                `).join('');

                // Renderizar vista Mobile
                mobileContainer.innerHTML = data.productos.map(p => `
                    <div class="mobile-product-card">
                        <div class="mobile-product-info">
                            <img src="fotos/${p.foto}" alt="${p.nombre}" class="img-producto"
                                 onerror="this.src='noimagen.png'">
                            <div>
                                <strong class="d-block">${p.nombre}</strong>
                                <small class="text-muted">ID: ${p.id}</small>
                            </div>
                        </div>
                        <div class="mobile-actions">
                            <button class="btn btn-sm btn-outline-primary" onclick="editarProducto(${p.id})">
                                Editar
                            </button>
                            <button class="btn btn-sm btn-outline-danger" onclick="eliminarProducto(${p.id})">
                                Eliminar
                            </button>
                        </div>
                    </div>
                `).join('');

                // Actualizar paginación
                paginaActual = data.pagina_actual;
                terminoBusqueda = busqueda;
                categoriaSeleccionada = categoria;

                document.getElementById('info-pagina').textContent = `Página ${data.pagina_actual} de ${data.total_paginas}`;
                document.getElementById('btn-anterior').disabled = data.pagina_actual <= 1;
                document.getElementById('btn-siguiente').disabled = data.pagina_actual >= data.total_paginas;
            })
            .catch(() => {
                tbody.innerHTML = '<tr><td colspan="5" class="text-center text-danger">Error al cargar</td></tr>';
                mobileContainer.innerHTML = '<div class="text-center text-danger py-3">Error al cargar</div>';
            });
        }

        // Funciones de ejemplo (mantienen tu código original)
        function editarProducto(id) {
            console.log('Editar producto:', id);
            // Tu lógica de edición aquí
        }

        function eliminarProducto(id) {
            if (confirm('¿Estás seguro de eliminar este producto?')) {
                console.log('Eliminar producto:', id);
                // Tu lógica de eliminación aquí
            }
        }

        // Cargar productos al iniciar
        document.addEventListener('DOMContentLoaded', function() {
            cargarProductos();
        });
    </script>
</body>
</html>

Tabla Responsiva bootstrap 5 tabla productos

vista tabla resolucion pantallas pc escritorio
vista tabla resolucion pantallas mobiles



<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tabla Responsiva</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <style> .img-producto { width: 50px; height: 50px; object-fit: cover; border-radius: 4px; } /* Estilos para móviles */ @media (max-width: 768px) { .table-responsive { border: 1px solid #dee2e6; border-radius: 0.375rem; } .mobile-product-card { border-bottom: 1px solid #dee2e6; padding: 1rem; background: white; } .mobile-product-card:last-child { border-bottom: none; } .mobile-product-header { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; } .mobile-product-details { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; margin-bottom: 1rem; } .mobile-detail-item { display: flex; flex-direction: column; } .mobile-detail-label { font-size: 0.75rem; color: #6c757d; font-weight: 500; } .mobile-detail-value { font-size: 0.875rem; font-weight: 500; } .mobile-actions { display: flex; gap: 0.5rem; justify-content: center; } .mobile-actions .btn { flex: 1; max-width: 120px; } } </style> </head> <body> <!-- Vista Desktop (se muestra en pantallas grandes) --> <div class="d-none d-md-block"> <div class="table-responsive"> <table class="table table-striped table-hover align-middle"> <thead class="table-dark"> <tr> <th>Id</th> <th>Foto</th> <th>Cod.Barra</th> <th>Nombre</th> <th>Precio</th> <th>Categoría</th> <th>Accion</th> <th>Accion</th> </tr> </thead> <tbody id="tabla-productos"> <tr> <td colspan="8" class="text-center"> <div class="spinner-border text-primary" role="status"> <span class="visually-hidden">Cargando...</span> </div> </td> </tr> </tbody> </table> </div> </div> <!-- Vista Mobile (se muestra en pantallas pequeñas) --> <div class="d-md-none" id="mobile-productos"> <div class="table-responsive"> <div class="text-center py-3"> <div class="spinner-border text-primary" role="status"> <span class="visually-hidden">Cargando...</span> </div> </div> </div> </div> <script> let paginaActual = 1; let terminoBusqueda = ''; let categoriaSeleccionada = ''; function cargarProductos(pagina = 1, busqueda = '', categoria = '') { const tbody = document.getElementById('tabla-productos'); const mobileContainer = document.getElementById('mobile-productos'); // Mostrar loading en ambas vistas tbody.innerHTML = '<tr><td colspan="8" class="text-center"><div class="spinner-border text-primary"></div></td></tr>'; mobileContainer.innerHTML = '<div class="text-center py-3"><div class="spinner-border text-primary"></div></div>'; fetch('productos.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ busqueda, categoria, pagina }) }) .then(response => response.json()) .then(data => { if (!data.productos || !Array.isArray(data.productos)) { tbody.innerHTML = '<tr><td colspan="8" class="text-center text-muted">No hay productos</td></tr>'; mobileContainer.innerHTML = '<div class="text-center text-muted py-3">No hay productos</div>'; return; } // Renderizar vista Desktop tbody.innerHTML = data.productos.map(producto => ` <tr> <td>${producto.id}</td> <td> <img src="fotos/${producto.foto}" alt="${producto.nombre}" class="img-producto" onerror="this.src='noimagen.png'"> </td> <td> ${producto.barra} <button class="btn btn-sm btn-outline-primary me-1" onclick="generarEtiqueta(${producto.barra}, '${producto.nombre.replace(/'/g, "\\'")}')"> Cod.Barra </button> </td> <td>${producto.nombre}</td> <td>$ ${parseFloat(producto.precio).toFixed(2)}</td> <td>${producto.categoria || '—'}</td> <td> <button class="btn btn-sm btn-outline-primary me-1" onclick="editarProducto(${producto.id})"> Editar </button> </td> <td> <button class="btn btn-sm btn-outline-danger" onclick="eliminarProducto(${producto.id})"> Eliminar </button> </td> </tr> `).join(''); // Renderizar vista Mobile mobileContainer.innerHTML = data.productos.map(producto => ` <div class="mobile-product-card"> <div class="mobile-product-header"> <img src="fotos/${producto.foto}" alt="${producto.nombre}" class="img-producto" onerror="this.src='noimagen.png'"> <div> <strong class="d-block">${producto.nombre}</strong> <small class="text-muted">ID: ${producto.id}</small> </div> </div> <div class="mobile-product-details"> <div class="mobile-detail-item"> <span class="mobile-detail-label">Código Barra</span> <span class="mobile-detail-value">${producto.barra}</span> </div> <div class="mobile-detail-item"> <span class="mobile-detail-label">Precio</span> <span class="mobile-detail-value">$ ${parseFloat(producto.precio).toFixed(2)}</span> </div> <div class="mobile-detail-item"> <span class="mobile-detail-label">Categoría</span> <span class="mobile-detail-value">${producto.categoria || '—'}</span> </div> </div> <div class="mobile-actions"> <button class="btn btn-sm btn-outline-primary" onclick="generarEtiqueta(${producto.barra}, '${producto.nombre.replace(/'/g, "\\'")}')"> Cod.Barra </button> <button class="btn btn-sm btn-outline-primary" onclick="editarProducto(${producto.id})"> Editar </button> <button class="btn btn-sm btn-outline-danger" onclick="eliminarProducto(${producto.id})"> Eliminar </button> </div> </div> `).join(''); // Actualizar paginación actualizarPaginacion(data); }) .catch(error => { console.error('Error al cargar productos:', error); tbody.innerHTML = '<tr><td colspan="8" class="text-center text-danger">Error al cargar los productos</td></tr>'; mobileContainer.innerHTML = '<div class="text-center text-danger py-3">Error al cargar los productos</div>'; }); } function actualizarPaginacion(data) { paginaActual = data.pagina_actual; terminoBusqueda = busqueda; categoriaSeleccionada = categoria; document.getElementById('info-pagina').textContent = `Página ${data.pagina_actual} de ${data.total_paginas}`; document.getElementById('btn-anterior').disabled = data.pagina_actual <= 1; document.getElementById('btn-siguiente').disabled = data.pagina_actual >= data.total_paginas; } // Funciones de ejemplo function generarEtiqueta(codigoBarra, nombre) { console.log('Generar etiqueta para:', codigoBarra, nombre); // Tu lógica de generación de etiqueta aquí } function editarProducto(id) { console.log('Editar producto:', id); // Tu lógica de edición aquí } function eliminarProducto(id) { if (confirm('¿Estás seguro de eliminar este producto?')) { console.log('Eliminar producto:', id); // Tu lógica de eliminación aquí } } // Cargar productos al iniciar document.addEventListener('DOMContentLoaded', function() { cargarProductos(); }); </script> </body> </html>

Comentarios