Skip to content

Table Component Demos

Basic Table

Simple table with sorting capabilities and hover effects.

vue
<template>
  <OTable 
    :headers="headers"
    :tableData="tableData"
    @cellClicked="handleCellClick"
  />
</template>

<script setup>
import { ref } from 'vue';

const headers = [
  { text: "Name", key: "name", sortable: true },
  { text: "Email", key: "email", sortable: true },
  { text: "Age", key: "age", classes: "center-align", sortable: true },
  { text: "Department", key: "department" }
];

const tableData = ref([
  { name: "John Doe", email: "john@example.com", age: 30, department: "Engineering" },
  { name: "Jane Smith", email: "jane@example.com", age: 25, department: "Marketing" },
  { name: "Bob Johnson", email: "bob@example.com", age: 35, department: "Sales" }
]);

const handleCellClick = (rowData, cell) => {
  console.log('Cell clicked:', rowData, cell);
};
</script>
Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering

Table with Pagination

Table with built-in pagination controls.

vue
<template>
  <OTable 
    :headers="headers"
    :tableData="tableData"
    :enablePagination="true"
    :itemsPerPage="3"
    :currentPage="currentPage"
    :totalItems="totalItems"
    @onPageChange="handlePageChange"
  />
</template>

<script setup>
import { ref, computed } from 'vue';

const headers = [
  { text: "ID", key: "id", sortable: true },
  { text: "Name", key: "name", sortable: true },
  { text: "Email", key: "email" },
  { text: "Status", key: "status", classes: "center-align" }
];

const tableData = ref([
  { id: 1, name: "John Doe", email: "john@example.com", status: "Active" },
  { id: 2, name: "Jane Smith", email: "jane@example.com", status: "Active" },
  { id: 3, name: "Bob Johnson", email: "bob@example.com", status: "Inactive" },
  { id: 4, name: "Alice Brown", email: "alice@example.com", status: "Active" },
  { id: 5, name: "Charlie Wilson", email: "charlie@example.com", status: "Active" }
]);

const currentPage = ref(1);
const totalItems = computed(() => tableData.value.length);

const handlePageChange = (page) => {
  currentPage.value = page;
};
</script>
ID
Name
Email
Status
1
John Doe
john@example.com
Active
2
Jane Smith
jane@example.com
Active
3
Bob Johnson
bob@example.com
Inactive

Table with Custom Cell Content

Table with custom cell rendering using slots.

vue
<template>
  <OTable 
    :headers="headers"
    :tableData="tableData"
    @cellClicked="handleCellClick"
  >
    <template #cell-status="{ rowData }">
      <span :class="['status-badge', rowData.status.toLowerCase()]">
        {{ rowData.status }}
      </span>
    </template>
    
    <template #cell-actions="{ rowData }">
      <button @click="editUser(rowData)" class="edit-btn">Edit</button>
      <button @click="deleteUser(rowData)" class="delete-btn">Delete</button>
    </template>
  </OTable>
</template>

<script setup>
import { ref } from 'vue';

const headers = [
  { text: "Name", key: "name", sortable: true },
  { text: "Email", key: "email" },
  { text: "Status", key: "status" },
  { text: "Actions", key: "actions", classes: "center-align" }
];

const tableData = ref([
  { name: "John Doe", email: "john@example.com", status: "Active" },
  { name: "Jane Smith", email: "jane@example.com", status: "Inactive" },
  { name: "Bob Johnson", email: "bob@example.com", status: "Active" }
]);

const editUser = (user) => {
  console.log('Edit user:', user);
};

const deleteUser = (user) => {
  console.log('Delete user:', user);
};
</script>
Name
Email
Status
Actions
John Doe
john@example.com
Active
Jane Smith
jane@example.com
Inactive
Bob Johnson
bob@example.com
Active

Table with Alternate Row Colors

Table with alternating row background colors for better readability.

vue
<template>
  <OTable 
    :headers="headers"
    :tableData="tableData"
    :isAlternateRowColored="true"
    @cellClicked="handleCellClick"
  />
</template>

<script setup>
import { ref } from 'vue';

