Orbito - Dokumentacja modułówOrbito - Dokumentacja modułów
Wprowadzenie
Pierwsze kroki
API
Komunikacja
Widoki
Wdrożenie
Społeczność
For AI agents
Wprowadzenie
Pierwsze kroki
API
Komunikacja
Widoki
Wdrożenie
Społeczność
For AI agents
  • OrbitoViewEngine

    • Wprowadzenie
    • BaseView – Klasa bazowa
    • Zmienne (VarStore)
    • Listy i notacja .$
    • Szablony Handlebars
    • Akcje (ActionHandler)
    • Tabele danych
    • Edycja danych
    • Kontrolki wartości
    • Warianty stylistyczne
    • Komponenty i sloty
    • Pliki, kamera i schemat z serwera
  • Widoki

    • AvatarView
    • BadgeView
    • ButtonView
    • CameraView
    • CardView
    • CheckboxGroupView
    • CheckboxView
    • ComponentView
    • CssBoxView
    • DataTableView
    • DropdownView
    • DynamicListView
    • DynamicView
    • FilePickerView
    • FilePreviewView
    • FlexView
    • GridView
    • HtmlView
    • InlineEditView
    • InputView
    • ListView
    • ModalView
    • PopoverView
    • RadioGroupView
    • RowView
    • SelectView
    • SliderView
    • SlotView
    • StepperView
    • TabsView
    • TextInputView
    • TextView

Tabele danych

Źródło: DataTableView.js, tableSource.js

Tabela w OVE ma jeden zestaw funkcji (kolumny, wyszukiwanie, sortowanie, paginacja, selekcja, akcje, stopka, edycja wiersza) i dwa źródła danych. Nie ma osobnego datagrid dla danych lokalnych — zmienia się wyłącznie to, skąd biorą się wiersze.

Źródło danych

Lokalne — tablica ze stanu

type: datatable
id: payments
data:
  varPath: $page.payments      # $page.* | $global.* | $props.* | <viewId>[.pole]
  searchFields: [title, note]  # pola przeszukiwane (domyślnie wszystkie proste)
  paginate: false              # wyłącza stronicowanie
search: true                   # pokazuje pole wyszukiwania (bez parametru API)
columns:
  - header: Tytuł
    field: title

Filtrowanie, sortowanie i strony liczone są w przeglądarce. Tabela sama odświeża się po zmianie wskazanej zmiennej — bez akcji reload. Sortowanie nie przestawia tablicy w stanie: wiersze są kopiowane przed posortowaniem.

API — zapytanie do modułu

dataSource:
  module: core/orders
  method: list
  params:
    status: active
  responsePath: data
  totalPath: pagination.total
queryKey: name                 # nazwa parametru wyszukiwania

Serwer dostaje stronę, rozmiar strony, frazę i sortowanie, a zwraca gotowy zestaw wierszy.

Tabela w cudzej karcie

Gdy tabela ma stanąć w content cudzej karty (typowo fragment modułu wstawiany przez schemaGuard do wspólnej karty strony zamówienia), użyj embedded: true zamiast pozwalać jej zbudować własną kartę:

type: datatable
id: shpList
footer: false          # embedded ma sens bez stopki i bez title — inaczej znów
embedded: true          # widać ramy karty w karcie
dataSource:
  module: core/shipping
  method: shipments.getByOrderId
  params:
    orderId: '@orderId'

embedded: true zdejmuje z hosta klasę card (zostaje ove-datatable-embedded) i z <table> klasę card-table — bez tego druga karta rysowałaby się w środku pierwszej, a card-table dokładałby w cudzym card-body drugi padding. Łączy się z footer: false i brakiem title: nagłówek i stopka nadal renderują się na zwykłych zasadach, więc zostawione by dawały ten sam efekt karty w karcie.

Domyślne minHeight: 300px na obszarze tabeli włącza się tylko gdy tabela ma stopkę — paginacja zmienia liczbę wierszy i bez rezerwy układ skakałby przy każdej stronie. Tabela embedded zwykle jest bez stopki, więc domyślnie nie dostaje minimalnej wysokości — zajmuje tyle, ile mają wiersze. Żeby to nadpisać w dowolną stronę (zarezerwować miejsce mimo braku stopki albo wymusić minHeight: 0 mimo stopki), podaj minHeight wprost w schemacie.

Ukrywanie pustej tabeli

