Documentación de vGrid
vGrid es una cuadrícula de datos JavaScript que funciona con un solo script y una hoja de estilos, sin dependencias. Se proporciona vGrid({ … }) un contenedor y una URL; el servidor pagina, ordena y filtra los datos, y la cuadrícula muestra el resultado.
vGrid({
el: '#orders',
dataSource: '/api/orders', // your endpoint
rowsPerPage: 25, // sent as limit=25
columns: [
{ name: 'number', label: 'Order' },
{ name: 'total', label: 'Total' }
]
});
Esta página te guía desde esa llamada hasta una cuadrícula conectada a tu propia base de datos, con miles o millones de filas. Puedes verla en funcionamiento en el Ejemplo de productos: ordena por precio, aplica un filtro y abre un panel de ventas.
Descargar
Dos archivos ejecutan la cuadrícula: vgrid.js y vgrid.css. En producción, usa el par minificado.
| Archivo | Este sitio |
|---|---|
vgrid.min.js | Descargar |
vgrid.min.css | Descargar |
vgrid.js, legible | Descargar |
vgrid.css, legible | Descargar |
También puedes cargarlos desde el CDN de jsDelivr, que sirve la versión más reciente del código publicado en GitHub:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/virgil2304/vGrid@main/dist/vgrid.min.css">
<script src="https://cdn.jsdelivr.net/gh/virgil2304/vGrid@main/dist/vgrid.min.js"></script>
Instalación
Añade vGrid a cualquier página HTML en tres pasos.
Incluir vGrid
Carga los dos archivos desde el CDN o desde tu propia copia (Descargar). El script define una función global, vGrid.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/virgil2304/vGrid@main/dist/vgrid.min.css">
<script src="https://cdn.jsdelivr.net/gh/virgil2304/vGrid@main/dist/vgrid.min.js"></script>
Añadir un elemento de destino
Cualquier elemento sirve: un <table> se utiliza tal cual; cualquier otro elemento recibe una tabla en su interior.
<div id="tasks"></div>
Inicializar la cuadrícula
Llama a vGrid cuando exista el elemento.
<script>
document.addEventListener('DOMContentLoaded', () => {
vGrid({
el: '#tasks',
columns: [
{ name: 'task', label: 'Task' },
{ name: 'owner', label: 'Owner' }
],
data: [
{ task: 'Draft release notes', owner: 'Ava' },
{ task: 'Review pull requests', owner: 'Noah' }
]
});
});
</script>
El resultado es una cuadrícula ordenable y filtrable, con números de fila y una barra de herramientas. Pruébala en el Ejemplo local: filtra por Status y luego ordena por Owner.
Requisitos y compatibilidad con navegadores
Sin dependencias, sin frameworks y sin paso de compilación. vGrid necesita un navegador compatible con la API Popover:
| Navegador | Mínimo |
|---|---|
| Chrome y Edge | 114 |
| Firefox | 125 |
| Safari y todos los navegadores de iOS / iPadOS | 17 |
| Opera | 100 |
| Samsung Internet | 23 |
En los navegadores antiguos las filas siguen cargándose, pero no se abren la ventana de ajustes, el menú de modos de filtro ni los menús de subcuadrícula. Internet Explorer, las versiones antiguas de Edge y Opera Mini no son compatibles.
Guía de integración
Desde cero hasta una cuadrícula cuyos datos pagina, ordena y filtra tu servidor. Empieza con las dos etiquetas de Incluir vGrid y un contenedor:
<div id="orders"></div>
La cuadrícula llama a tu URL con estos parámetros de consulta:
GET /api/orders?page=2&limit=25&sort=total&dir=desc&status=paid
El endpoint filtra, ordena y cuenta los resultados, y devuelve una página:
{
"data": [ { "number": "A-1001", "customer": "Ava", "status": "paid", "total": 120 } ],
"total": 1834,
"page": 2,
"limit": 25
}
En el servidor, con el lenguaje que prefieras: conecta con la base de datos, lee una página, convierte cada fila en un objeto y devuelve los datos con la estructura anterior. Eso es lo que necesita vGrid; la conexión y la consulta son responsabilidad de tu aplicación.
<?php
$db = new PDO('mysql:host=localhost;dbname=shop', 'user', 'password');
$page = (int) ($_GET['page'] ?? 1);
$limit = (int) ($_GET['limit'] ?? 25);
$total = (int) $db->query('SELECT COUNT(*) FROM orders')->fetchColumn();
$rows = $db->prepare('SELECT * FROM orders LIMIT :limit OFFSET :offset');
$rows->bindValue(':limit', $limit, PDO::PARAM_INT);
$rows->bindValue(':offset', ($page - 1) * $limit, PDO::PARAM_INT);
$rows->execute();
$data = [];
foreach ($rows->fetchAll(PDO::FETCH_ASSOC) as $row) {
$data[] = [ // one object per row
'number' => $row['number'], // key = columns[].name
'customer' => $row['customer'],
'status' => $row['status'],
'total' => (float) $row['total'],
];
}
header('Content-Type: application/json');
echo json_encode([ // the shape vGrid reads
'data' => $data,
'total' => $total, // all matching rows, not this page
'page' => $page,
'limit' => $limit,
]);
import sqlite3
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.get('/api/orders')
def orders():
db = sqlite3.connect('shop.db')
db.row_factory = sqlite3.Row
page = int(request.args.get('page', 1))
limit = int(request.args.get('limit', 25))
total = db.execute('SELECT COUNT(*) FROM orders').fetchone()[0]
rows = db.execute('SELECT * FROM orders LIMIT ? OFFSET ?',
(limit, (page - 1) * limit))
data = []
for row in rows:
data.append({ # one object per row
'number': row['number'], # key = columns[].name
'customer': row['customer'],
'status': row['status'],
'total': row['total'],
})
return jsonify( # the shape vGrid reads
data=data,
total=total, # all matching rows, not this page
page=page,
limit=limit,
)
using Microsoft.Data.SqlClient;
var app = WebApplication.Create(args);
app.MapGet("/api/orders", async (int page = 1, int limit = 25) =>
{
await using var db = new SqlConnection(
"Server=localhost;Database=shop;Integrated Security=true");
await db.OpenAsync();
var count = new SqlCommand("SELECT COUNT(*) FROM orders", db);
var total = (int)(await count.ExecuteScalarAsync())!;
var query = new SqlCommand("SELECT * FROM orders ORDER BY id " +
"OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY", db);
query.Parameters.AddWithValue("@offset", (page - 1) * limit);
query.Parameters.AddWithValue("@limit", limit);
var data = new List<object>();
await using var rows = await query.ExecuteReaderAsync();
while (await rows.ReadAsync())
{
data.Add(new // one object per row
{
number = rows["number"], // key = columns[].name
customer = rows["customer"],
status = rows["status"],
total = rows["total"]
});
}
return Results.Json(new // the shape vGrid reads
{
data,
total, // all matching rows, not this page
page,
limit
});
});
app.Run();
// application.properties
// spring.datasource.url=jdbc:mysql://localhost/shop
// spring.datasource.username=user
// spring.datasource.password=password
@RestController
public class OrdersController {
private final JdbcTemplate db;
public OrdersController(JdbcTemplate db) {
this.db = db;
}
@GetMapping("/api/orders")
public Map<String, Object> orders(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "25") int limit) {
Integer total = db.queryForObject(
"SELECT COUNT(*) FROM orders", Integer.class);
List<Map<String, Object>> rows = db.queryForList(
"SELECT * FROM orders LIMIT ? OFFSET ?", limit, (page - 1) * limit);
List<Map<String, Object>> data = new ArrayList<>();
for (Map<String, Object> row : rows) {
Map<String, Object> item = new LinkedHashMap<>(); // one object per row
item.put("number", row.get("number")); // key = columns[].name
item.put("customer", row.get("customer"));
item.put("status", row.get("status"));
item.put("total", row.get("total"));
data.add(item);
}
Map<String, Object> response = new LinkedHashMap<>(); // the shape vGrid reads
response.put("data", data);
response.put("total", total); // all matching rows, not this page
response.put("page", page);
response.put("limit", limit);
return response;
}
}
import express from 'express';
import mysql from 'mysql2/promise';
const db = await mysql.createConnection({
host: 'localhost', user: 'user', password: 'password', database: 'shop'
});
const app = express();
app.get('/api/orders', async (req, res) => {
const page = Number(req.query.page ?? 1);
const limit = Number(req.query.limit ?? 25);
const [[{ total }]] = await db.query('SELECT COUNT(*) AS total FROM orders');
const [rows] = await db.query('SELECT * FROM orders LIMIT ? OFFSET ?',
[limit, (page - 1) * limit]);
const data = [];
for (const row of rows) {
data.push({ // one object per row
number: row.number, // key = columns[].name
customer: row.customer,
status: row.status,
total: row.total
});
}
res.json({ // the shape vGrid reads
data,
total, // all matching rows, not this page
page,
limit
});
});
app.listen(3000);
Cada filtro con valor llega como un parámetro con el nombre de su columna; la ordenación llega como sort y dir; añádelos a la consulta en WHERE y ORDER BY.
Los endpoints públicos de este sitio se describen en la Referencia de la API. Luego configura la cuadrícula para que use tu endpoint:
vGrid({
el: '#orders',
dataSource: '/api/orders',
rowsPerPage: 25, // sent as limit=25
columns: [
{ name: 'number', label: 'Order' },
{ name: 'customer', label: 'Customer' },
{ name: 'status', label: 'Status' },
{ name: 'total', label: 'Total' }
]
});
Verás las primeras 25 filas, el mensaje «Mostrando 1–25 de 1834» y un paginador. Al escribir en un filtro, se envía una solicitud cuando haces una pausa; puedes verla en la pestaña Red del navegador. Si aparece un mensaje en lugar de las filas, es la respuesta del servidor, por ejemplo «El servidor respondió con el error 500» o «La respuesta no contiene el campo data».
Puedes verlo en funcionamiento en el Ejemplo Ajax: filtra por Name y luego ordena por Code.
Dentro de una aplicación basada en un framework se aplican las mismas reglas:
- El framework controla el contenedor; vGrid controla todo lo que hay dentro. No permitas que el framework renderice ni borre sus elementos secundarios.
- Crea la cuadrícula cuando el contenedor ya esté en la página y llama a
destroy()cuando se elimine; de lo contrario, quedarán activos los escuchadores, observadores y solicitudes. - La configuración se lee una sola vez. Un nuevo objeto de configuración reconstruye la cuadrícula, así que mantenla estable (
useMemo,computed) y usa la API de instancia (reload(),setPage(),sort()) para los cambios cotidianos. - Importa la hoja de estilos una sola vez y de forma global. El CSS limitado a un componente (Vue
scoped, los módulos CSS y la encapsulación de Angular) no afecta a los elementos de la cuadrícula. - React y Vue son opcionales; instala solo el que necesite tu adaptador.
Instalar con npm
vGrid aún no está publicado en el registro de npm; npm lo instala desde GitHub. Añade #<commit> para fijar un commit.
npm install github:virgil2304/vGrid
| Importación | Contenido |
|---|---|
vgrid | El vGrid función, como módulo ES y CommonJS |
vgrid/style.css | La hoja de estilos |
vgrid/react | El componente React VGRID |
vgrid/vue | El componente Vue vGrid |
vgrid/browser | vGrid, también asignada a globalThis.vGrid para el código que necesita la variable global |
vgrid/dist/* | Los archivos de Descargar |
Con un empaquetador:
import { vGrid } from 'vgrid';
import 'vgrid/style.css';
const grid = vGrid({
el: '#orders',
dataSource: '/api/orders',
rowsPerPage: 25,
columns: [
{ name: 'number', label: 'Order' },
{ name: 'total', label: 'Total' }
]
});
// when the container leaves the page; vGrid() returns null on a bad config
grid?.destroy();
Con CommonJS (Jest y otras herramientas basadas en require): const { vGrid } = require('vgrid');. Cualquier empaquetador que lea package.json exports es compatible: Vite, webpack 5, Rollup, esbuild y Parcel 2.
Montaje e identificación
Dónde se coloca la cuadrícula, cuál es su título y qué nombre la distingue de las demás cuadrículas de la página.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
el | selector o Element | obligatorio | El contenedor. Un <table> se utiliza tal cual; el contenido de cualquier otro elemento se sustituye por una tabla nueva. Si no se encuentra el elemento, la cuadrícula se detiene (Solución de problemas). |
caption | cadena HTML | ninguno | Una fila en la parte superior de la tabla, junto a los botones de la barra de herramientas. Se inserta como HTML. |
namespace | cadena de texto | eldel elemento id | Añade <namespace>-<part> junto a cada clase vgrid-<part> , y añade <namespace>-row-<id> a las filas que tengan un campo id . También se usa como nombre alternativo del archivo, <namespace>-<date>, si el servidor no envía uno, y como título al imprimir. |
autoDestroy | true | false | false | Destruye la cuadrícula en el siguiente desplazamiento o cambio de tamaño de la ventana después de que se retire su contenedor. Úsalo en páginas que eliminan cuadrículas sin llamar a destroy(). |
Dos cuadrículas en una página:
vGrid({
el: '#orders',
caption: 'Orders',
dataSource: '/api/orders',
rowsPerPage: 25,
columns: [{ name: 'number', label: 'Order' }, { name: 'total', label: 'Total' }]
});
vGrid({
el: document.querySelector('#returns'),
caption: '<strong>Returns</strong>', // HTML
namespace: 'returns-grid', // instead of the id "returns"
autoDestroy: true, // this panel can be removed
dataSource: '/api/returns',
rowsPerPage: 25,
columns: [{ name: 'number', label: 'Return' }]
});
Las filas de la segunda cuadrícula tienen la clase returns-grid-row-<id>, y sus descargas usan como nombre alternativo returns-grid-<date> si el servidor no envía uno. Selecciona una cuadrícula mediante su contenedor o un registro mediante la clase de su fila:
#orders .vgrid-caption { /* the Orders grid's caption only */ }
.returns-grid-row-42 { /* the return with id 42 */ }
Consulta el título y el espacio de nombres en el Ejemplo local: su fila de título tiene las clases vgrid-caption local-grid-caption.
Datos
Las filas provienen de un arreglo en la página (data) o del servidor (dataSource). Si se configura dataSource , data , se ignora.
Datos locales
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
data | arreglo de objetos de fila | [] | Filas almacenadas en el navegador; la cuadrícula las ordena, filtra y pagina por sí misma. |
const grid = vGrid({
el: '#tasks',
data: tasks, // [{ task: 'Draft release notes', owner: 'Ava' }, …]
rowsPerPage: 10,
columns: [{ name: 'task', label: 'Task' }, { name: 'owner', label: 'Owner' }]
});
grid.reload(newTasks); // new rows, back to page 1
Todas las filas están en la página, por lo que los datos locales son adecuados para conjuntos pequeños; los conjuntos grandes deben procesarse en el servidor. Pruébalo en el Ejemplo local.
Datos remotos
El navegador conserva una página de filas; cada cambio de ordenación, filtro o página genera una solicitud al servidor.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
dataSource | URL | ninguno | Configura la cuadrícula para usar datos remotos. La cadena de consulta de la URL se envía con cada solicitud; si hay un conflicto, prevalecen los parámetros de la cuadrícula. |
method | 'GET' | 'POST' | 'GET' | GET envía los parámetros en la cadena de consulta; POST los envía en el cuerpo como JSON. |
headers | objeto | {} | Encabezados adicionales para cada solicitud, como un token de autenticación. También se envían a los paneles de subcuadrícula. |
vGrid({
el: '#orders',
dataSource: '/api/orders?region=eu', // region=eu goes with every request
headers: { Authorization: 'Bearer ' + token },
rowsPerPage: 25,
columns: [{ name: 'number', label: 'Order' }, { name: 'total', label: 'Total' }]
});
Para enviar los parámetros en el cuerpo como JSON:
vGrid({
el: '#orders',
dataSource: '/api/orders',
method: 'POST', // body: {"page":1,"limit":25}
rowsPerPage: 25,
columns: [{ name: 'number', label: 'Order' }, { name: 'total', label: 'Total' }]
});
Consulta la cuadrícula remota en el Ejemplo Ajax: abre la pestaña Red del navegador y ordena los datos o cambia de página.
La solicitud
Cada carga y cada cambio de ordenación, filtro o página envía estos parámetros: en la cadena de consulta para GET, en el cuerpo JSON para POST.
| Parámetro | Se envía cuando | Ejemplo |
|---|---|---|
page | siempre | page=2 |
limit | se establece el tamaño de página | limit=25 |
sort, dir | se ordena una columna; con un criterio secundario (Mayús+clic en un encabezado), ambos son listas separadas por comas y ordenadas por prioridad | sort=total&dir=descsort=status,total&dir=asc,desc |
columns | se ocultan algunas columnas; enumera las visibles | columns=number,total |
| un nombre de columna | su filtro tiene un valor | status=paid |
| una clave de modo de filtro | se elige un modo de filtro; un rango envía cada extremo con valor bajo su propia clave | from_date=2026-01-01 |
un externalFilters clave | el campo de entrada de la página tiene un valor | region=eu |
download | un descarga del servidor | download=true |
lang | siempre; el idioma del lector, vacío si no se encuentra ninguno (Idioma) | lang=de-AT |
GET /api/orders?page=2&limit=25&sort=total&dir=desc&columns=number,total&status=paid&lang=en
POST /api/orders
{ "page": 2, "limit": 25, "sort": "total", "dir": "desc", "columns": "number,total", "status": "paid", "lang": "en" }
Se omiten los filtros vacíos. La cuadrícula espera una pausa de 300 ms al escribir, y una solicitud nueva cancela la que todavía está en curso.
La respuesta
{
"data": [ { "number": "A-1026", "total": 120 } ],
"total": 1834,
"page": 2,
"limit": 25
}
| Campo | Obligatorio | Efecto |
|---|---|---|
data | sí | Las filas, identificadas por columns[].name. Cualquier respuesta que no sea un arreglo muestra un error en lugar de las filas. |
total | no; usa como valor predeterminado data.length | Filas que coinciden con los filtros en todas las páginas. Se usa para mostrar «Mostrando X–Y de Z» y calcular el número de páginas. |
page | no; usa la página solicitada de forma predeterminada | La página que se muestra. Envíala para corregir una página que ya no existe. |
limit | no | El tamaño de página. Sin este valor no hay paginador ni mensaje «Mostrando». |
Consulta una respuesta real en el Ejemplo Ajax: en la pestaña Red, abre la solicitud a /api/continents.
Solicitudes, seguridad y nombres reservados
En una página con un csrf-token etiqueta meta, cada solicitud al mismo origen la incluye como X-CSRF-TOKEN encabezado: filas, descargas y paneles de subcuadrícula. Un token que configures en headers tiene prioridad; las solicitudes a otros orígenes nunca lo reciben.
<meta name="csrf-token" content="…">
Estos nombres se usan para la paginación y la ordenación, por lo que ninguna columna, externalFilters clave ni clave de modo de filtro puede usarlos, sin importar el uso de mayúsculas: page, limit, sort, dir, offset, cursor, perpage, pagesize, sortby, sortorder, columns.
{ name: 'sort', label: 'Sort order' } // stops the grid
{ name: 'sort_order', label: 'Sort order' } // works
Una columna o un filtro externo con un nombre reservado detiene la cuadrícula: vGrid() devuelve null y la consola indica cuál es. Se descarta toda clave de modo de filtro reservada. Consulta Solución de problemas.
Respuestas lentas, vacías o incorrectas
Mientras se procesa una solicitud, las filas se atenúan de inmediato; después de 200 ms aparece sobre ellas el indicador «Cargando…». Una respuesta vacía data arreglo, se muestra «No hay registros para mostrar.»
Si una solicitud falla, las filas permanecen y el indicador muestra el motivo, que también se anuncia a los lectores de pantalla:
| Causa | Mensaje |
|---|---|
| Estado distinto de 2xx | El servidor respondió con <status>. |
| El cuerpo no es JSON | La respuesta no es JSON válido. |
El cuerpo es un arreglo o null | La respuesta no es un objeto que contenga un arreglo data. |
No data | La respuesta no contiene el campo «data». |
data no es un arreglo | El campo «data» no es un arreglo. |
La siguiente solicitud correcta borra el mensaje. El error también se envía a onReady como { error } y en la consola como vGrid fetch error:. Personaliza el indicador y la fila vacía:
.vgrid-loading-badge { /* the Loading… badge */ }
.vgrid-loading-badge.vgrid-loading-error { /* the badge showing an error */ }
.vgrid-empty td { /* the "No records to show." row */ }
Observa el indicador en el Ejemplo Ajax: limita la velocidad de red del navegador y cambia de página.
Totales del servidor
Muestra en elementos de la página valores que el servidor calcula sobre todos los resultados filtrados, como el total de ingresos. Solo funciona con cuadrículas remotas.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
externalSummary | objeto con claves selector o Element | {} | Después de cada carga, el texto de cada elemento se convierte en el valor summary con la misma clave. Si falta una clave en summary , se vacía el elemento; una respuesta sin summary los deja tal como están. |
<p>Revenue: <span id="revenue"></span> from <span id="order-count"></span> orders</p>
vGrid({
el: '#orders',
dataSource: '/api/orders',
rowsPerPage: 25,
externalSummary: { revenue: '#revenue', count: '#order-count' },
columns: [{ name: 'number', label: 'Order' }, { name: 'total', label: 'Total' }]
});
El servidor añade un summary arreglo a la respuesta:
{
"data": [ { "number": "A-1001", "total": 120 } ],
"total": 1834,
"page": 1,
"limit": 25,
"summary": [
{ "key": "revenue", "value": "$48,210.00" },
{ "key": "count", "value": "1834" }
]
}
Si el elemento no está en la página, se registra un error y se omite.
Idioma
Cada solicitud de una cuadrícula remota indica al servidor el idioma del lector para que pueda responder en ese idioma: con valores traducidos, fechas y números locales y nombres en la escritura adecuada. La cuadrícula lo envía como lang, siempre, en cada solicitud.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
locale | una etiqueta de idioma, como 'en', 'de-AT' o 'pt-BR' | se encuentra en la página | El idioma que la cuadrícula envía al servidor como lang. |
locale: 'de-AT',
De dónde procede el idioma
La cuadrícula usa el primero de estos elementos que contenga una etiqueta de idioma válida:
| # | Código fuente | Ejemplo |
|---|---|---|
| 1 | locale en las opciones de la cuadrícula | vGrid({ locale: 'de-AT' }) |
| 2 | El más cercano lang atributo: en el elemento de la cuadrícula o en cualquiera de sus elementos contenedores, hasta llegar a <html> | <section lang="es">, <html lang="de-AT"> |
| 3 | Los idiomas del navegador del lector, en el orden que haya establecido | fr-FR |
| 4 | Ninguna de las anteriores | lang=, se envía vacío |
Las etiquetas se envían con su escritura estándar: pt-br se envía como pt-BR. Un locale que no sea una etiqueta de idioma genera un error, y la cuadrícula consulta el idioma de la página y del navegador. El idioma se lee una sola vez, al crear la cuadrícula; cambiar el lang posterior no lo cambia.
Como el elemento más cercano lang tiene prioridad sobre <html lang>, una misma página puede incluir cuadrículas en distintos idiomas:
<html lang="en">
…
<div id="orders"></div> <!-- sends lang=en -->
<div id="bestellungen" lang="de"></div> <!-- sends lang=de -->
Qué recibe el servidor
| Solicitud | Cuándo lang es |
|---|---|
Filas, GET | cadena de consulta: /api/orders?page=1&lang=de-AT |
Filas, POST | cuerpo JSON: { "page": 1, "lang": "de-AT" } |
| Descarga del servidor | igual que las filas |
| paneles HTML y de texto | cadena de consulta, independientemente del method: /api/order-notes?id=42&lang=de-AT |
| Paneles con cuadrículas anidadas | cadena de consulta o el cuerpo de la solicitud, igual que ocurre con las filas; una cuadrícula anidada siempre usa el idioma de su cuadrícula principal |
La cuadrícula lang reemplaza cualquier otro: un lang ya definido en dataSource o en un panel, y la dataSource, así como la propia ?lang= cuando inheritQueryString está presente. Por el mismo motivo, no uses ese nombre para una columna ni para un externalFilters clave lang: se reemplazaría el valor del filtro.
Léelo en el servidor como cualquier otro parámetro y usa el idioma predeterminado de tu aplicación si está vacío o indica un idioma que no ofreces:
$lang = in_array($request->input('lang'), ['en', 'de', 'fr'], true) ? $request->input('lang') : 'en';
Las cuadrículas locales, con data y sin dataSource, no se envían solicitudes ni datos. Los botones y mensajes propios de la cuadrícula están en inglés.
Véalo en el Ejemplo de productos: la página está en <html lang="en">, así que en la pestaña Red cada solicitud a /api/products, y cada panel que abre, incluye lang=en.
Columnas
columns es un arreglo con un objeto por columna, en el orden de visualización. Cada name es una clave de los objetos de fila.
vGrid({
el: '#orders',
dataSource: '/api/orders',
rowsPerPage: 25,
columns: [
{ name: 'number', label: 'Order', width: 120 },
{ name: 'status', label: 'Status', type: 'enum', options: { paid: 'Paid', due: 'Due' } },
{ name: 'customer', label: 'Customer', type: 'link' }, // href from row.link
{ name: 'notes', label: 'Notes', type: 'html', sort: false, filter: false },
{ name: 'internal_ref', label: 'Ref', active: false } // hidden at start
]
});
Identificación y visualización
| Clave | Admite | Predeterminado | Efecto |
|---|---|---|---|
name | cadena de texto | obligatorio | La clave de la fila que se muestra en esta columna; también se usa para ordenar y filtrar. Nombres reservados detienen la cuadrícula. |
label | cadena de texto | name | Texto del encabezado, marcador del filtro, lista de Ajustes, lista de ordenación externa, CSV y encabezado de impresión. |
type | 'html' | 'enum' | 'link' | texto sin formato | html: el valor se inserta como HTML; la ordenación, el filtrado y el CSV usan su texto. enum: muestra options[value]. link: un enlace a la dirección de href campo si es un valor de tipo / path; http: o https: address; en otros casos, texto sin formato. |
href | nombre del campo de fila | 'link' | Qué campo de la fila contiene la dirección de type: 'link', para que una fila pueda tener varias columnas de enlace. |
options | objeto con los valores value y text | ninguno | La búsqueda para type: 'enum'. La ordenación y el filtrado locales usan el texto mostrado. |
render | (value, row) => text | Node | undefined | ninguno | Determina lo que muestra la celda. El texto se inserta como texto y un nodo DOM se inserta tal cual; undefined usa la visualización normal de esa fila. La ordenación y el filtrado locales usan el valor original; el CSV y la impresión usan el texto renderizado. |
width | number, '120', '120px', o cualquier <th width> valor | automático | Los valores en píxeles establecen el ancho inicial; otros valores (como '20%') dimensiona la columna hasta el primer diseño. |
active | true | false | true | false oculta la columna al inicio; Configuración puede mostrarla. Al menos una columna debe permanecer visible. Los Ajustes guardados tienen prioridad. |
isRowKey | true | false | false | El número de fila la celda muestra el valor de esta columna. Se admite como máximo una; dos detienen la cuadrícula. |
Ordenación y filtrado por columna
| Clave | Admite | Predeterminado | Efecto |
|---|---|---|---|
sort | true | false | true | false desactiva los clics en el encabezado y excluye la columna de la lista de ordenación externa. |
filter | true | false | true | false deja vacía su celda de filtro. |
filterType | 'select' | cuadro de texto | Una lista desplegable creada a partir de filterOptions. |
filterOptions | cadena de texto "value:Text;value:Text" | '' | Opciones de la lista desplegable. Un elemento sin : usa el mismo valor y texto; un valor vacío (":All") significa que no hay filtro y activa el botón ×. |
filterClear | true | false | true | false elimina el botón × de este filtro. |
filterModes | objeto | ninguno | Consultas precisas al servidor para este filtro; consulta Modos de filtro. |
{ name: 'status', label: 'Status', filterType: 'select', filterOptions: ':All;paid:Paid;due:Due' }
Los encabezados se encuentran en tr.vgrid-header, y cada control de filtro lleva vgrid-filter-<name>; todas las clases se enumeran en Nombres de clase de los elementos.
.vgrid-header th { /* every column heading */ }
.vgrid-filter-status { /* the Status filter */ }
Puedes verlos en el Ejemplo de productos: Price tiene modos de filtro; abre Ajustes y muestra Condition para ver un filtro desplegable.
Números de fila
Una columna inicial que numera las filas.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
rowNumbers | true | false | true | Muestra la columna numérica. |
rowNumbersType | 'sequential' | nombre del campo | 'sequential' | sequential cuenta las filas de todas las páginas: la página 2 de 25 empieza en la fila 26. Si se indica el nombre de un campo, se muestra ese valor en su lugar. |
rowNumbersType: 'id', // shows row.id
Una columna con isRowKey: true reemplaza ambos valores. La impresión siempre incluye una columna numérica con estos ajustes. La celda numérica es la primera de cada fila, salvo que antes aparezca el control de subcuadrícula:
.vgrid-row > td:first-child { /* the row numbers */ }
El Ejemplo Ajax números que continúan entre páginas; la opción Ejemplo de productos los desactiva.
Ordenación
Haz clic en un encabezado o enfócalo y pulsa Intro o Espacio para ordenar de forma ascendente; repite la acción para ordenar de forma descendente. El encabezado muestra ▲ o ▼. Mantén pulsada Mayús al activar otro encabezado para añadir una ordenación secundaria; cada encabezado ordenado muestra su prioridad. Cada ordenación vuelve a la página 1. Una cuadrícula remota envía sort y dir, como listas separadas por comas cuando hay más de uno, y el servidor ordena los resultados; una cuadrícula local compara números si ambos valores son numéricos y, en caso contrario, compara el texto mostrado.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
sortBy | { column, order }, o un arreglo de ellos | ninguno | Ordenación inicial. column es el nombre de una columna; order es 'asc' (predeterminado) o 'desc'. Un arreglo establece un criterio principal y sus desempates, en orden. |
externalSort | { column, direction }, cada uno un selector o Element | {} | Los elementos de la página <select> que controlan la ordenación. La cuadrícula completa column con «Ordenar por…» y todas las columnas visibles que se pueden ordenar, y un direction con Ascendente y Descendente. Ambos controles siguen los clics en los encabezados. |
<select id="sort-column"></select>
<select id="sort-direction"></select>
sortBy: { column: 'total', order: 'desc' },
externalSort: { column: '#sort-column', direction: '#sort-direction' },
sortBy: [{ column: 'status' }, { column: 'total', order: 'desc' }], // status, then total within each status
Si un control no está en la página, se registra un error. Los controles de ordenación externa muestran el primer criterio, y sort() reemplaza todos los criterios de ordenación por el que se indique. El encabezado ordenado muestra aria-sort:
.vgrid-header th[aria-sort="ascending"],
.vgrid-header th[aria-sort="descending"] { /* the sorted heading */ }
Pruébelo en el Ejemplo Ajax: haz clic en Code y vuelve a hacer clic.
Filtrado
Tres formas de limitar las filas: la fila de filtros bajo los encabezados, los campos de entrada de la página y los modos de filtro para consultas precisas al servidor.
Fila de filtros
Un cuadro por columna. Una cuadrícula remota envía cada cuadro con contenido como parámetro tras una pausa de 300 ms. Una local conserva las filas cuyo texto visible contiene lo escrito, sin distinguir mayúsculas; los menús desplegables buscan coincidencias exactas con el valor o el texto de la opción.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
filterRow | true | false | true | Muestra la fila de filtros. |
filterClear | true | false | true | Un botón × en cada filtro con contenido; por columna, con columns[].filterClear. Escape también borra un filtro de texto. |
filterRow: false, // no filter boxes
El botón Borrar filtros (Acciones de la barra de herramientas) los vacía todos.
.vgrid-filter { /* the filter row */ }
.vgrid-filter-clear { /* the × buttons */ }
Pruébelo en el Ejemplo local: escribe en Task y pulsa Escape.
Filtros externos
Los campos de entrada de tu página, que se envían con cada solicitud como name=value cuando tienen un valor. Solo para cuadrículas remotas.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
externalFilters | objeto con el nombre name: selector o Element | {} | La cuadrícula se recarga cuando cambia el change evento. Borrar filtros los devuelve a sus valores iniciales. |
<select id="region">
<option value="">All regions</option>
<option value="eu">Europe</option>
</select>
<input type="date" id="from">
externalFilters: { region: '#region', from_date: '#from' }, // region=eu&from_date=2026-01-01
Un campo de texto activa change al pulsar Intro o al perder el foco. Los nombres siguen las reglas de nombres reservados regla; si un campo de entrada no está en la página, se registra un error y se omite. Los campos y sus estilos son tuyos.
Consulte la Ejemplo de productos: Categories, Brand y Have Sales son filtros externos.
Modos de filtro
Un botón de modo dentro de un filtro de texto cambia el parámetro enviado, para que el servidor ejecute consultas precisas (igual a, empieza por, entre) en lugar de una búsqueda «contiene». Solo en cuadrículas remotas y filtros de texto.
{
name: 'price',
label: 'Price',
filterModes: {
price_equals: { label: 'Equals', symbol: '=' },
price_above: 'Higher than',
range: { keys: ['price_from', 'price_to'], label: 'Between', symbol: '↔' }
}
}
Escribir 25 en Igual a envía price_equals=25; Entre muestra los cuadros «desde» y «hasta» y envía cada uno con contenido bajo su propia clave.
| Clave | Admite | Predeterminado | Efecto |
|---|---|---|---|
filterModes.<param> | etiqueta, o { label, symbol, value } | ninguno | Un modo que envía <param>. |
filterModes.<param>.label | texto, cadena HTML o Element | el nombre del parámetro | Texto del menú y ayuda emergente del botón. |
filterModes.<param>.symbol | cadena de texto | ninguno | Símbolo del botón y del menú; si se omite, el botón muestra la primera letra de la etiqueta. |
filterModes.<param>.value | non-empty text or number | ninguno | Makes it a one-click mode that sends this value; see One-click modes. |
filterModes.range | { keys, label, symbol } | ninguno | Dos cuadros: «desde» y «hasta». |
filterModes.range.keys | dos nombres de parámetro distintos | obligatorios para range | Se envía para «desde» y «hasta». |
filterModes.range.label | texto, cadena HTML o Element | las claves, from – to | Texto del menú y ayuda emergente del botón. |
filterModes.range.symbol | cadena de texto | ninguno | Como se indicó arriba. |
Primero aparece el modo «Contiene» (≈), que envía el nombre de la columna, salvo que una clave coincida con ese nombre. Con menos de dos modos no aparece el botón. Al cambiar de modo se conserva el texto escrito y se recarga la cuadrícula si el filtro tenía contenido; Borrar filtros devuelve cada filtro a su primer modo.
One-click modes
A mode with a value needs no typing: choosing it reloads the grid at once and sends <param>=<value>. Use it for questions a text box can't ask, such as rows with no date.
{
name: 'due_date',
label: 'Due',
filterModes: {
due_date_empty: { label: 'No date', symbol: '∅', value: '1' },
due_date_set: { label: 'Has a date', symbol: '✓', value: '1' }
}
}
Choosing No date sends due_date_empty=1; any text typed in the filter is dropped. The filter box then shows "No date" and can't be typed in.
- Click the box, or press Enter, Space or Down arrow in it, to open the mode menu and pick another mode.
- Clear filters, the × button, or Escape in the box returns the filter to its first mode and reloads. With
filterClear: falsethere is no × and Escape does nothing.
Your server decides what the parameter means. For "no date" on a column that can hold NULL or an empty string, match both:
WHERE due_date IS NULL OR due_date = ''
Se ignoran y se registra un error en la consola los modos sin dataSource, en un filtro desplegable, con un valor vacío o con una clave reservada key, a range without two different keys, or a value that is empty or set on a range (Solución de problemas).
.vgrid-filter-mode { /* the mode button */ }
.vgrid-filter-mode-menu { /* the menu */ }
.vgrid-filter-mode-item { /* one menu entry */ }
.vgrid-filter-mode-symbol { /* the symbol inside an entry */ }
.vgrid-filter-fixed { /* the read-only box of a one-click mode */ }
Pruébelo en el Ejemplo de productos: haz clic en el botón de modo del filtro Price y selecciona Between.
Paginación
Para grandes volúmenes de datos, establece siempre rowsPerPage: sin este valor no hay paginación y se solicitan todas las filas al servidor.
Tamaño de página
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
rowsPerPage | número positivo | 0, sin paginación; 10 con externalPagination o externalRowsPerPage | Filas por página, enviadas como limit. |
rowsPerPageOptions | arreglo de números positivos | automático | Opciones de «Mostrar N filas»; rowsPerPage siempre se incluye. En modo automático: 5 y 10 para un máximo de 10 filas; 10, 20 y 50 para un máximo de 50; en los demás casos, 20, 40, 50 y 100, según los datos locales o cada respuesta remota total. Necesita rowsPerPage. |
rowsPerPage: 25, // limit=25
rowsPerPageOptions: [25, 50, 100, 500],
Barras de paginación
Con rowsPerPage configurado, aparece una barra encima y debajo de la tabla: «Mostrando 26–50 de 1834», el paginador (« ‹ 1 2 3 … › ») y «Mostrar N filas». En una cuadrícula estrecha, la barra se apila y el paginador muestra menos números de página.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
showPaginationControls | true | false | true | Valor predeterminado para las dos opciones siguientes. |
showPagination | true | false | showPaginationControls | El recuento y la paginación. |
showRowsPerPage | true | false | showPaginationControls | "Show N rows". |
showRowsPerPage: false, // keep the pager, drop the page-size choice
.vgrid-pagination-bar { /* each bar */ }
.vgrid-pagination-bar[data-vgrid-stacked] { /* a bar stacked on a narrow grid */ }
.vgrid-count { /* Showing X–Y of Z */ }
.vgrid-pager button[aria-current="page"] { /* the current page */ }
.vgrid-rows-per-page { /* Show N rows */ }
Vea las barras en el Ejemplo Ajax.
Paginación externa
Coloca el recuento, el paginador y la selección del tamaño de página en tus propios elementos.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
externalPagination | selector, elemento, matriz o NodeList | ninguno | El contenido de cada contenedor se sustituye por el recuento y el paginador. Un selector incluye todos los elementos que coincidan. |
externalRowsPerPage | selector, elemento, matriz o NodeList | ninguno | Su <select> elementos que establecen el tamaño de página y se mantienen sincronizados entre sí y con la cuadrícula; si falta un tamaño, se añade como opción. |
<div class="pager-top"></div>
<select id="page-size"><option>25</option><option>50</option></select>
rowsPerPage: 25,
showPaginationControls: false, // no built-in bars
externalPagination: '.pager-top',
externalRowsPerPage: '#page-size',
Si un elemento no está en la página, se registra un error. Consulta Ejemplo de productos: los paginadores superior e inferior son externos; cambia «Mostrar» en cualquiera de ellos.
Apariencia
Líneas, tamaño del texto, sombreado y movimiento. Los colores provienen de tu página; consulta Estilos y nombres de clase.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
borders | 'all' | 'horizontal' | 'rows' | 'inner' | 'none' | 'horizontal' | all: un marco y todas las líneas. horizontal: un marco y líneas entre filas. rows: líneas encima, entre y debajo de las filas, sin bordes exteriores. inner: solo líneas entre filas. none: sin líneas. |
size | 'smallest' | 'small' | 'medium' | 'large' | 'larger' | 'largest' | 'medium' | El tamaño inicial del texto, de 0,75 a 1,5 veces el de la página. Los botones A− y A+ recorren los tamaños y guardan la selección en este navegador. |
striped | true | false | true | Sombrea una fila sí y otra no. |
hover | true | false | true | Resalta la fila bajo el puntero. |
rowClass | row => string | ninguno | Clases que se añaden a cada fila según sus datos; si se devuelve un valor vacío, no se añade ninguna. |
easing | milisegundos | 160 | Duración de las animaciones de paneles, menús y movimientos de columnas; 0 desactiva las animaciones. |
borders: 'all',
size: 'small',
striped: false,
easing: 0,
Un valor desconocido genera un error y se usa el predeterminado. Cada opción establece un hook en .vgrid-wrapper (Hooks configurados mediante opciones):
.vgrid-wrapper[data-vgrid-borders="all"] { /* grids with every line */ }
.vgrid-wrapper[data-vgrid-size="small"] { /* grids at size small */ }
Consulte la Ejemplo de productos, establecido en borders: 'horizontal' y size: 'small'; pruebe A− y A+ en su barra de herramientas.
Cambio de tamaño y orden de columnas
Cambio de tamaño
Arrastra la línea entre dos encabezados o dos cuadros de filtro para cambiar el tamaño. Las columnas de la derecha ceden o absorben el espacio, y ninguna se estrecha por debajo de 40 px; si las columnas de la derecha ya no tienen espacio, la tabla se amplía. Siempre está activado; no hay ninguna opción. El puntero cambia al cursor de redimensionamiento al pasar sobre una línea.
Cuando las columnas no caben en el ancho disponible, la cuadrícula se desplaza horizontalmente en lugar de reducirlas por debajo de 40 px; el área desplazable puede recibir el foco y moverse con las flechas.
Sin ratón: selecciona un encabezado y pulsa Alt+Flecha derecha para ampliarlo o Alt+Flecha izquierda para reducirlo en 10 px; también puedes usar los botones − y + junto a cada columna en Configuración.
Cambio de orden
Mantén pulsado un encabezado y arrástralo a otra posición; un marcador indica dónde quedará. Si mueves el puntero antes de que termine el tiempo de espera, se cancela el arrastre y un clic normal sigue ordenando la columna.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
reorderColumns | true | false | true | Permite mover columnas. Escape cancela el arrastre. |
reorderDelay | milisegundos | 350 | Cuánto tiempo hay que mantener pulsado antes de iniciar el arrastre. |
reorderDelay: 600, // a longer hold, for touch screens
Sin ratón, los botones ↑ y ↓ junto a cada columna en Configuración la mueven una posición. El nuevo orden se conserva hasta que se recarga la página; Configuración → Guardar lo guarda. Se necesitan al menos dos columnas visibles.
.vgrid-column-ghost { /* the heading being dragged */ }
.vgrid-column-marker { /* the drop line */ }
[data-vgrid-drag-source] { /* the column's cells during the drag */ }
[data-vgrid-dropped] { /* the column's cells just after the drop */ }
Pruebe ambas opciones en la Ejemplo Ajax: arrastra la línea entre Code y Name, luego mantén pulsado Name y muévelo a la izquierda.
Acciones de la barra de herramientas
Un grupo de botones, situado por defecto a la derecha de la fila del título: Borrar filtros ✕, Descargar ⤓, Imprimir ⤒, Actualizar ↻, Ajustes ⚙ y A− / A+ para el tamaño del texto.
Activación de funciones
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
settings | true | false | true | El ventana emergente de configuración, además de Borrar filtros y Actualizar. |
download | true | false | 'server' | 'view' | false | 'server': el servidor envía todos los resultados filtrados en un archivo. 'view': un CSV generado en el navegador. true: server con un dataSource, de lo contrario view; 'server' sin un dataSource usa como alternativa view. |
print | true | false | true | Imprime las filas visibles como una tabla sencilla. |
externalSettings | selector o Element | ninguno | Nombre anterior de actions.element. |
download: 'server',
print: false,
La descarga del servidor repite la solicitud actual (filtros, ordenación, columnas visibles, página y límite) con download=true, y guarda el archivo que se reciba. Ignore page y limit para enviar todos los resultados, en cualquier formato; asigna al archivo el nombre indicado en Content-Disposition:
HTTP/1.1 200 OK
Content-Type: text/csv
Content-Disposition: attachment; filename="orders.csv"
Si no se especifica un nombre de archivo, la cuadrícula usa <namespace>-<date> y una extensión de Content-Type. El botón se desactiva mientras se carga el archivo; si falla, la cuadrícula muestra el error como cualquier respuesta defectuosa.
Un CSV del navegador ('view') usa las etiquetas de columna como encabezados y el texto mostrado de cada celda. Una cuadrícula local exporta todas las filas filtradas; una remota exporta la página visible. La impresión siempre incluye la página visible.
El grupo de botones
actions acepta true (la fila de título), false (sin botones), una cadena de posición o un objeto:
| Clave | Admite | Predeterminado | Efecto |
|---|---|---|---|
position | 'caption' | 'bottom' | 'none' | 'external' | 'caption' | bottom: una fila debajo de la tabla. external necesita element; sin ella, los botones permanecen en el título. |
element | selector o Element | ninguno | El contenedor de los botones; su contenido se sustituye. Si se configura, tiene prioridad sobre position. |
order | matriz de nombres de acciones | ['clear', 'download', 'print', 'refresh', 'settings', 'textSize'] | Primero las acciones indicadas; las demás, en el orden predeterminado. |
clear | valor de la acción | sigue settings | Clear filters ✕. |
download | valor de la acción, 'server' o 'view' | sigue download | Descargar ⤓; reemplaza la opción de nivel superior download. |
print | valor de la acción | sigue print | Imprimir ⤒. |
refresh | valor de la acción | sigue settings | Actualizar ↻: vuelve a cargar las filas remotas o redibuja las locales. |
settings | valor de la acción | sigue settings | Configuración ⚙. |
textSize | true | false | objeto | true | A− y A+. |
actions: {
element: '#toolbar', // your container
order: ['refresh', 'download'],
download: 'server',
print: false
},
Una clave desconocida o un nombre de acción no reconocido genera un error en la consola.
Valores de las acciones
Cada acción acepta true, false, una cadena (su símbolo) o un objeto:
| Clave | Admite | Predeterminado | Efecto |
|---|---|---|---|
active | true | false | true cuando se proporciona el objeto | false oculta el botón. |
symbol | cadena de texto | ✕ ⤓ ⤒ ↻ ⚙ | El texto del botón. |
title | cadena de texto | «Borrar filtros», «Descargar», «Imprimir», «Actualizar» y «Ajustes» | La ayuda emergente. |
html | cadena HTML o elemento | ninguno | El contenido del botón, insertado como HTML; tiene prioridad sobre symbol. |
className | cadena de texto | ninguno | Clases del botón. |
mode | 'server' | 'view' | 'server' con un dataSource, de lo contrario 'view' | download solamente. |
decrease, increase | cadena de texto | A−, A+ | textSize solamente: los textos de los botones. |
decreaseTitle, increaseTitle | cadena de texto | "Smaller text", "Larger text" | textSize solamente: las ayudas emergentes. |
textSize acepta active y className también.
actions: {
refresh: { title: 'Reload orders', className: 'btn btn-sm btn-outline-secondary' },
clear: '⌫', // a symbol
textSize: { decrease: 'a', increase: 'A' }
},
Ventana de ajustes y opciones guardadas
Ajustes muestra las columnas con una casilla cada una. Aplicar mantiene la selección hasta que se recarga la página; Guardar también la recuerda en este navegador, junto con el orden de las columnas. Debe quedar al menos una columna seleccionada. Las opciones guardadas prevalecen sobre columns[].active, y las columnas ocultas se envían al servidor como columns.
Junto a cada columna, ↑ y ↓ la mueven una posición, y − y + cambian su ancho en 10 px ; los cambios se aplican de inmediato y el ancho se conserva hasta recargar la página.
Las opciones se guardan en localStorage en vgrid:<el>:<dataSource>:columns, y el tamaño del texto en …:textSize; <el> es el el selector o el id del elemento. Cambie el o dataSource y las opciones anteriores dejan de aplicarse. Para olvidarlas:
localStorage.removeItem('vgrid:#orders:/api/orders:columns');
.vgrid-actions { /* the button group */ }
.vgrid-settings { /* the popup */ }
.vgrid-settings-actions { /* Apply and Save */ }
.vgrid-settings-close { /* the × in the popup */ }
Consulte la Ejemplo de productos: sus botones están en la barra de herramientas de la página. Abre Ajustes, marca Category, pulsa Guardar y recarga la página.
Subcuadrículas: paneles de detalle por fila
Cada subcuadrícula añade una columna de alternancia. Al abrir el control de una fila, se carga el panel desde el servidor: se envía una solicitud por fila abierta, por lo que los datos de detalle solo se consultan cuando alguien los necesita.
vGrid({
el: '#orders',
dataSource: '/api/orders',
rowsPerPage: 25,
columns: [{ name: 'number', label: 'Order' }, { name: 'total', label: 'Total' }],
subgrid: {
panels: [
{
name: 'items', label: 'Items', id: 'id', type: 'grid',
dataSource: '/api/order-items',
columns: [{ name: 'sku', label: 'SKU' }, { name: 'qty', label: 'Qty' }]
},
{ name: 'notes', label: 'Notes', id: 'id', type: 'html', dataSource: '/api/order-notes' }
]
}
});
Para la fila con id 42, Items solicita /api/order-items?id=42 con los parámetros de paginación habituales y espera la respuesta habitual respuesta; Notes solicita /api/order-notes?id=42 e inserta la respuesta como HTML.
Si solo hay un panel disponible, el control (+ / -) lo abre directamente; si hay varios, ⋮ abre un menú con ellos y la opción Ocultar. Cada fila muestra un panel a la vez: abrir otro sustituye al actual. Los paneles de más de 400 px tienen desplazamiento.
Grupo de subcuadrículas
subgrid es un objeto o un arreglo de objetos; cada uno añade su propia columna de alternancia.
| Clave | Admite | Predeterminado | Efecto |
|---|---|---|---|
panels | matriz de objetos de panel | obligatorio | Los paneles que ofrece este control. Se descarta cualquier grupo que no tenga un panel válido. |
position | 'start' | 'end' | número de columna | 'start' | Dónde aparece la columna de alternancia; las celdas se cuentan desde la izquierda, empezando por 1. |
single | true | false | false | true mantiene abierto un solo panel en toda la cuadrícula. |
open | true | nombre del panel | ninguno | La opción que recibe el foco primero en el menú (true: la primera). No abre nada por sí sola. |
el | cadena HTML | + / -, ⋮ para un menú | Tu propio marcado para la alternancia; se utiliza el primer elemento y se convierte en un botón accesible con el teclado. |
method | 'GET' | 'POST' | 'GET' | El valor predeterminado para cada panel. |
headers | objeto | de la cuadrícula headers | El valor predeterminado para cada panel. |
rowsPerPage | número positivo | 10 | El valor predeterminado para cada panel de cuadrícula. |
externalFilters | objeto con el nombre name: selector o Element | ninguno | El valor predeterminado para cada panel. |
subgrid: [
{ position: 'start', panels: [/* … */] },
{ position: 'end', single: true, el: '<button type="button">Details</button>', panels: [/* … */] }
],
Paneles
| Clave | Admite | Predeterminado | Efecto |
|---|---|---|---|
name | cadena de texto | obligatorio | La identidad del panel; la usa open. |
label | cadena de texto | name | El texto del menú, la ayuda emergente del interruptor y los mensajes. |
id | nombre del campo de fila | obligatorio | El campo de la fila cuyo valor se envía. Las filas sin valor no muestran el control de este panel. |
dataSource | URL | obligatorio | Se solicita como dataSource?id=<value>. |
idInPath | true | false | false | Solicitudes dataSource/<value> en su lugar. |
type | 'grid' | 'html' | texto sin formato | grid: una cuadrícula anidada. html: la respuesta se inserta como HTML. Si se omite, se muestra como texto. |
caption | cadena HTML | false | ninguno | Un encabezado sobre el contenido; el botón × para cerrar siempre está disponible. |
method | 'GET' | 'POST' | del grupo; de lo contrario, 'GET' | |
headers | objeto | del grupo; de lo contrario, de la cuadrícula | |
externalFilters | objeto con el nombre name: selector o Element | del grupo | Los campos de entrada de la página, que se añaden a la solicitud del panel cuando se abre. |
Un panel sin name, id o dataSource se descarta y se registra un error en la consola. Mientras carga, el panel muestra «Cargando…»; si la respuesta está vacía, muestra «No hay nada que mostrar para Notes.»; si falla, muestra «No se pudo cargar Notes: el servidor respondió con el error 500.»
Paneles con cuadrículas anidadas
A type: 'grid' el panel es una cuadrícula remota en la URL del panel: su servidor recibe id más page, limit, sort, dir y filtros. Estas claves se aplican solo a los paneles de cuadrícula:
| Clave | Predeterminado |
|---|---|
columns | [], con cada clave de columna |
rowsPerPage | del grupo; de lo contrario, 10 |
rowNumbers, rowNumbersType, borders, striped, hover, easing, reorderColumns, reorderDelay | el valor de la cuadrícula principal |
size | 'medium', no heredado |
Las cuadrículas anidadas no tienen ajustes ni barra de herramientas, y comparten el namespace.
Herencia de la cadena de consulta
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
inheritQueryString | true | false | false | Añade la cadena de consulta de la página a cada solicitud del panel; si un parámetro ya está en la URL del panel, prevalece ese valor. Las solicitudes de la cuadrícula principal no cambian. |
inheritQueryString: true, // on /orders?tenant=7, panels request /api/order-items?tenant=7&id=42
.vgrid-toggle-subgrid { /* every toggle */ }
.vgrid-toggle-subgrid-2 { /* the second group's toggles */ }
.vgrid-panel-menu { /* the panel menu */ }
.vgrid-subgrid-body { /* an open panel */ }
.vgrid-subgrid-caption { /* its heading and × */ }
.vgrid-panel-error { /* a panel that failed */ }
Vea ambos tipos en la Ejemplo de productos: el signo + al principio de una fila abre Resumen, un panel HTML solicitado como /api/products/summary/<id> (idInPath); la flecha ↗ del final abre Sales, una cuadrícula anidada.
Interacción con las filas
Opciones para que los lectores interactúen con una fila o copien su contenido. Todas están desactivadas de forma predeterminada.
Clic y doble clic en filas
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
onRowClick | función | ninguno | Se llama con { row, event } cuando se hace clic en una fila o se pulsa Intro o Espacio con una fila enfocada. |
onRowDblClick | función | ninguno | Se llama con { row, event } con un doble clic o al pulsar Mayús+Intro en una fila enfocada. |
onRowClick: ({ row }) => location.assign('/orders/' + row.id),
Los clics en botones, enlaces o controles de formulario dentro de la fila no cuentan. Si cellSelection está activado, las teclas funcionan desde una celda enfocada en lugar de desde la fila.
Acciones de fila
Botones al final de cada fila, dentro de una columna titulada Acciones.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
rowActions | arreglo de acciones o una función que recibe la fila y devuelve uno | false | Añade la columna Acciones. Una función decide qué botones aparecen en cada fila. |
| Clave de acción | Admite | Predeterminado | Efecto |
|---|---|---|---|
label | texto | 'Action' | El texto del botón. |
name | texto | la etiqueta | Identifica la acción: se establece como data-vgrid-row-action en el botón y se pasa a onClick. |
onClick | función | obligatorio | Se llama con { row, event, grid, name }; grid es el instancia. |
ariaLabel | texto | la etiqueta | El nombre accesible, para etiquetas con iconos. |
disabled | true | false | false | Muestra el botón deshabilitado. |
rowActions: row => [
{ name: 'open', label: 'Open', onClick: ({ row }) => location.assign('/orders/' + row.id) },
{ name: 'void', label: 'Void', disabled: row.status === 'void',
onClick: ({ row, grid }) => fetch('/api/orders/' + row.id + '/void', { method: 'POST' }).then(() => grid.reload()) },
],
.vgrid-row-actions { /* the Actions cell */ }
[data-vgrid-row-action="void"] { /* one action's button */ }
Reordenación de filas
Una columna después de las columnas de datos, con botones ↑ y ↓ para mover una fila una posición.
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
rowReorder | true | false | false | Añade la columna de orden de filas. |
onRowReorder | función | ninguno | Se llama con { row, from, to, rows } después de mover una fila; from y to recuento que empieza en 0 y abarca todo el conjunto de datos, rows es la página actual. Es obligatorio en una cuadrícula remota, donde el servidor guarda el orden. |
rowReorder: true,
onRowReorder: ({ row, to }) => fetch('/api/queue/' + row.id + '/position', { method: 'PUT', body: String(to) }),
Una cuadrícula local mueve la fila en sus propios datos. Los botones se desactivan mientras haya un filtro u ordenación activos.
.vgrid-row-reorder { /* the Row order cell */ }
[data-vgrid-row-reorder="up"], [data-vgrid-row-reorder="down"] { /* the two buttons */ }
Selección y copia de celdas
| Opción | Admite | Predeterminado | Efecto |
|---|---|---|---|
cellSelection | true | false | false | Las celdas pueden recibir el foco: las flechas permiten moverse entre ellas, Mayús más una flecha amplía la selección y Ctrl+C o Comando+C copia el rango como texto separado por tabulaciones. No se admite pegar. |
cellSelection: true,
Al hacer clic en una celda, se selecciona; los clics en botones y enlaces dentro de una celda no cambian la selección. Solo se copian las columnas visibles.
.vgrid [aria-selected="true"] { /* a selected cell */ }
Eventos
Funciones que la cuadrícula llama cuando ocurren eventos. Cada una recibe un objeto; se ignora el valor devuelto.
| Opción | Se llama cuando | Argumento |
|---|---|---|
onReady | las filas están en pantalla: después de cada renderizado local, de cada carga remota o cuando falla una carga remota | { total, rows }: filas coincidentes y filas visibles; o { error } |
onSort | cambia la ordenación: un encabezado, la ordenación externa o sort() | { column, order } para la primera ordenación; también con una ordenación secundaria sorts: [ { column, order } ] en orden de prioridad |
onFilter | cambia un filtro o se ejecuta Borrar filtros. Solo para cuadrículas locales; en una remota, usa onReady | { filters: [ { column, value } ] } |
onPage | se muestra una página, cuando rowsPerPage está definido | { page, rowsPerPage, total } |
onRowClick, onRowDblClick | se hace clic o doble clic en una fila, o se pulsa Intro, Espacio o Mayús+Intro en una fila enfocada. Consulta Clic y doble clic en filas | { row, event } |
onRowReorder | el botón ↑ o ↓ de una fila la mueve. Consulte Reordenación de filas | { row, from, to, rows } |
vGrid({
el: '#orders',
dataSource: '/api/orders',
rowsPerPage: 25,
columns: [{ name: 'number', label: 'Order' }, { name: 'total', label: 'Total' }],
onReady: ({ total, error }) => {
document.querySelector('#order-count').textContent = error ? 'unavailable' : total;
},
onPage: ({ page }) => history.replaceState(null, '', '?page=' + page)
});
API de la instancia
vGrid() devuelve un objeto para cambios posteriores. Consérvelo.
| Miembro | Efecto |
|---|---|
element | La cuadrícula <table>. |
config | El objeto que proporcionó. |
reload(rows?) | Vuelve a la página 1: una cuadrícula remota vuelve a cargar los datos; una local se vuelve a dibujar y acepta filas nuevas si pasas un arreglo. |
setPage(n) | Muestra la página n, 1 o más. Una cuadrícula local se detiene en su última página; en una remota, el servidor page que determina la respuesta. |
sort(column, order = 'asc') | Ordena por una columna visible; cualquier otro nombre genera una advertencia. |
destroy() | Elimina los escuchadores, las solicitudes, los paneles y el marcado de la cuadrícula. Un <table> el permanece vacío. |
const grid = vGrid({ /* … */ });
document.querySelector('#refresh').addEventListener('click', () => grid?.reload());
grid?.sort('total', 'desc').setPage(3); // reload, setPage and sort chain
grid?.destroy(); // when the grid leaves the page
vGrid() devuelve null, con un error en la consola, cuando el no encuentra nada, una columna o un filtro externo usa un nombre reservado, dos columnas establecen isRowKey, o todas las columnas están ocultas. Por eso ?. anterior.
Estilos y nombres de clase
vgrid.css se ocupa únicamente de la disposición; los colores y las fuentes provienen de la página. Personaliza la cuadrícula con los hooks, variables y clases siguientes.
#orders {
--vgrid-border-color: #c9d1d9;
--vgrid-hover-color: #fff8e1;
}
#orders .vgrid-caption { /* the Orders grid's caption only */ }
Hooks configurados mediante opciones
| Opción | Evento |
|---|---|
borders | data-vgrid-borders="all | horizontal | rows | inner | none" en .vgrid-wrapper |
size | data-vgrid-size="smallest | small | medium | large | larger | largest" en .vgrid-wrapper |
striped | data-vgrid-striped en .vgrid-wrapper; las filas sombreadas llevan data-vgrid-stripe |
hover | data-vgrid-hover en .vgrid-wrapper |
reorderColumns | data-vgrid-reorder en .vgrid-wrapper |
onRowClick, onRowDblClick | data-vgrid-clickable en cada tr.vgrid-row |
cellSelection | aria-selected="true" en las celdas seleccionadas |
easing | --vgrid-easing: <easing>ms en .vgrid-wrapper |
namespace | <namespace>-<part> junto a cada vgrid-<part> clase |
Variables CSS
Configúralas en tu CSS, en el contenedor de la cuadrícula o en cualquiera de sus elementos antecesores; no son vGrid({ … }) opciones.
| Variable | Predeterminado | Afecta a |
|---|---|---|
--vgrid-border-color | #dee2e6 | Líneas, marcos y bordes de ventanas emergentes |
--vgrid-border-width | 1px | Todas las líneas |
--vgrid-border-h | --vgrid-border-width | Líneas entre filas |
--vgrid-border-v | --vgrid-border-width; 0 en horizontal, rows, inner | Líneas entre columnas |
--vgrid-border-radius | .25rem | Esquinas del marco y de las ventanas emergentes |
--vgrid-font-size | establecido por size, .75em a 1.5em | Texto de la cuadrícula; puedes reemplazarlo con una regla más específica que .vgrid-wrapper[data-vgrid-size] |
--vgrid-hover-color | rgba(128, 128, 128, .18) | La fila bajo el puntero |
--vgrid-stripe-color | rgba(128, 128, 128, .07) | Filas sombreadas |
--vgrid-popup-background | Canvas | Configuración, menús e indicador de carga |
--vgrid-popup-shadow | 0 .4em 1.4em rgba(0, 0, 0, .18) | Configuración, menús e indicador de carga |
--vgrid-drag-shadow | una sombra suave de dos capas | El encabezado que se está arrastrando |
--vgrid-drop-color | el color de énfasis del sistema, atenuado | El breve resaltado de la columna movida después de soltarla |
--vgrid-scrollbar-color | el color del texto, atenuado | Barras de desplazamiento de Configuración, menús y paneles |
--vgrid-subgrid-max-height | 400px | La altura a partir de la cual un panel se desplaza |
Nombres de clase de los elementos
Cada clase de abajo también está disponible como <namespace>-<part>, salvo los cinco nombres fijos del final de la tabla.
| Clase | Elemento |
|---|---|
vgrid-caption | La fila de título |
vgrid-actions | El grupo de botones en la fila de título o en la inferior |
vgrid-actions-row | La fila inferior que contiene los botones |
vgrid-settings, vgrid-settings-close, vgrid-settings-title, vgrid-settings-list, vgrid-settings-actions | La ventana de Ajustes, su ×, su encabezado, la lista desplazable de columnas y sus botones Aplicar y Guardar |
vgrid-header | La fila de encabezados |
vgrid-filter | La fila de filtros |
vgrid-filter-<name> | El campo o menú desplegable de filtro de una columna |
vgrid-filter-clear | El botón × de un filtro |
vgrid-filter-moded | Un filtro con modos, botón y campos |
vgrid-filter-mode, vgrid-filter-mode-<name> | El botón de modo |
vgrid-filter-mode-menu, vgrid-filter-mode-item, vgrid-filter-mode-symbol | El menú de modos, una opción y su símbolo |
vgrid-filter-fixed | The read-only box of a one-click mode |
vgrid-row | Una fila de datos; con un espacio de nombres y row.id, también <namespace>-row-<id> |
vgrid-row-actions, vgrid-row-reorder | La celda de Acciones de una fila y su celda de Orden de fila; los botones usan data-vgrid-row-action="<name>" y data-vgrid-row-reorder="up | down" |
vgrid-empty | La fila "No records to show." |
vgrid-loading-space | Espacio para el indicador de carga cuando no hay filas |
vgrid-pagination, vgrid-pagination-bar | Una fila de paginación y su barra |
vgrid-count, vgrid-pager, vgrid-pager-ellipsis, vgrid-rows-per-page | «Mostrando X–Y de Z», el paginador, su … y «Mostrar N filas» |
vgrid-toggle-column | El <col> de una columna de interruptor de subcuadrícula |
vgrid-toggle-subgrid, vgrid-toggle-subgrid-<n> | Un interruptor; n cuenta los grupos desde 1 |
vgrid-panel-menu, vgrid-panel-menu-<n>, vgrid-panel-menu-item | El menú del panel y sus opciones |
vgrid-subgrid-cell, vgrid-subgrid-slide, vgrid-subgrid-clip, vgrid-subgrid-body | Un panel abierto, de afuera hacia adentro |
vgrid-subgrid-caption, vgrid-subgrid-title, vgrid-subgrid-close | La barra de encabezado de un panel, su texto y su × |
vgrid-panel-loading, vgrid-panel-empty, vgrid-panel-error, vgrid-panel-text | Los mensajes de un panel y una respuesta de texto sin formato |
vgrid-column-ghost, vgrid-column-marker | El encabezado arrastrado y la línea de destino |
vgrid | El <table>; fijo |
vgrid-wrapper | El elemento que rodea la tabla; fijo |
vgrid-loading-badge, vgrid-loading-error | El indicador de carga y el indicador de error; nombres fijos |
vgrid-spinner, vgrid-loading-text | El indicador giratorio y el texto de la insignia; fijo |
Teclado y accesibilidad
Funciones que se pueden usar sin ratón y lo que oyen las tecnologías de asistencia.
- Menús (modos de filtro y paneles de subcuadrícula): las flechas arriba y abajo permiten moverse, Inicio y Fin saltan al principio o al final, y Escape cierra el menú; el menú de modos de filtro devuelve el foco a su botón.
- Interruptores de subcuadrícula: Enter o Space; el contenido personalizado
subgrid.else puede enfocar medianterole="button". - Filtros: Escape borra un filtro de texto. Arrastre de columnas: Escape cancela la acción.
- Ordenación: pulsa Intro o Espacio en un encabezado; con Mayús se añade un criterio secundario.
- Filas y celdas: con
onRowClick, Enter, Space y Shift+Enter en una fila; concellSelection; las flechas permiten moverse entre celdas y Ctrl+C o Comando+C copia la selección. - Anunciado:
aria-sorten el encabezado ordenado,aria-expandeden los interruptores,aria-currenten la página actual, el paginador con etiqueta, los botones para borrar y cerrar, y los mensajes de carga y error mediante una región dinámica. - Columnas: Alt+Flecha izquierda o Alt+Flecha derecha sobre un encabezado enfocado cambia su tamaño; los botones ↑ ↓ − + en Configuración mover y cambiar el tamaño de cualquier columna.
- Si el sistema operativo tiene activada la reducción de movimiento, las transiciones de la cuadrícula son más breves;
easing: 0los desactiva.
externalSort: { column: '#sort-column', direction: '#sort-direction' }, // keyboard sorting
Seguridad
Qué contenido inserta la cuadrícula como HTML y qué protege, para que sepas qué debe limpiar el servidor.
- Insertado como HTML, por lo que debe escapar cualquier dato de usuario incluido:
caption,type: 'html'celdas,type: 'html'respuestas de panel, etiquetas de panelcaption,subgrid.el,filterModesy etiquetas de acciónhtml. Todo lo demás se inserta como texto. - Enlaces:
type: 'link'solo crea enlaces a rutas que empiezan con una sola/, y ahttp:yhttps:direcciones; cualquier otra cosa, comojavascript:o//other.host, se muestra como texto. Un nodo devuelto porrenderes suyo: lo que coloque dentro se inserta tal cual. - CSV: las celdas que empiezan con
=,+,@, un tabulador o un-que no sea un número reciben delante', para que las hojas de cálculo no las ejecuten como fórmulas. - Encabezados:
headersse envían con cada solicitud de cuadrícula o panel, incluso a otros orígenes; Token CSRF solo se envía al mismo origen.
{ "data": [ { "notes": "<b>Paid</b> by <script>" } ] }
Arriba: un type: 'html' la celda conserva la etiqueta de negrita y muestra el texto del usuario tal como se escribió, porque el servidor lo escapó.
Solución de problemas
Cada mensaje que la cuadrícula escribe en la consola del navegador, su causa y cómo resolverlo. Los mensajes marcados detiene significa vGrid() devuelto null.
| Mensaje | Causa y solución |
|---|---|
| Configuración inicial | |
vGrid: "el" must identify an element. detiene | El selector no encontró ningún elemento. Ejecute vGrid() cuando el elemento ya exista. Montaje |
vGrid: autoDestroy must be true or false. | Use un valor booleano. Montaje |
vGrid: borders must be one of …, size must be one of …, striped / hover must be true or false., easing must be a duration … | Se usa el valor predeterminado. Apariencia |
vGrid: locale must be a language tag such as "en" or "de-AT". | La cuadrícula usa el idioma de la página o del navegador. Usa una etiqueta como 'de' o 'de-AT'. Idioma |
| Datos y servidor | |
vGrid fetch error: con el motivo | Falló una solicitud; la cuadrícula también muestra el motivo. Respuestas defectuosas |
vGrid: external summary target for "…" was not found. | Corrija el selector. Totales del servidor |
vGrid: reload() expects an array of rows. | Proporcione una matriz o nada. API de la instancia |
| Columnas | |
vGrid: column name(s) … are reserved for remote API controls. detiene | Cambie el nombre de la columna o del filtro externo. Nombres reservados |
vGrid: only one column can use isRowKey: true. detiene | Manténgalo en una sola columna. Columnas |
vGrid: render on column "…" must be a function., … must return text or a DOM node., … failed: … | La celda muestra el valor sin procesar. Columnas |
vGrid: href on column "…" must be a row field name. | row.link se utiliza. Columnas |
vGrid: rowClass must be a function., rowClass failed: … | No se añade ninguna clase. Apariencia |
vGrid: at least one column must stay active. detiene | Deje una columna sin active: false. Columnas |
vGrid: column "…" not found (una advertencia) | sort() hace referencia a una columna oculta o desconocida. API de la instancia |
| Ordenación y filtrado | |
vGrid: external sort column / direction control was not found. | Corrija el selector. Ordenación |
vGrid: external filter for "…" was not found. | Corrija el selector; se omite ese filtro. Filtros externos |
vGrid: filterModes on column "…" needs a dataSource. | Los modos requieren una cuadrícula remota. Modos de filtro |
vGrid: filterModes on column "…" works with text filters only. | Quite filterType: 'select' o los modos. Modos de filtro |
vGrid: filterModes on column "…" must be an object of parameter: label pairs. | Proporcione un objeto. Modos de filtro |
vGrid: filterModes range on column "…" needs keys: an array of two different parameter names. | Proporcione range.keys dos nombres distintos. Modos de filtro |
vGrid: filterModes on column "…" has an empty parameter name., … uses the reserved name(s) …. | Se descarta ese modo; cámbiele el nombre. Modos de filtro |
vGrid: filterModes key "…" on column "…" needs a non-empty value and cannot be a range. | That mode is dropped; give value some text, or remove it from range. One-click modes |
| Paginación | |
vGrid: rowsPerPageOptions must be a non-empty array of positive numbers., … has no effect without a positive rowsPerPage. | Corrija la matriz o establezca rowsPerPage. Tamaño de página |
vGrid: setPage() expects a page number of 1 or greater. | Proporcione un número entero desde 1. API de la instancia |
vGrid: external pagination control was not found., external rows-per-page control was not found. | Corrija el selector. Paginación externa |
| Acciones de la barra de herramientas | |
vGrid: actions must be true, false, a position name, or an object., actions.position must be one of … | Use un valor admitido. El grupo de botones |
vGrid: actions.… is not a known action., actions.order has no action named …., actions.… must be true, false, a symbol, or an object. | Compruebe la escritura. Valores de las acciones |
vGrid: actions.element was not found., external settings control was not found., actions.position 'external' needs actions.element. | Corrige o añade el contenedor; los botones aparecerán junto al título. El grupo de botones |
vGrid: download must be true, false, or one of server, view., download: 'server' needs a dataSource. | Use un valor admitido; sin un dataSource la descarga será un CSV del navegador. Activación de funciones |
vGrid: print must be true or false. | Use un valor booleano. Activación de funciones |
vGrid download error:, vGrid print error: | Falló la descarga del servidor o la vista de impresión; la cuadrícula muestra el motivo. Activación de funciones |
vGrid: reorderDelay must be a number of milliseconds, 0 or more. | Se usa el valor predeterminado 350. Cambio de orden |
| Interacción con las filas | |
vGrid: rowActions must be an array, a function, or false., rowActions[].name must be a string. | No hay columna Acciones o la acción se ha nombrado igual que su etiqueta. Acciones de fila |
vGrid: rowReorder must be true or false., cellSelection must be true or false. | La función permanece desactivada. Interacción con las filas |
| Subcuadrículas | |
vGrid: subgrid panel "…" needs an id naming the column its value comes from., … needs a dataSource. | Se descarta ese panel; añada la clave. Paneles |
vGrid: subgrid position must be "start", "end", or the column number counted from the left. | El interruptor vuelve al inicio. Grupo de subcuadrículas |
vGrid: subgrid open: "…" does not match any panel name. | Use el valor de un panel para name. Grupo de subcuadrículas |
vGrid: subgrid panel "…" external filter for "…" was not found. | Corrija el selector. Paneles |
vGrid panel error: | Falló la solicitud de un panel; el panel muestra el motivo. Paneles |
Los errores que se muestran en la cuadrícula se enumeran en Respuestas lentas, vacías o incorrectas.
Recetas
Preguntas frecuentes con el fragmento de código correspondiente.
Filtrar por un intervalo de fechas
{
name: 'shipped', label: 'Shipped',
filterModes: { range: { keys: ['shipped_from', 'shipped_to'], label: 'Between', symbol: '↔' } }
}
Su servidor lee shipped_from y shipped_to. Más información en Modos de filtro.
Exportar todos los resultados filtrados, no solo esta página
download: 'server', // your server receives download=true with the filters and sort
Cuando download=true llegue, ignore page y limit y devuelva un archivo en cualquier formato. Más información en Activación de funciones y La solicitud.
Mostrar totales fuera de la cuadrícula
externalSummary: { revenue: '#revenue' }, // response: "summary": [ { "key": "revenue", "value": "…" } ]
Más información en Totales del servidor.
Enviar un token de autenticación
headers: { Authorization: 'Bearer ' + token }, // subgrid panels get it too
Más información en Datos remotos.
Controlar la cuadrícula desde su propio formulario de búsqueda
<input type="search" id="q" placeholder="Search orders">
<select id="status"><option value="">Any status</option><option value="paid">Paid</option></select>
externalFilters: { q: '#q', status: '#status' }, // the search box sends on Enter
Más información en Filtros externos.
Mostrar filas de detalle para cada registro
subgrid: {
panels: [{
name: 'items', label: 'Items', id: 'id', type: 'grid',
dataSource: '/api/order-items', // requested as ?id=<the row's id>
columns: [{ name: 'sku', label: 'SKU' }, { name: 'qty', label: 'Qty' }]
}]
},
Más información en Subcuadrículas.
Recordar las columnas de cada lector
settings: true, // the default: Settings → Save remembers columns in this browser
Las opciones se guardan por navegador, bajo el valor de la cuadrícula el y dataSource; mantenga ambos estables. Más información en ventana emergente de configuración.
Colocar varias cuadrículas en una página
vGrid({ el: '#orders', dataSource: '/api/orders', columns: [/* … */] });
vGrid({ el: '#returns', dataSource: '/api/returns', columns: [/* … */] });
Cada cuadrícula obtiene sus clases del id de su contenedor; configura namespace para elegir otra. Más información en Montaje e identificación.
Opciones disponibles
Todas las opciones vGrid({ … }) acepta, agrupadas según lo que controlan. Selecciona un nombre para ver una breve descripción y un ejemplo.
Montaje
Datos y servidor
Columnas
Claves de columna
activefilterfilterClearfilterModesfilterOptionsfilterTypehrefisRowKeylabelnameoptionsrendersorttypewidth
Números de fila
Ordenación
Filtrado
Paginación
externalPaginationexternalRowsPerPagerowsPerPagerowsPerPageOptionsshowPaginationshowPaginationControlsshowRowsPerPage
Apariencia
Reordenación de columnas
Acciones de la barra de herramientas
Subcuadrículas
Interacción con las filas
Eventos
Todas las opciones, de la A a la Z
actions
Coloca y configura los botones de la barra de herramientas. Claves: position, element, order, clear, download, print, refresh, settings, textSize. Valor predeterminado: 'caption'.
actions: { position: 'bottom' },
Más información en Grupo de botones
active clave de columna
Oculta la columna al inicio cuando false; Configuración permite mostrarla. Valor predeterminado: true.
{ name: 'ref', active: false }
Más información en Identidad y presentación
autoDestroy
Destruye la cuadrícula cuando su contenedor sale de la página. Valor predeterminado: false.
autoDestroy: true,
Más información en Montaje e identidad
borders
Elige qué líneas dibuja la cuadrícula. Valor predeterminado: 'horizontal'.
borders: 'all',
caption
Añade una fila de título en la parte superior de la tabla, insertada como HTML. Valor predeterminado: ninguno.
caption: 'Orders',
Más información en Montaje e identidad
cellSelection
Permite enfocar las celdas, desplazarse con las flechas, ampliar rangos con Mayús y copiarlos como texto separado por tabulaciones. Valor predeterminado: false.
cellSelection: true,
Más información en Selección y copia de celdas
columns
Enumera las columnas, con un objeto por columna y en el orden de visualización; cada clave tiene una entrada propia en Claves de columna. Valor predeterminado: [].
columns: [{ name: 'number', label: 'Order' }],
data
Proporciona a la cuadrícula sus filas en el navegador. Valor predeterminado: [].
data: [{ number: 'A-1001', total: 120 }],
Más información en Datos locales
dataSource
Configura la cuadrícula para usar datos remotos: el servidor pagina, ordena y filtra. Valor predeterminado: ninguno.
dataSource: '/api/orders',
Más información en Datos remotos
download
Añade un botón Descargar; el archivo lo genera el servidor o el navegador. Valor predeterminado: false.
download: 'server',
Más información en Activación de funciones
easing
Define la duración de las animaciones de la cuadrícula, en milisegundos. Valor predeterminado: 160.
easing: 0, // no animation
el
Indica el elemento que contiene la cuadrícula. Valor predeterminado: obligatorio.
el: '#orders',
Más información en Montaje e identidad
externalFilters
Envía los campos de entrada de la página con cada solicitud. Valor predeterminado: {}.
externalFilters: { region: '#region' },
Más información en Filtros externos
externalPagination
Coloca el recuento y el paginador en tus propios elementos. Valor predeterminado: ninguno.
externalPagination: '.pager',
Más información en Paginación externa
externalRowsPerPage
Permite que sus propios elementos <select> establezcan el tamaño de página. Valor predeterminado: ninguno.
externalRowsPerPage: '#page-size',
Más información en Paginación externa
externalSettings
El nombre anterior de actions.element. Valor predeterminado: ninguno.
externalSettings: '#toolbar',
Más información en Activación de funciones
externalSort
Permite que sus propios elementos <select> elementos controlan la ordenación. Claves: column, direction. Valor predeterminado: {}.
externalSort: { column: '#sort-column', direction: '#sort-direction' },
externalSummary
Rellena los elementos de la página con los totales que envía el servidor. Valor predeterminado: {}.
externalSummary: { revenue: '#revenue' },
Más información en Totales del servidor
filter clave de columna
Elimina el filtro de la columna cuando false. Valor predeterminado: true.
{ name: 'notes', filter: false }
Más información en Ordenación y filtrado por columna
filterClear
Añade un botón × a los filtros con contenido. Valor predeterminado: true.
filterClear: false,
Más información en Fila de filtros
filterClear clave de columna
Elimina el botón × de esta columna cuando false. Valor predeterminado: true.
{ name: 'status', filterClear: false }
Más información en Ordenación y filtrado por columna
filterModes clave de columna
Añade un botón de modo que cambia el parámetro enviado por el filtro. Claves: una por parámetro, con label, symbol y value; range con keys, label y symbol. Valor predeterminado: ninguno.
{ name: 'price', filterModes: { price_equals: 'Equals' } }
Más información en Modos de filtro
filterOptions clave de columna
Enumera las opciones del menú desplegable como "value:Text;value:Text". Valor predeterminado: ''.
{ name: 'status', filterType: 'select', filterOptions: ':All;paid:Paid' }
Más información en Ordenación y filtrado por columna
filterRow
Muestra una fila de cuadros de filtro debajo de los encabezados. Valor predeterminado: true.
filterRow: false,
Más información en Fila de filtros
filterType clave de columna
Convierte el filtro en una lista desplegable. Valor predeterminado: cuadro de texto.
{ name: 'status', filterType: 'select' }
Más información en Ordenación y filtrado por columna
headers
Añade encabezados a todas las solicitudes, incluidas las de paneles de subcuadrícula. Valor predeterminado: {}.
headers: { Authorization: 'Bearer ' + token },
Más información en Datos remotos
hover
Resalta la fila bajo el puntero. Valor predeterminado: true.
hover: false,
href clave de columna
Indica el campo de la fila que contiene la dirección de una type: 'link' columna. Valor predeterminado: 'link'.
{ name: 'customer', type: 'link', href: 'customerUrl' }
Más información en Identidad y presentación
inheritQueryString
Añade la cadena de consulta de la página a cada solicitud de panel. Valor predeterminado: false.
inheritQueryString: true,
Más información en Herencia de la cadena de consulta
isRowKey clave de columna
Muestra el valor de esta columna en la celda del número de fila. Valor predeterminado: false.
{ name: 'number', isRowKey: true }
Más información en Identidad y presentación
label clave de columna
Establece el encabezado de la columna. Valor predeterminado: name.
{ name: 'number', label: 'Order' }
Más información en Identidad y presentación
locale
Establece el idioma que la cuadrícula envía al servidor como lang. Valor predeterminado: el atributo lang más cercano en la página y después el idioma del navegador.
locale: 'de-AT',
method
Envía las solicitudes como GET, o como un cuerpo JSON con POST. Valor predeterminado: 'GET'.
method: 'POST',
Más información en Datos remotos
name clave de columna
Indica la clave de la fila que muestra la columna. Valor predeterminado: obligatorio.
{ name: 'number' }
Más información en Identidad y presentación
namespace
Indica las clases adicionales de la cuadrícula y los nombres alternativos de archivo. Valor predeterminado: elsu id.
namespace: 'orders-grid',
Más información en Montaje e identidad
onFilter
Se llama cuando cambia un filtro en una cuadrícula local. Valor predeterminado: ninguno.
onFilter: ({ filters }) => console.log(filters),
onPage
Se llama cuando se muestra una página. Valor predeterminado: ninguno.
onPage: ({ page, total }) => console.log(page, total),
onReady
Se llama cuando las filas aparecen en pantalla o cuando falla una carga remota. Valor predeterminado: ninguno.
onReady: ({ total, error }) => console.log(total, error),
onRowClick
Se llama con { row, event } cuando se hace clic en una fila o se pulsa Intro o Espacio sobre ella. Valor predeterminado: ninguno.
onRowClick: ({ row }) => location.assign('/orders/' + row.id),
Más información en Clic y doble clic en filas
onRowDblClick
Se llama con { row, event } con un doble clic o al pulsar Mayús+Intro en una fila enfocada. Valor predeterminado: ninguno.
onRowDblClick: ({ row }) => openEditor(row),
Más información en Clic y doble clic en filas
onRowReorder
Se llama con { row, from, to, rows } después de que un botón ↑ o ↓ mueva una fila; obligatorio en una cuadrícula remota con rowReorder. Valor predeterminado: ninguno.
onRowReorder: ({ row, to }) => saveOrder(row.id, to),
Más información en Reordenación de filas
onSort
Se llama cuando cambia la ordenación; con una ordenación secundaria, el objeto también incluye sorts. Valor predeterminado: ninguno.
onSort: ({ column, order }) => console.log(column, order),
options clave de columna
Asigna valores al texto mostrado para type: 'enum'. Valor predeterminado: ninguno.
{ name: 'status', type: 'enum', options: { paid: 'Paid' } }
Más información en Identidad y presentación
print
Añade un botón Imprimir para las filas visibles. Valor predeterminado: true.
print: false,
Más información en Activación de funciones
render clave de columna
Devuelve lo que muestra la celda: texto, un nodo DOM o undefined para la presentación normal. Valor predeterminado: ninguno.
{ name: 'price', render: value => '$' + Number(value).toFixed(2) }
Más información en Identidad y presentación
reorderColumns
Permite mover columnas al mantener pulsado y arrastrar un encabezado. Valor predeterminado: true.
reorderColumns: false,
Más información en Reordenación
reorderDelay
Define cuánto tiempo hay que mantener pulsado un encabezado antes de moverlo, en milisegundos. Valor predeterminado: 350.
reorderDelay: 600,
Más información en Reordenación
rowActions
Botones al final de cada fila. Una matriz de { name, label, onClick, ariaLabel, disabled }, o una función que devuelve uno a partir de la fila. Valor predeterminado: false.
rowActions: [{ name: 'open', label: 'Open', onClick: ({ row }) => location.assign('/orders/' + row.id) }],
Más información en Acciones de fila
rowReorder
Añade una columna de botones ↑ y ↓ que mueven una fila una posición. Valor predeterminado: false.
rowReorder: true,
Más información en Reordenación de filas
rowClass
Devuelve las clases que se añadirán a una fila según sus datos. Valor predeterminado: ninguna.
rowClass: row => row.status === 'overdue' ? 'table-danger' : '',
rowNumbers
Muestra una columna inicial con números de fila. Valor predeterminado: true.
rowNumbers: false,
Más información en Números de fila
rowNumbersType
Cuenta las filas o muestra un campo de fila en la columna numérica. Valor predeterminado: 'sequential'.
rowNumbersType: 'id',
Más información en Números de fila
rowsPerPage
Define cuántas filas muestra cada página; el servidor recibe el valor como limit. Valor predeterminado: 0, sin paginación.
rowsPerPage: 25,
Más información en Tamaño de página
rowsPerPageOptions
Define las opciones de «Mostrar N filas». Valor predeterminado: automático.
rowsPerPageOptions: [25, 50, 100],
Más información en Tamaño de página
settings
Añade la ventana Ajustes, Borrar filtros y Actualizar. Valor predeterminado: true.
settings: false,
Más información en Activación de funciones
showPagination
Muestra el recuento y la paginación. Valor predeterminado: showPaginationControls.
showPagination: false,
Más información en Barras de paginación
showPaginationControls
Muestra u oculta ambos componentes de las barras de paginación. Valor predeterminado: true.
showPaginationControls: false,
Más información en Barras de paginación
showRowsPerPage
Muestra "Show N rows". Valor predeterminado: showPaginationControls.
showRowsPerPage: false,
Más información en Barras de paginación
size
Establece el tamaño de texto inicial. Valor predeterminado: 'medium'.
size: 'small',
sort clave de columna
Impide ordenar por el encabezado cuando false. Valor predeterminado: true.
{ name: 'notes', sort: false }
Más información en Ordenación y filtrado por columna
sortBy
Ordena la cuadrícula al inicio. Claves: column, order; un arreglo añade los criterios de desempate en orden. Valor predeterminado: ninguno.
sortBy: { column: 'total', order: 'desc' },
sortBy: [{ column: 'status' }, { column: 'total', order: 'desc' }],
striped
Sombrea una fila sí y otra no. Valor predeterminado: true.
striped: false,
subgrid
Añade paneles de detalle que se abren por fila. Claves: panels, position, single, open, el, method, headers, rowsPerPage, externalFilters; los paneles aceptan name, label, id, dataSource, idInPath, type, caption, method, headers, externalFilters, y las claves de cuadrícula se aplican a los paneles de cuadrícula. Valor predeterminado: ninguno.
subgrid: { panels: [{ name: 'items', id: 'id', dataSource: '/api/order-items' }] },
Más información en Subcuadrículas
type clave de columna
Muestra el valor como HTML, como texto obtenido de una búsqueda o como enlace. Valor predeterminado: texto sin formato.
{ name: 'notes', type: 'html' }
Más información en Identidad y presentación
width clave de columna
Establece el ancho inicial de la columna. Valor predeterminado: automático.
{ name: 'number', width: 120 }