const headers = [
  { text: "Name", key: "name", sortable: true },
  { text: "Email", key: "email", sortable: true },
  { text: "Age", key: "age", classes: "center-align", sortable: true },
  { text: "Department", key: "department" }
];

const tableData = ref([
  { name: "John Doe", email: "john@example.com", age: 30, department: "Engineering" },
  { name: "Jane Smith", email: "jane@example.com", age: 25, department: "Marketing" },
  { name: "Bob Johnson", email: "bob@example.com", age: 35, department: "Sales" }
]);
</script>
Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering

Table with Alternate Column Colors

Table with alternating column background colors.

vue
<template>
  <OTable 
    :headers="headers"
    :tableData="tableData"
    :isAlternateColumnColored="true"
  />
</template>

<script setup>
import { ref } from 'vue';

const headers = [
  { text: "Name", key: "name" },
  { text: "Email", key: "email" },
  { text: "Role", key: "role" },
  { text: "Status", key: "status" }
];

const tableData = ref([
  { name: "John Doe", email: "john@example.com", role: "Developer", status: "Active" },
  { name: "Jane Smith", email: "jane@example.com", role: "Designer", status: "Active" },
  { name: "Bob Johnson", email: "bob@example.com", role: "Manager", status: "Away" }
]);
</script>
Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering

Table with Both Row and Column Colors

Table with both alternating row and column colors.

vue
<template>
  <OTable 
    :headers="headers"
    :tableData="tableData"
    :isAlternateRowColored="true"
    :isAlternateColumnColored="true"
  />
</template>
Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering

Table with Infinite Scroll

Table with infinite scroll functionality for loading more data.

vue
<template>
  <OTable 
    :headers="headers"
    :tableData="tableData"
    :enableInfiniteScroll="true"
    @scrolledToEndInTable="loadMoreData"
  />
</template>

<script setup>
import { ref } from 'vue';

const headers = [
  { text: "Name", key: "name", sortable: true },
  { text: "Email", key: "email", sortable: true },
  { text: "Age", key: "age", classes: "center-align", sortable: true },
  { text: "Department", key: "department" }
];

const tableData = ref([
  { name: "John Doe", email: "john@example.com", age: 30, department: "Engineering" },
  { name: "Jane Smith", email: "jane@example.com", age: 25, department: "Marketing" },
  { name: "Bob Johnson", email: "bob@example.com", age: 35, department: "Sales" }
]);

const loadMoreData = () => {
  console.log('Loading more data...');
  // In a real application, you would fetch more data from an API
  // and append it to tableData
};
</script>
Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering

Table with Data Transformation

Table using domFunc to transform cell data before display.

vue
<template>
  <OTable
    :headers="headers"
    :tableData="data"
  />
</template>

<script setup>
import { ref } from 'vue';

const formatDate = (dateString) => {
  if (!dateString) return '-';
  const date = new Date(dateString);
  return date.toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'short',
    day: 'numeric'
  });
};

const formatCurrency = (value) => {
  if (!value && value !== 0) return '-';
  return `$${parseFloat(value).toFixed(2)}`;
};

const headers = [
  { text: "Name", key: "name" },
  { text: "Joined Date", key: "joinedDate", domFunc: formatDate },
  { text: "Salary", key: "salary", domFunc: formatCurrency, classes: "right-align" }
];

const data = ref([
  { name: "John Doe", joinedDate: "2022-01-15", salary: 75000 },
  { name: "Jane Smith", joinedDate: "2021-06-22", salary: 82000 },
  { name: "Bob Johnson", joinedDate: "2023-03-10", salary: 65000 },
  { name: "Alice Brown", joinedDate: "2022-11-05", salary: 78000 }
]);
</script>
Name
Joined Date
Salary
John Doe
Jan 15, 2022
$75000.00
Jane Smith
Jun 22, 2021
$82000.00
Bob Johnson
Mar 10, 2023
$65000.00
Alice Brown
Nov 5, 2022
$78000.00

Table with Copy Functionality

Table with copy to clipboard functionality for specific columns.

vue
<template>
  <OTable
    :headers="headers"
    :tableData="data"
  />
