Improve DataTable demo performance

pull/5018/head
mertsincan 2023-12-31 14:08:33 +00:00
parent 69d9c0875b
commit 27db388223
48 changed files with 1560 additions and 1366 deletions

View File

@ -0,0 +1,55 @@
<template>
<div v-if="!visible" class="demo-section-loading">Loading...</div>
<slot v-else></slot>
</template>
<script>
export default {
name: 'DeferredDemo',
emits: ['load'],
props: {
options: {
type: Object,
default: null
}
},
data() {
return {
visible: false
};
},
observer: null,
timeout: null,
mounted() {
this.observer = new IntersectionObserver(([entry]) => {
clearTimeout(this.timeout);
if (entry.isIntersecting) {
this.timeout = setTimeout(() => {
this.visible = true;
this.observer.unobserve(this.$el);
this.$emit('load');
}, 350);
}
}, this.options);
this.observer.observe(this.$el);
},
beforeUnmount() {
!this.visible && this.$el && this.observer?.unobserve(this.$el);
clearTimeout(this.timeout);
}
};
</script>
<style>
.demo-section-loading {
display: grid;
place-items: center;
padding: 2rem;
border-radius: 10px;
margin-bottom: 1rem;
font-size: 2rem;
height: 350px;
background: var(--maskbg);
}
</style>

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>DataTable requires a <i>value</i> as data to display and <i>Column</i> components as children for the representation.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" tableStyle="min-width: 50rem">
<Column field="code" header="Code"></Column>
@ -10,6 +11,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -98,8 +100,10 @@ const products = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -5,6 +5,7 @@
to span are defined with the <i>colspan</i> and <i>rowspan</i> properties of a Column.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="sales" tableStyle="min-width: 50rem">
<ColumnGroup type="header">
@ -49,6 +50,7 @@
</ColumnGroup>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" />
</template>
@ -294,7 +296,8 @@ const thisYearTotal = computed(() => {
}
};
},
created() {
methods: {
loadDemoData() {
this.sales = [
{ product: 'Bamboo Watch', lastYearSale: 51, thisYearSale: 40, lastYearProfit: 54406, thisYearProfit: 43342 },
{ product: 'Black Watch', lastYearSale: 83, thisYearSale: 9, lastYearProfit: 423132, thisYearProfit: 312122 },
@ -308,7 +311,6 @@ const thisYearTotal = computed(() => {
{ product: 'Gold Phone Case', lastYearSale: 75, thisYearSale: 54, lastYearProfit: 21212, thisYearProfit: 12533 }
];
},
methods: {
formatCurrency(value) {
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
}

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Column visibility based on a condition can be implemented with dynamic columns, in this sample a MultiSelect is used to manage the visible columns.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" tableStyle="min-width: 50rem">
<template #header>
@ -13,6 +14,7 @@
<Column v-for="(col, index) of selectedColumns" :key="col.field + '_' + index" :field="col.field" :header="col.header"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -139,7 +141,6 @@ const onToggle = (val) => {
}
};
},
created() {
this.columns = [
{ field: 'name', header: 'Name' },
@ -148,10 +149,10 @@ const onToggle = (val) => {
];
this.selectedColumns = this.columns;
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
onToggle(value) {
this.selectedColumns = this.columns.filter((col) => value.includes(col));
}

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Particular rows and cells can be styled based on conditions. The <i>rowClass</i> receives a row data as a parameter to return a style class for a row whereas cells are customized using the <i>body</i> template.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" :rowClass="rowClass" :rowStyle="rowStyle" tableStyle="min-width: 50rem">
<Column field="code" header="Code"></Column>
@ -16,6 +17,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -160,10 +162,10 @@ const stockClass = (data) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsSmall().then((data) => (this.products = data));
},
methods: {
rowClass(data) {
return [{ 'bg-primary': data.category === 'Fitness' }];
},

View File

@ -4,6 +4,7 @@
DataTable has exclusive integration with ContextMenu using the <i>contextMenu</i> event to open a menu on right click alont with <i>contextMenuSelection</i> property and <i>row-contextmenu</i> event to control the selection via the menu.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<ContextMenu ref="cm" :model="menuModel" @hide="selectedProduct = null" />
<DataTable v-model:contextMenuSelection="selectedProduct" :value="products" contextMenu @row-contextmenu="onRowContextMenu" tableStyle="min-width: 50rem">
@ -17,6 +18,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -174,10 +176,10 @@ const formatCurrency = (value) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
onRowContextMenu(event) {
this.$refs.cm.show(event.originalEvent);
},

View File

@ -2,11 +2,13 @@
<DocSectionText v-bind="$attrs">
<p>Columns can be created programmatically.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" tableStyle="min-width: 50rem">
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -110,8 +112,10 @@ const columns = [
{ field: 'quantity', header: 'Quantity' }
];
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>DataTable can export its data to CSV format.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable ref="dt" :value="products" tableStyle="min-width: 50rem">
<template #header>
@ -15,6 +16,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -127,10 +129,10 @@ const exportCSV = () => {
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
exportCSV() {
this.$refs.dt.exportCSV();
}

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Enabling <i>showGridlines</i> displays borders between cells.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" showGridlines tableStyle="min-width: 50rem">
<Column field="code" header="Code"></Column>
@ -10,6 +11,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -98,8 +100,10 @@ const products = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -10,6 +10,7 @@
</p>
<p>Note that, the implementation of <i>checkbox selection</i> in lazy mode needs to be handled manually as in this example since the DataTable cannot know about the whole dataset.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card p-fluid">
<DataTable
ref="dt"
@ -69,6 +70,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -213,8 +215,8 @@ export default {
this.loading = true;
this.lazyParams = {
first: this.$refs.dt.first,
rows: this.$refs.dt.rows,
first: 0,
rows: 10,
sortField: null,
sortOrder: null,
filters: this.filters
@ -324,8 +326,8 @@ onMounted(() => {
loading.value = true;
lazyParams.value = {
first: dt.value.first,
rows: dt.value.rows,
first: 0,
rows: 10,
sortField: null,
sortOrder: null,
filters: filters.value
@ -425,12 +427,13 @@ const onRowUnselect = () => {
}
};
},
mounted() {
methods: {
loadDemoData() {
this.loading = true;
this.lazyParams = {
first: this.$refs.dt.first,
rows: this.$refs.dt.rows,
first: 0,
rows: 10,
sortField: null,
sortOrder: null,
filters: this.filters
@ -438,7 +441,6 @@ const onRowUnselect = () => {
this.loadLazyData();
},
methods: {
loadLazyData(event) {
this.loading = true;
this.lazyParams = { ...this.lazyParams, first: event?.first || this.first };

View File

@ -6,12 +6,14 @@
the rows after reorder completes.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" reorderableColumns @column-reorder="onColReorder" @row-reorder="onRowReorder" tableStyle="min-width: 50rem">
<Column rowReorder headerStyle="width: 3rem" :reorderableColumn="false" />
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -139,10 +141,10 @@ const onRowReorder = (event) => {
{ field: 'quantity', header: 'Quantity' }
];
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
onColReorder() {
this.$toast.add({ severity: 'success', summary: 'Column Reordered', life: 3000 });
},

View File

@ -9,6 +9,7 @@
<i>&#123;'1004': true&#125;</i>. The <i>dataKey</i> alternative is more performant for large amounts of data.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable v-model:expandedRows="expandedRows" :value="products" dataKey="id" @rowExpand="onRowExpand" @rowCollapse="onRowCollapse" tableStyle="min-width: 60rem">
<template #header>
@ -67,6 +68,7 @@
</template>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -426,10 +428,10 @@ const getOrderSeverity = (order) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsWithOrdersSmall().then((data) => (this.products = data));
},
methods: {
onRowExpand(event) {
this.$toast.add({ severity: 'info', summary: 'Product Expanded', detail: event.data.name, life: 3000 });
},

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>In addition to a regular table, alternatives with alternative sizes are available.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<div class="flex justify-content-center mb-4">
<SelectButton v-model="size" :options="sizeOptions" optionLabel="label" dataKey="label" />
@ -13,6 +14,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -126,8 +128,10 @@ const sizeOptions = ref([
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -6,6 +6,7 @@
browser is closed. Other alternative is <i>local</i> referring to <i>localStorage</i> for an extended lifetime.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable
v-model:filters="filters"
@ -76,6 +77,7 @@
<template #empty> No customers found. </template>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -433,10 +435,10 @@ const getSeverity = (status) => {
created() {
this.initFilters();
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersSmall().then((data) => (this.customers = data));
},
methods: {
initFilters() {
this.filters = {
global: { value: null, matchMode: FilterMatchMode.CONTAINS },

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Alternating rows are displayed when <i>stripedRows</i> property is present.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" stripedRows tableStyle="min-width: 50rem">
<Column field="code" header="Code"></Column>
@ -10,6 +11,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -98,8 +100,10 @@ const products = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Custom content at <i>header</i> and <i>footer</i> sections are supported via templating.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" tableStyle="min-width: 50rem">
<template #header>
@ -35,6 +36,7 @@
<template #footer> In total there are {{ products ? products.length : 0 }} products. </template>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -236,10 +238,10 @@ const getSeverity = (product) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
formatCurrency(value) {
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
},

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Setting <i>columnResizeMode</i> as <i>expand</i> changes the table width as well.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" resizableColumns columnResizeMode="expand" showGridlines tableStyle="min-width: 50rem">
<Column field="code" header="Code"></Column>
@ -10,6 +11,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -96,8 +98,10 @@ const products = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -5,6 +5,7 @@
that does not change the overall table width.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" resizableColumns columnResizeMode="fit" showGridlines tableStyle="min-width: 50rem">
<Column field="code" header="Code"></Column>
@ -13,6 +14,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -99,8 +101,10 @@ const products = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Cell editing is enabled by setting <i>editMode</i> as <i>cell</i>, defining input elements with <i>editor</i> templating of a Column and implementing <i>cell-edit-complete</i> to update the state.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card p-fluid">
<DataTable
:value="products"
@ -31,6 +32,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" :dependencies="{ sass: '1.45.0', 'sass-loader': '8.0.2' }" />
</template>
@ -260,10 +262,10 @@ const formatCurrency = (value) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
onCellEditComplete(event) {
let { data, newValue, field } = event;

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Cell Editing with Sorting and Filter</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card p-fluid">
<DataTable
v-model:filters="filters"
@ -28,6 +29,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" :dependencies="{ sass: '1.45.0', 'sass-loader': '8.0.2' }" />
</template>
@ -271,10 +273,10 @@ const isPositiveInteger = (val) => {
{ field: 'price', header: 'Price' }
];
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
onCellEditComplete(event) {
let { data, newValue, field } = event;

View File

@ -5,6 +5,7 @@
<i>editor</i> slot of a Column and implementing <i>row-edit-save</i> are necessary to update the state. The column to control the editing state should have <i>editor</i> templating applied.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card p-fluid">
<DataTable
v-model:editingRows="editingRows"
@ -54,6 +55,7 @@
<Column :rowEditor="true" style="width: 10%; min-width: 8rem" bodyStyle="text-align:center"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" :dependencies="{ sass: '1.45.0', 'sass-loader': '8.0.2' }" />
</template>
@ -317,10 +319,10 @@ const formatCurrency = (value) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
onRowEditSave(event) {
let { newData, index } = event;

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>When <i>filterDisplay</i> is set as <i>menu</i>, filtering is done via popups with support for multiple constraints and advanced templating.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable v-model:filters="filters" :value="customers" paginator showGridlines :rows="10" dataKey="id" filterDisplay="menu" :loading="loading" :globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']">
<template #header>
@ -112,6 +113,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -682,13 +684,13 @@ const getSeverity = (status) => {
created() {
this.initFilters();
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => {
this.customers = this.getCustomers(data);
this.loading = false;
});
},
methods: {
formatDate(value) {
return value.toLocaleDateString('en-US', {
day: '2-digit',

View File

@ -6,6 +6,7 @@
</p>
<p>The optional global filtering searches the data against a single value that is bound to the <i>global</i> key of the <i>filters</i> object. The fields to search against is defined with the <i>globalFilterFields</i>.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable v-model:filters="filters" :value="customers" paginator :rows="10" dataKey="id" filterDisplay="row" :loading="loading" :globalFilterFields="['name', 'country.name', 'representative.name', 'status']">
<template #header>
@ -77,6 +78,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -510,13 +512,13 @@ const getSeverity = (status) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => {
this.customers = this.getCustomers(data);
this.loading = false;
});
},
methods: {
getCustomers(data) {
return [...(data || [])].map((d) => {
d.date = new Date(d.date);

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Pagination is enabled by adding <i>paginator</i> property and defining <i>rows</i> per page.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="customers" paginator :rows="5" :rowsPerPageOptions="[5, 10, 20, 50]" tableStyle="min-width: 50rem">
<Column field="name" header="Name" style="width: 25%"></Column>
@ -10,6 +11,7 @@
<Column field="representative.name" header="Representative" style="width: 25%"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -104,8 +106,10 @@ const customers = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
}
}
};
</script>

View File

@ -5,6 +5,7 @@
<PrimeVueNuxtLink to="/paginator">Paginator</PrimeVueNuxtLink> component for more information about the advanced customization options.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable
:value="customers"
@ -27,6 +28,7 @@
<Column field="representative.name" header="Representative" style="width: 25%"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -145,8 +147,10 @@ const customers = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
}
}
};
</script>

View File

@ -1,5 +1,6 @@
<template>
<DocSectionText v-bind="$attrs"></DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable
:value="products"
@ -46,6 +47,7 @@
/>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -248,8 +250,10 @@ const products = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -5,6 +5,7 @@
<i>rowgroup-collapse</i> events.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable
v-model:expandedRowGroups="expandedRowGroups"
@ -45,6 +46,7 @@
</template>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -286,10 +288,10 @@ const getSeverity = (status) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
},
methods: {
onRowGroupExpand(event) {
this.$toast.add({ severity: 'info', summary: 'Row Group Expanded', detail: 'Value: ' + event.data, life: 3000 });
},

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>When <i>rowGroupMode</i> is configured to be <i>rowspan</i>, the grouping column spans multiple rows.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="customers" rowGroupMode="rowspan" groupRowsBy="representative.name" sortMode="single" sortField="representative.name" :sortOrder="1" tableStyle="min-width: 50rem">
<Column header="#" headerStyle="width:3rem">
@ -35,6 +36,7 @@
<Column field="date" header="Date" style="min-width: 100px"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -242,10 +244,10 @@ const getSeverity = (status) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
},
methods: {
onRowGroupExpand(event) {
this.$toast.add({ severity: 'info', summary: 'Row Group Expanded', detail: 'Value: ' + event.data, life: 3000 });
},

View File

@ -5,6 +5,7 @@
with <i>groupfooter</i> slots.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="customers" rowGroupMode="subheader" groupRowsBy="representative.name" sortMode="single" sortField="representative.name" :sortOrder="1" scrollable scrollHeight="400px" tableStyle="min-width: 50rem">
<template #groupheader="slotProps">
@ -35,6 +36,7 @@
</template>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -260,10 +262,10 @@ const getSeverity = (status) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
},
methods: {
calculateCustomerTotal(name) {
let total = 0;

View File

@ -3,6 +3,7 @@
<p>Specifying <i>selectionMode</i> as <i>multiple</i> on a Column, displays a checkbox inside that column for selection.</p>
<p>The header checkbox toggles the selection state of the whole dataset by default, when paginator is enabled you may add <i>selectAll</i> property and <i>select-all-change</i> event to only control the selection of visible rows.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable v-model:selection="selectedProduct" :value="products" dataKey="id" tableStyle="min-width: 50rem">
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
@ -12,6 +13,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -109,8 +111,10 @@ const metaKey = ref(true);
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -5,6 +5,7 @@
<i>metaKeySelection</i> is present, behavior is changed in a way that selecting a new row requires meta key to be present. Note that in touch enabled devices, DataTable always ignores metaKey.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<div class="flex justify-content-center align-items-center mb-4 gap-2">
<InputSwitch v-model="metaKey" inputId="input-metakey" />
@ -17,6 +18,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -121,8 +123,10 @@ const metaKey = ref(true);
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -5,6 +5,7 @@
trigger selection using the radio buttons.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable v-model:selection="selectedProduct" :value="products" dataKey="id" tableStyle="min-width: 50rem">
<Column selectionMode="single" headerStyle="width: 3rem"></Column>
@ -14,6 +15,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -111,8 +113,10 @@ const metaKey = ref(true);
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>DataTable provides <i>row-select</i> and <i>row-unselect</i> events to listen selection events.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable v-model:selection="selectedProduct" :value="products" selectionMode="single" dataKey="id" :metaKeySelection="false" @rowSelect="onRowSelect" @rowUnselect="onRowUnselect" tableStyle="min-width: 50rem">
<Column field="code" header="Code"></Column>
@ -10,6 +11,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -124,10 +126,10 @@ const onRowUnselect = (event) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
onRowSelect(event) {
this.$toast.add({ severity: 'info', summary: 'Product Selected', detail: 'Name: ' + event.data.name, life: 3000 });
},

View File

@ -9,6 +9,7 @@
setting it to false.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<div class="flex justify-content-center align-items-center mb-4 gap-2">
<InputSwitch v-model="metaKey" inputId="input-metakey" />
@ -21,6 +22,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -125,8 +127,10 @@ const metaKey = ref(true);
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -2,8 +2,18 @@
<DocSectionText v-bind="$attrs">
<p>DataTable with selection, pagination, filtering, sorting and templating.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable v-model:filters="filters" v-model:selection="selectedCustomers" :value="customers" paginator :rows="10" dataKey="id" filterDisplay="menu" :globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']">
<DataTable
v-model:filters="filters"
v-model:selection="selectedCustomers"
:value="customers"
paginator
:rows="10"
dataKey="id"
filterDisplay="menu"
:globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']"
>
<template #header>
<div class="flex justify-content-between">
<Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" />
@ -99,6 +109,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -628,12 +639,12 @@ const getSeverity = (status) => {
created() {
this.initFilters();
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersLarge().then((data) => {
this.customers = this.getCustomers(data);
});
},
methods: {
formatDate(value) {
return value.toLocaleDateString('en-US', {
day: '2-digit',

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>CRUD implementation example with a Dialog.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<Toolbar class="mb-4">
<template #start>
@ -69,6 +70,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<Dialog v-model:visible="productDialog" :style="{ width: '450px' }" header="Product Details" :modal="true" class="p-fluid">
<img v-if="product.image" :src="`https://primefaces.org/cdn/primevue/images/product/${product.image}`" :alt="product.image" class="block m-auto pb-3" />
@ -830,14 +832,13 @@ const getStatusLabel = (status) => {
}
};
},
created() {
this.initFilters();
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProducts().then((data) => (this.products = data));
},
methods: {
formatCurrency(value) {
if (value) return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });

View File

@ -8,7 +8,7 @@
<div class="card flex justify-content-center">
<Button label="Show" icon="pi pi-external-link" @click="dialogVisible = true" />
<Dialog v-model:visible="dialogVisible" header="Flex Scroll" :style="{ width: '75vw' }" maximizable modal :contentStyle="{ height: '300px' }">
<Dialog v-model:visible="dialogVisible" header="Flex Scroll" :style="{ width: '75vw' }" maximizable modal :contentStyle="{ height: '300px' }" @show="onShow">
<DataTable :value="customers" scrollable scrollHeight="flex" tableStyle="min-width: 50rem">
<Column field="name" header="Name"></Column>
<Column field="country.name" header="Country"></Column>
@ -140,10 +140,12 @@ onMounted(() => {
}
};
},
mounted() {
methods: {
onShow() {
CustomerService.getCustomersMedium().then((data) => {
this.customers = data;
});
}
}
};
</script>

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>A column can be fixed during horizontal scrolling by enabling the <i>frozen</i> property. The location is defined with the <i>alignFrozen</i> that can be <i>left</i> or <i>right</i>.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<ToggleButton v-model="balanceFrozen" onIcon="pi pi-lock" offIcon="pi pi-lock-open" onLabel="Balance" offLabel="Balance" />
@ -22,6 +23,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -165,12 +167,12 @@ const formatCurrency = (value) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersLarge().then((data) => {
this.customers = data;
});
},
methods: {
formatCurrency(value) {
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
}

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Rows can be fixed during scrolling by enabling the <i>frozenValue</i> property.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable
:value="customers"
@ -26,6 +27,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -255,12 +257,12 @@ onMounted(() => {
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => {
this.customers = data;
});
},
methods: {
toggleLock(data, frozen, index) {
if (frozen) {
this.lockedCustomers = this.lockedCustomers.filter((c, i) => i !== index);

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Horizontal scrollbar is displayed when table width exceeds the parent width.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="customers" scrollable scrollHeight="400px">
<Column field="id" header="Id" footer="Id" style="min-width: 100px"></Column>
@ -19,6 +20,7 @@
<Column field="representative.name" header="Representative" footer="Representative" style="min-width: 200px"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -152,12 +154,12 @@ const formatCurrency = (value) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => {
this.customers = data;
});
},
methods: {
formatCurrency(value) {
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
}

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Adding <i>scrollable</i> property along with a <i>scrollHeight</i> for the data viewport enables vertical scrolling with fixed headers.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="customers" scrollable scrollHeight="400px" tableStyle="min-width: 50rem">
<Column field="name" header="Name"></Column>
@ -10,6 +11,7 @@
<Column field="company" header="Company"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -107,10 +109,12 @@ onMounted(() => {
}
};
},
mounted() {
methods: {
loadDemoData() {
CustomerService.getCustomersMedium().then((data) => {
this.customers = data;
});
}
}
};
</script>

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Multiple columns can be sorted by defining <i>sortMode</i> as <i>multiple</i>. This mode requires metaKey (e.g. <i></i>) to be pressed when clicking a header.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" sortMode="multiple" tableStyle="min-width: 50rem">
<Column field="code" header="Code" sortable style="width: 25%"></Column>
@ -10,6 +11,7 @@
<Column field="quantity" header="Quantity" sortable style="width: 25%"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -98,8 +100,10 @@ const products = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -5,6 +5,7 @@
<i>DataTableSortMeta</i> objects.
</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" sortField="price" :sortOrder="-1" tableStyle="min-width: 50rem">
<Column field="code" header="Code" sortable style="width: 20%"></Column>
@ -18,6 +19,7 @@
<Column field="quantity" header="Quantity" sortable style="width: 20%"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -129,10 +131,10 @@ const formatCurrency = (value) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
},
methods: {
formatCurrency(value) {
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
}

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>When <i>removableSort</i> is present, the third click removes the sorting from the column.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" removableSort tableStyle="min-width: 50rem">
<Column field="code" header="Code" sortable style="width: 25%"></Column>
@ -10,6 +11,7 @@
<Column field="quantity" header="Quantity" sortable style="width: 25%"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -98,8 +100,10 @@ const products = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -2,6 +2,7 @@
<DocSectionText v-bind="$attrs">
<p>Sorting on a column is enabled by adding the <i>sortable</i> property.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="products" tableStyle="min-width: 50rem">
<Column field="code" header="Code" sortable style="width: 25%"></Column>
@ -10,6 +11,7 @@
<Column field="quantity" header="Quantity" sortable style="width: 25%"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['ProductService']" />
</template>
@ -98,8 +100,10 @@ const products = ref();
}
};
},
mounted() {
methods: {
loadDemoData() {
ProductService.getProductsMini().then((data) => (this.products = data));
}
}
};
</script>

View File

@ -3,6 +3,7 @@
<p>When lazy loading is enabled via the <i>virtualScrollerOptions</i>, data is fetched on demand during scrolling instead of preload.</p>
<p>In sample below, an in-memory list and timeout is used to mimic fetching from a remote datasource. The <i>virtualCars</i> is an empty array that is populated on scroll.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable
:value="virtualCars"
@ -48,6 +49,7 @@
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CarService']" />
</template>
@ -280,10 +282,10 @@ const loadCarsLazy = (event) => {
}
};
},
mounted() {
methods: {
loadDemoData() {
this.cars = Array.from({ length: 100000 }).map((_, i) => CarService.generateCar(i + 1));
},
methods: {
loadCarsLazy(event) {
!this.lazyLoading && (this.lazyLoading = true);

View File

@ -6,6 +6,7 @@
</p>
<p>In this example, <strong>100000</strong> preloaded records are rendered by the Table.</p>
</DocSectionText>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable :value="cars" scrollable scrollHeight="400px" :virtualScrollerOptions="{ itemSize: 46 }" tableStyle="min-width: 50rem">
<Column field="id" header="Id" style="width: 20%"></Column>
@ -15,6 +16,7 @@
<Column field="color" header="Color" style="width: 20%"></Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CarService']" />
</template>
@ -98,8 +100,10 @@ onMounted(() => {
}
};
},
mounted() {
methods: {
loadDemoData() {
this.cars = Array.from({ length: 100000 }).map((_, i) => CarService.generateCar(i + 1));
}
}
};
</script>

View File

@ -1,5 +1,7 @@
import DeferredDemo from '@/components/demo/DeferredDemo.vue';
import CodeHighlight from '@/directives/CodeHighlight';
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('code', CodeHighlight);
nuxtApp.vueApp.component('DeferredDemo', DeferredDemo); // @todo
});