Gdy źródło nie zwróci żadnych wierszy, tabelę chowamy klasą d-none przez classIf, nie przez renderIf:

# Pusta tabela znika, ale zostaje jako źródło danych i cel reload/refresh —
# renderIf by ją usunął z drzewa widoków razem z tą rolą.
classIf:
  d-none:
    shpList:
      $size: 0

renderIf przy zmianie warunku usuwa i odbudowuje widok od nowa — tabela przestałaby istnieć, więc nie mogłaby dalej być źródłem danych dla onVarChange innych elementów ani celem akcji reload/refresh po nadaniu. classIf tylko dokłada i zdejmuje klasę na istniejącym hoście, więc tabela żyje przez cały czas, a chowa się wyłącznie wizualnie.

Kolumny

PoleZnaczenie
headerNagłówek kolumny
fieldŚcieżka do wartości w wierszu (customer.name) — komórka pokazuje samą wartość
contentTablica widoków w komórce (ma pierwszeństwo przed field)
actionsAkcje wiersza jako przyciski (ma pierwszeństwo przed content)
alignstart, center, end
widthSzerokość kolumny (150px, 1%)
sortable / sortKeySortowanie; sortKey domyślnie równy field
decimals, prefix, suffix, emptyTextFormatowanie wartości field
summary / summaryValuePodsumowanie w stopce tabeli
className / cellClassNameDodatkowe klasy nagłówka / komórek
columns:
  - header: Nazwa
    field: title
    sortable: true
  - header: Kwota
    field: amount
    align: end
    decimals: 2
    suffix: " PLN"
    summary: sum
  - header: ""
    width: 1%
    actions:
      - icon: trash
        title: Usuń
        variant: danger
        action: callMethod
        module: core/orders
        method: payment.remove
        params:
          id: { valueFrom: payments.$.id }
        refresh: [payments]

Wpis akcji to pełna konfiguracja akcji — działa każde jej pole (params, onSuccess, refresh, confirm…), a nie tylko wybrany zestaw. Pola prezentacyjne (label, icon, variant, outline, size, title, className) opisują przycisk.

Podsumowania

- header: Kwota
  field: amount
  summary: sum                                   # sum | avg | min | max | count
- header: Kwota
  field: amount
  summary: { agg: sum, decimals: 2, suffix: " PLN" }
- header: Razem
  summaryValue: "{{ ordersTable.total }}"        # gotowa wartość zamiast agregacji

Źródło lokalne agreguje wszystkie przefiltrowane wiersze, a źródło API — wiersze bieżącej strony, bo tylko one są znane przeglądarce. Dla sum liczonych na serwerze użyj summaryValue.

Edycja wiersza

rowKey: id
editable:
  fields:                      # opis pól taki sam jak w `inlineedit`
    - key: qty
      type: number
      min: 0
      required: true
    - key: note
  save:
    module: core/orders
    method: product.update
    params:
      orderId: { valueFrom: $page.orderId }
    rowKeyParam: productId     # nazwa parametru z identyfikatorem (domyślnie `rowKey`)
    onlyChanged: true
    refresh: [orderDetail]
columns:
  - header: Ilość
    field: qty                 # w trybie edycji zamienia się w kontrolkę pola `qty`

Tabela dokłada kolumnę z przyciskami ✎ / ✓ / ✕. Edycja pracuje na roboczej kopii danych (patrz Edycja danych), więc anulowanie nie wymaga przeładowania. Edytowany wiersz rozpoznawany jest po rowKey, dzięki czemu przeżywa sortowanie i odświeżenie danych; gdy wiersz zniknie ze zbioru, edycja się zamyka. Błąd zapisu pojawia się pod wierszem i nie zamyka trybu edycji.

Zdarzenia

ZdarzenieKiedy
datatable:loaded:<id>po załadowaniu danych
datatable:pageChange:<id>po zmianie strony
datatable:search:<id>po wyszukiwaniu
datatable:sort:<id>po sortowaniu
datatable:select:<id>po zaznaczeniu wierszy
datatable:rowClick:<id>po kliknięciu w wiersz
datatable:editRow:<id>po otwarciu edycji wiersza
datatable:cancelRow:<id>po anulowaniu edycji
datatable:savedRow:<id>po udanym zapisie wiersza
Ostatnio zaktualizowano:: 16.09.2026, 10:04
Contributors: Wiktor Koźmiński, Claude Fable 5.1
Prev
Akcje (ActionHandler)
Next
Edycja danych