</template>

<script setup>
import { ref } from 'vue';

const headers = [
  { text: "Name", key: "name", enableCopy: true, headerClasses: "right-align" },
  { text: "Email", key: "email", enableCopy: true },
  { text: "ID", key: "id", enableCopy: true, classes: "center-align" }
];

const data = ref([
  { name: "John Doe", email: "john@example.com", id: "EMP001" },
  { name: "Jane Smith", email: "jane@example.com", id: "EMP002" },
  { name: "Bob Johnson", email: "bob@example.com", id: "EMP003" }
]);
</script>
Name
Email
ID
John Doe
john@example.com
EMP001
Jane Smith
jane@example.com
EMP002
Bob Johnson
bob@example.com
EMP003

Table with Custom Column Widths

Table with custom column widths.

vue
<template>
  <OTable
    :headers="headers"
    :tableData="data"
    :defaultCellWidth="'1fr'"
  />
</template>

<script setup>
import { ref } from 'vue';

const headers = [
  { text: "Name", key: "name", width: "200px" },
  { text: "Email", key: "email", width: "250px" },
  { text: "Role", key: "role", width: "150px" },
  { text: "Status", key: "status" }
];

const data = ref([
  { name: "John Doe", email: "john@example.com", role: "Developer", status: "Active" },
  { name: "Jane Smith", email: "jane@example.com", role: "Designer", status: "Active" },
  { name: "Bob Johnson", email: "bob@example.com", role: "Manager", status: "Away" }
]);
</script>
Name
Email
Role
Status
John Doe
john@example.com
Developer
Active
Jane Smith
jane@example.com
Designer
Active
Bob Johnson
bob@example.com
Manager
Away

Table with Custom Headers

Table with custom header content using header slots.

vue
<template>
  <OTable 
    :headers="headers"
    :tableData="tableData"
    @cellClicked="handleCellClick"
  >
    <template #header-name="{ cell }">
      <div class="custom-header">
        <span>{{ cell.text }}</span>
        <span class="required">*</span>
      </div>
    </template>
    
    <template #header-email="{ cell }">
      <div class="custom-header">
        <span>{{ cell.text }}</span>
        <span class="info-icon">ℹ️</span>
      </div>
    </template>
  </OTable>
</template>

<script setup>
import { ref } from 'vue';

const headers = [
  { text: "Name", key: "name", sortable: true },
  { text: "Email", key: "email", sortable: true },
  { text: "Age", key: "age", classes: "center-align", sortable: true }
];

const tableData = ref([
  { name: "John Doe", email: "john@example.com", age: 30 },
  { name: "Jane Smith", email: "jane@example.com", age: 25 },
  { name: "Bob Johnson", email: "bob@example.com", age: 35 }
]);
</script>
Name*
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering

Async Table with Server-side Sorting

Table configured for server-side data handling with async mode.

vue
<template>
  <OTable 
    :headers="headers"
    :tableData="tableData"
    :async="true"
    :enablePagination="true"
    :currentPage="currentPage"
    :totalItems="totalItems"
    @onSort="handleSort"
    @onPageChange="handlePageChange"
  />
</template>

<script setup>
import { ref } from 'vue';

const headers = [
  { text: "Name", key: "name", sortable: true },
  { text: "Email", key: "email", sortable: true },
  { text: "Created", key: "createdAt", sortable: true }
];

const tableData = ref([]);
const currentPage = ref(1);
const totalItems = ref(0);

const handleSort = ({ key, direction }) => {
  console.log('Sort:', key, direction);
  // Handle sorting on the server
};

const handlePageChange = (page) => {
  currentPage.value = page;
  // Handle page change on the server
};
</script>
ID
Name
Email
Status
1
John Doe
john@example.com
Active
2
Jane Smith
jane@example.com
Active
3
Bob Johnson
bob@example.com
Inactive
4
Alice Brown
alice@example.com
Active
5
Charlie Wilson
charlie@example.com
Active
6
Diana Prince
diana@example.com
Inactive
7
Edward Norton
edward@example.com
Active
8
Fiona Gallagher
fiona@example.com
Active