Improve DataTable demo performance
parent
69d9c0875b
commit
27db388223
|
@ -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>
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<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>
|
<p>DataTable requires a <i>value</i> as data to display and <i>Column</i> components as children for the representation.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code"></Column>
|
<DataTable :value="products" tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
<Column field="category" header="Category"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -98,8 +100,10 @@ const products = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,50 +5,52 @@
|
||||||
to span are defined with the <i>colspan</i> and <i>rowspan</i> properties of a Column.
|
to span are defined with the <i>colspan</i> and <i>rowspan</i> properties of a Column.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="sales" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<ColumnGroup type="header">
|
<DataTable :value="sales" tableStyle="min-width: 50rem">
|
||||||
<Row>
|
<ColumnGroup type="header">
|
||||||
<Column header="Product" :rowspan="3" />
|
<Row>
|
||||||
<Column header="Sale Rate" :colspan="4" />
|
<Column header="Product" :rowspan="3" />
|
||||||
</Row>
|
<Column header="Sale Rate" :colspan="4" />
|
||||||
<Row>
|
</Row>
|
||||||
<Column header="Sales" :colspan="2" />
|
<Row>
|
||||||
<Column header="Profits" :colspan="2" />
|
<Column header="Sales" :colspan="2" />
|
||||||
</Row>
|
<Column header="Profits" :colspan="2" />
|
||||||
<Row>
|
</Row>
|
||||||
<Column header="Last Year" sortable field="lastYearSale" />
|
<Row>
|
||||||
<Column header="This Year" sortable field="thisYearSale" />
|
<Column header="Last Year" sortable field="lastYearSale" />
|
||||||
<Column header="Last Year" sortable field="lastYearProfit" />
|
<Column header="This Year" sortable field="thisYearSale" />
|
||||||
<Column header="This Year" sortable field="thisYearProfit" />
|
<Column header="Last Year" sortable field="lastYearProfit" />
|
||||||
</Row>
|
<Column header="This Year" sortable field="thisYearProfit" />
|
||||||
</ColumnGroup>
|
</Row>
|
||||||
<Column field="product" />
|
</ColumnGroup>
|
||||||
<Column field="lastYearSale">
|
<Column field="product" />
|
||||||
<template #body="slotProps"> {{ slotProps.data.lastYearSale }}% </template>
|
<Column field="lastYearSale">
|
||||||
</Column>
|
<template #body="slotProps"> {{ slotProps.data.lastYearSale }}% </template>
|
||||||
<Column field="thisYearSale">
|
</Column>
|
||||||
<template #body="slotProps"> {{ slotProps.data.thisYearSale }}% </template>
|
<Column field="thisYearSale">
|
||||||
</Column>
|
<template #body="slotProps"> {{ slotProps.data.thisYearSale }}% </template>
|
||||||
<Column field="lastYearProfit">
|
</Column>
|
||||||
<template #body="slotProps">
|
<Column field="lastYearProfit">
|
||||||
{{ formatCurrency(slotProps.data.lastYearProfit) }}
|
<template #body="slotProps">
|
||||||
</template>
|
{{ formatCurrency(slotProps.data.lastYearProfit) }}
|
||||||
</Column>
|
</template>
|
||||||
<Column field="thisYearProfit">
|
</Column>
|
||||||
<template #body="slotProps">
|
<Column field="thisYearProfit">
|
||||||
{{ formatCurrency(slotProps.data.thisYearProfit) }}
|
<template #body="slotProps">
|
||||||
</template>
|
{{ formatCurrency(slotProps.data.thisYearProfit) }}
|
||||||
</Column>
|
</template>
|
||||||
<ColumnGroup type="footer">
|
</Column>
|
||||||
<Row>
|
<ColumnGroup type="footer">
|
||||||
<Column footer="Totals:" :colspan="3" footerStyle="text-align:right" />
|
<Row>
|
||||||
<Column :footer="lastYearTotal" />
|
<Column footer="Totals:" :colspan="3" footerStyle="text-align:right" />
|
||||||
<Column :footer="thisYearTotal" />
|
<Column :footer="lastYearTotal" />
|
||||||
</Row>
|
<Column :footer="thisYearTotal" />
|
||||||
</ColumnGroup>
|
</Row>
|
||||||
</DataTable>
|
</ColumnGroup>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" />
|
<DocSectionCode :code="code" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -294,21 +296,21 @@ const thisYearTotal = computed(() => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
this.sales = [
|
|
||||||
{ product: 'Bamboo Watch', lastYearSale: 51, thisYearSale: 40, lastYearProfit: 54406, thisYearProfit: 43342 },
|
|
||||||
{ product: 'Black Watch', lastYearSale: 83, thisYearSale: 9, lastYearProfit: 423132, thisYearProfit: 312122 },
|
|
||||||
{ product: 'Blue Band', lastYearSale: 38, thisYearSale: 5, lastYearProfit: 12321, thisYearProfit: 8500 },
|
|
||||||
{ product: 'Blue T-Shirt', lastYearSale: 49, thisYearSale: 22, lastYearProfit: 745232, thisYearProfit: 65323 },
|
|
||||||
{ product: 'Brown Purse', lastYearSale: 17, thisYearSale: 79, lastYearProfit: 643242, thisYearProfit: 500332 },
|
|
||||||
{ product: 'Chakra Bracelet', lastYearSale: 52, thisYearSale: 65, lastYearProfit: 421132, thisYearProfit: 150005 },
|
|
||||||
{ product: 'Galaxy Earrings', lastYearSale: 82, thisYearSale: 12, lastYearProfit: 131211, thisYearProfit: 100214 },
|
|
||||||
{ product: 'Game Controller', lastYearSale: 44, thisYearSale: 45, lastYearProfit: 66442, thisYearProfit: 53322 },
|
|
||||||
{ product: 'Gaming Set', lastYearSale: 90, thisYearSale: 56, lastYearProfit: 765442, thisYearProfit: 296232 },
|
|
||||||
{ product: 'Gold Phone Case', lastYearSale: 75, thisYearSale: 54, lastYearProfit: 21212, thisYearProfit: 12533 }
|
|
||||||
];
|
|
||||||
},
|
|
||||||
methods: {
|
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 },
|
||||||
|
{ product: 'Blue Band', lastYearSale: 38, thisYearSale: 5, lastYearProfit: 12321, thisYearProfit: 8500 },
|
||||||
|
{ product: 'Blue T-Shirt', lastYearSale: 49, thisYearSale: 22, lastYearProfit: 745232, thisYearProfit: 65323 },
|
||||||
|
{ product: 'Brown Purse', lastYearSale: 17, thisYearSale: 79, lastYearProfit: 643242, thisYearProfit: 500332 },
|
||||||
|
{ product: 'Chakra Bracelet', lastYearSale: 52, thisYearSale: 65, lastYearProfit: 421132, thisYearProfit: 150005 },
|
||||||
|
{ product: 'Galaxy Earrings', lastYearSale: 82, thisYearSale: 12, lastYearProfit: 131211, thisYearProfit: 100214 },
|
||||||
|
{ product: 'Game Controller', lastYearSale: 44, thisYearSale: 45, lastYearProfit: 66442, thisYearProfit: 53322 },
|
||||||
|
{ product: 'Gaming Set', lastYearSale: 90, thisYearSale: 56, lastYearProfit: 765442, thisYearProfit: 296232 },
|
||||||
|
{ product: 'Gold Phone Case', lastYearSale: 75, thisYearSale: 54, lastYearProfit: 21212, thisYearProfit: 12533 }
|
||||||
|
];
|
||||||
|
},
|
||||||
formatCurrency(value) {
|
formatCurrency(value) {
|
||||||
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,19 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<template #header>
|
<DataTable :value="products" tableStyle="min-width: 50rem">
|
||||||
<div style="text-align: left">
|
<template #header>
|
||||||
<MultiSelect :modelValue="selectedColumns" :options="columns" optionLabel="header" @update:modelValue="onToggle" display="chip" placeholder="Select Columns" />
|
<div style="text-align: left">
|
||||||
</div>
|
<MultiSelect :modelValue="selectedColumns" :options="columns" optionLabel="header" @update:modelValue="onToggle" display="chip" placeholder="Select Columns" />
|
||||||
</template>
|
</div>
|
||||||
<Column field="code" header="Code" />
|
</template>
|
||||||
<Column v-for="(col, index) of selectedColumns" :key="col.field + '_' + index" :field="col.field" :header="col.header"></Column>
|
<Column field="code" header="Code" />
|
||||||
</DataTable>
|
<Column v-for="(col, index) of selectedColumns" :key="col.field + '_' + index" :field="col.field" :header="col.header"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -30,7 +32,7 @@ export default {
|
||||||
<DataTable :value="products" tableStyle="min-width: 50rem">
|
<DataTable :value="products" tableStyle="min-width: 50rem">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="text-align:left">
|
<div style="text-align:left">
|
||||||
<MultiSelect :modelValue="selectedColumns" :options="columns" optionLabel="header" @update:modelValue="onToggle"
|
<MultiSelect :modelValue="selectedColumns" :options="columns" optionLabel="header" @update:modelValue="onToggle"
|
||||||
display="chip" placeholder="Select Columns" />
|
display="chip" placeholder="Select Columns" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -44,7 +46,7 @@ export default {
|
||||||
<DataTable :value="products" tableStyle="min-width: 50rem">
|
<DataTable :value="products" tableStyle="min-width: 50rem">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div style="text-align:left">
|
<div style="text-align:left">
|
||||||
<MultiSelect :modelValue="selectedColumns" :options="columns" optionLabel="header" @update:modelValue="onToggle"
|
<MultiSelect :modelValue="selectedColumns" :options="columns" optionLabel="header" @update:modelValue="onToggle"
|
||||||
display="chip" placeholder="Select Columns" />
|
display="chip" placeholder="Select Columns" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -139,7 +141,6 @@ const onToggle = (val) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.columns = [
|
this.columns = [
|
||||||
{ field: 'name', header: 'Name' },
|
{ field: 'name', header: 'Name' },
|
||||||
|
@ -148,10 +149,10 @@ const onToggle = (val) => {
|
||||||
];
|
];
|
||||||
this.selectedColumns = this.columns;
|
this.selectedColumns = this.columns;
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
onToggle(value) {
|
onToggle(value) {
|
||||||
this.selectedColumns = this.columns.filter((col) => value.includes(col));
|
this.selectedColumns = this.columns.filter((col) => value.includes(col));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,20 +2,22 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" :rowClass="rowClass" :rowStyle="rowStyle" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code"></Column>
|
<DataTable :value="products" :rowClass="rowClass" :rowStyle="rowStyle" tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity">
|
<Column field="category" header="Category"></Column>
|
||||||
<template #body="slotProps">
|
<Column field="quantity" header="Quantity">
|
||||||
<div :class="stockClass(slotProps.data)">
|
<template #body="slotProps">
|
||||||
{{ slotProps.data.quantity }}
|
<div :class="stockClass(slotProps.data)">
|
||||||
</div>
|
{{ slotProps.data.quantity }}
|
||||||
</template>
|
</div>
|
||||||
</Column>
|
</template>
|
||||||
</DataTable>
|
</Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -119,7 +121,7 @@ import { ProductService } from '@/service/ProductService';
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
ProductService.getProductsSmall().then((data) => (this.products = data));
|
ProductService.getProductsSmall().then((data) => (this.products = data));
|
||||||
});
|
});
|
||||||
|
|
||||||
const products = ref();
|
const products = ref();
|
||||||
|
|
||||||
const rowClass = (data) => {
|
const rowClass = (data) => {
|
||||||
|
@ -160,10 +162,10 @@ const stockClass = (data) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsSmall().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsSmall().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
rowClass(data) {
|
rowClass(data) {
|
||||||
return [{ 'bg-primary': data.category === 'Fitness' }];
|
return [{ 'bg-primary': data.category === 'Fitness' }];
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,19 +4,21 @@
|
||||||
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.
|
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>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<ContextMenu ref="cm" :model="menuModel" @hide="selectedProduct = null" />
|
<div class="card">
|
||||||
<DataTable v-model:contextMenuSelection="selectedProduct" :value="products" contextMenu @row-contextmenu="onRowContextMenu" tableStyle="min-width: 50rem">
|
<ContextMenu ref="cm" :model="menuModel" @hide="selectedProduct = null" />
|
||||||
<Column field="code" header="Code"></Column>
|
<DataTable v-model:contextMenuSelection="selectedProduct" :value="products" contextMenu @row-contextmenu="onRowContextMenu" tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="price" header="Price">
|
<Column field="category" header="Category"></Column>
|
||||||
<template #body="slotProps">
|
<Column field="price" header="Price">
|
||||||
{{ formatCurrency(slotProps.data.price) }}
|
<template #body="slotProps">
|
||||||
</template>
|
{{ formatCurrency(slotProps.data.price) }}
|
||||||
</Column>
|
</template>
|
||||||
</DataTable>
|
</Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<ContextMenu ref="cm" :model="menuModel" @hide="selectedProduct = null" />
|
<ContextMenu ref="cm" :model="menuModel" @hide="selectedProduct = null" />
|
||||||
<DataTable :value="products" contextMenu v-model:contextMenuSelection="selectedProduct"
|
<DataTable :value="products" contextMenu v-model:contextMenuSelection="selectedProduct"
|
||||||
@rowContextmenu="onRowContextMenu" tableStyle="min-width: 50rem">
|
@rowContextmenu="onRowContextMenu" tableStyle="min-width: 50rem">
|
||||||
<Column field="code" header="Code"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
|
@ -174,10 +176,10 @@ const formatCurrency = (value) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
onRowContextMenu(event) {
|
onRowContextMenu(event) {
|
||||||
this.$refs.cm.show(event.originalEvent);
|
this.$refs.cm.show(event.originalEvent);
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Columns can be created programmatically.</p>
|
<p>Columns can be created programmatically.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header"></Column>
|
<DataTable :value="products" tableStyle="min-width: 50rem">
|
||||||
</DataTable>
|
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -110,8 +112,10 @@ const columns = [
|
||||||
{ field: 'quantity', header: 'Quantity' }
|
{ field: 'quantity', header: 'Quantity' }
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,19 +2,21 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>DataTable can export its data to CSV format.</p>
|
<p>DataTable can export its data to CSV format.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable ref="dt" :value="products" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<template #header>
|
<DataTable ref="dt" :value="products" tableStyle="min-width: 50rem">
|
||||||
<div style="text-align: left">
|
<template #header>
|
||||||
<Button icon="pi pi-external-link" label="Export" @click="exportCSV($event)" />
|
<div style="text-align: left">
|
||||||
</div>
|
<Button icon="pi pi-external-link" label="Export" @click="exportCSV($event)" />
|
||||||
</template>
|
</div>
|
||||||
<Column field="code" header="Code" exportHeader="Product Code"></Column>
|
</template>
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code" exportHeader="Product Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
<Column field="category" header="Category"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -127,10 +129,10 @@ const exportCSV = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
exportCSV() {
|
exportCSV() {
|
||||||
this.$refs.dt.exportCSV();
|
this.$refs.dt.exportCSV();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Enabling <i>showGridlines</i> displays borders between cells.</p>
|
<p>Enabling <i>showGridlines</i> displays borders between cells.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" showGridlines tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code"></Column>
|
<DataTable :value="products" showGridlines tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
<Column field="category" header="Category"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -98,8 +100,10 @@ const products = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,65 +10,67 @@
|
||||||
</p>
|
</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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card p-fluid">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card p-fluid">
|
||||||
ref="dt"
|
<DataTable
|
||||||
v-model:filters="filters"
|
ref="dt"
|
||||||
v-model:selection="selectedCustomers"
|
v-model:filters="filters"
|
||||||
:value="customers"
|
v-model:selection="selectedCustomers"
|
||||||
lazy
|
:value="customers"
|
||||||
paginator
|
lazy
|
||||||
:first="first"
|
paginator
|
||||||
:rows="10"
|
:first="first"
|
||||||
dataKey="id"
|
:rows="10"
|
||||||
:totalRecords="totalRecords"
|
dataKey="id"
|
||||||
:loading="loading"
|
:totalRecords="totalRecords"
|
||||||
@page="onPage($event)"
|
:loading="loading"
|
||||||
@sort="onSort($event)"
|
@page="onPage($event)"
|
||||||
@filter="onFilter($event)"
|
@sort="onSort($event)"
|
||||||
filterDisplay="row"
|
@filter="onFilter($event)"
|
||||||
:globalFilterFields="['name', 'country.name', 'company', 'representative.name']"
|
filterDisplay="row"
|
||||||
:selectAll="selectAll"
|
:globalFilterFields="['name', 'country.name', 'company', 'representative.name']"
|
||||||
@select-all-change="onSelectAllChange"
|
:selectAll="selectAll"
|
||||||
@row-select="onRowSelect"
|
@select-all-change="onSelectAllChange"
|
||||||
@row-unselect="onRowUnselect"
|
@row-select="onRowSelect"
|
||||||
tableStyle="min-width: 75rem"
|
@row-unselect="onRowUnselect"
|
||||||
>
|
tableStyle="min-width: 75rem"
|
||||||
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
|
>
|
||||||
<Column field="name" header="Name" filterMatchMode="startsWith" sortable>
|
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
<Column field="name" header="Name" filterMatchMode="startsWith" sortable>
|
||||||
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search" />
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
</template>
|
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search" />
|
||||||
</Column>
|
</template>
|
||||||
<Column field="country.name" header="Country" filterField="country.name" filterMatchMode="contains" sortable>
|
</Column>
|
||||||
<template #body="{ data }">
|
<Column field="country.name" header="Country" filterField="country.name" filterMatchMode="contains" sortable>
|
||||||
<div class="flex align-items-center gap-2">
|
<template #body="{ data }">
|
||||||
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
<div class="flex align-items-center gap-2">
|
||||||
<span>{{ data.country.name }}</span>
|
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
||||||
</div>
|
<span>{{ data.country.name }}</span>
|
||||||
</template>
|
</div>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
</template>
|
||||||
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search" />
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
</template>
|
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search" />
|
||||||
</Column>
|
</template>
|
||||||
<Column field="company" header="Company" filterMatchMode="contains" sortable>
|
</Column>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
<Column field="company" header="Company" filterMatchMode="contains" sortable>
|
||||||
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search" />
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
</template>
|
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search" />
|
||||||
</Column>
|
</template>
|
||||||
<Column field="representative.name" header="Representative" filterField="representative.name" sortable>
|
</Column>
|
||||||
<template #body="{ data }">
|
<Column field="representative.name" header="Representative" filterField="representative.name" sortable>
|
||||||
<div class="flex align-items-center gap-2">
|
<template #body="{ data }">
|
||||||
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
<div class="flex align-items-center gap-2">
|
||||||
<span>{{ data.representative.name }}</span>
|
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
||||||
</div>
|
<span>{{ data.representative.name }}</span>
|
||||||
</template>
|
</div>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
</template>
|
||||||
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search" />
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
</template>
|
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search" />
|
||||||
</Column>
|
</template>
|
||||||
</DataTable>
|
</Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -213,8 +215,8 @@ export default {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
this.lazyParams = {
|
this.lazyParams = {
|
||||||
first: this.$refs.dt.first,
|
first: 0,
|
||||||
rows: this.$refs.dt.rows,
|
rows: 10,
|
||||||
sortField: null,
|
sortField: null,
|
||||||
sortOrder: null,
|
sortOrder: null,
|
||||||
filters: this.filters
|
filters: this.filters
|
||||||
|
@ -324,8 +326,8 @@ onMounted(() => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
lazyParams.value = {
|
lazyParams.value = {
|
||||||
first: dt.value.first,
|
first: 0,
|
||||||
rows: dt.value.rows,
|
rows: 10,
|
||||||
sortField: null,
|
sortField: null,
|
||||||
sortOrder: null,
|
sortOrder: null,
|
||||||
filters: filters.value
|
filters: filters.value
|
||||||
|
@ -425,20 +427,20 @@ const onRowUnselect = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
this.loading = true;
|
|
||||||
|
|
||||||
this.lazyParams = {
|
|
||||||
first: this.$refs.dt.first,
|
|
||||||
rows: this.$refs.dt.rows,
|
|
||||||
sortField: null,
|
|
||||||
sortOrder: null,
|
|
||||||
filters: this.filters
|
|
||||||
};
|
|
||||||
|
|
||||||
this.loadLazyData();
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
this.lazyParams = {
|
||||||
|
first: 0,
|
||||||
|
rows: 10,
|
||||||
|
sortField: null,
|
||||||
|
sortOrder: null,
|
||||||
|
filters: this.filters
|
||||||
|
};
|
||||||
|
|
||||||
|
this.loadLazyData();
|
||||||
|
},
|
||||||
loadLazyData(event) {
|
loadLazyData(event) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.lazyParams = { ...this.lazyParams, first: event?.first || this.first };
|
this.lazyParams = { ...this.lazyParams, first: event?.first || this.first };
|
||||||
|
|
|
@ -6,12 +6,14 @@
|
||||||
the rows after reorder completes.
|
the rows after reorder completes.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" reorderableColumns @column-reorder="onColReorder" @row-reorder="onRowReorder" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column rowReorder headerStyle="width: 3rem" :reorderableColumn="false" />
|
<DataTable :value="products" reorderableColumns @column-reorder="onColReorder" @row-reorder="onRowReorder" tableStyle="min-width: 50rem">
|
||||||
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header"></Column>
|
<Column rowReorder headerStyle="width: 3rem" :reorderableColumn="false" />
|
||||||
</DataTable>
|
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -72,7 +74,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<\/script>
|
<\/script>
|
||||||
|
|
||||||
`,
|
`,
|
||||||
composition: `
|
composition: `
|
||||||
|
@ -112,7 +114,7 @@ const onRowReorder = (event) => {
|
||||||
toast.add({severity:'success', summary: 'Rows Reordered', life: 3000});
|
toast.add({severity:'success', summary: 'Rows Reordered', life: 3000});
|
||||||
};
|
};
|
||||||
|
|
||||||
<\/script>
|
<\/script>
|
||||||
`,
|
`,
|
||||||
data: `
|
data: `
|
||||||
{
|
{
|
||||||
|
@ -139,10 +141,10 @@ const onRowReorder = (event) => {
|
||||||
{ field: 'quantity', header: 'Quantity' }
|
{ field: 'quantity', header: 'Quantity' }
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
onColReorder() {
|
onColReorder() {
|
||||||
this.$toast.add({ severity: 'success', summary: 'Column Reordered', life: 3000 });
|
this.$toast.add({ severity: 'success', summary: 'Column Reordered', life: 3000 });
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,64 +9,66 @@
|
||||||
<i>{'1004': true}</i>. The <i>dataKey</i> alternative is more performant for large amounts of data.
|
<i>{'1004': true}</i>. The <i>dataKey</i> alternative is more performant for large amounts of data.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable v-model:expandedRows="expandedRows" :value="products" dataKey="id" @rowExpand="onRowExpand" @rowCollapse="onRowCollapse" tableStyle="min-width: 60rem">
|
<div class="card">
|
||||||
<template #header>
|
<DataTable v-model:expandedRows="expandedRows" :value="products" dataKey="id" @rowExpand="onRowExpand" @rowCollapse="onRowCollapse" tableStyle="min-width: 60rem">
|
||||||
<div class="flex flex-wrap justify-content-end gap-2">
|
<template #header>
|
||||||
<Button text icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
<div class="flex flex-wrap justify-content-end gap-2">
|
||||||
<Button text icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
<Button text icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
||||||
</div>
|
<Button text icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||||
</template>
|
</div>
|
||||||
<Column expander style="width: 5rem" />
|
|
||||||
<Column field="name" header="Name"></Column>
|
|
||||||
<Column header="Image">
|
|
||||||
<template #body="slotProps">
|
|
||||||
<img :src="`https://primefaces.org/cdn/primevue/images/product/${slotProps.data.image}`" :alt="slotProps.data.image" class="shadow-4" width="64" />
|
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
<Column expander style="width: 5rem" />
|
||||||
<Column field="price" header="Price">
|
<Column field="name" header="Name"></Column>
|
||||||
<template #body="slotProps">
|
<Column header="Image">
|
||||||
{{ formatCurrency(slotProps.data.price) }}
|
<template #body="slotProps">
|
||||||
|
<img :src="`https://primefaces.org/cdn/primevue/images/product/${slotProps.data.image}`" :alt="slotProps.data.image" class="shadow-4" width="64" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="price" header="Price">
|
||||||
|
<template #body="slotProps">
|
||||||
|
{{ formatCurrency(slotProps.data.price) }}
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="category" header="Category"></Column>
|
||||||
|
<Column field="rating" header="Reviews">
|
||||||
|
<template #body="slotProps">
|
||||||
|
<Rating :modelValue="slotProps.data.rating" readonly :cancel="false" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column header="Status">
|
||||||
|
<template #body="slotProps">
|
||||||
|
<Tag :value="slotProps.data.inventoryStatus" :severity="getSeverity(slotProps.data)" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<template #expansion="slotProps">
|
||||||
|
<div class="p-3">
|
||||||
|
<h5>Orders for {{ slotProps.data.name }}</h5>
|
||||||
|
<DataTable :value="slotProps.data.orders">
|
||||||
|
<Column field="id" header="Id" sortable></Column>
|
||||||
|
<Column field="customer" header="Customer" sortable></Column>
|
||||||
|
<Column field="date" header="Date" sortable></Column>
|
||||||
|
<Column field="amount" header="Amount" sortable>
|
||||||
|
<template #body="slotProps">
|
||||||
|
{{ formatCurrency(slotProps.data.amount) }}
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="status" header="Status" sortable>
|
||||||
|
<template #body="slotProps">
|
||||||
|
<Tag :value="slotProps.data.status.toLowerCase()" :severity="getOrderSeverity(slotProps.data)" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column headerStyle="width:4rem">
|
||||||
|
<template #body>
|
||||||
|
<Button icon="pi pi-search" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</DataTable>
|
||||||
<Column field="category" header="Category"></Column>
|
</div>
|
||||||
<Column field="rating" header="Reviews">
|
</DeferredDemo>
|
||||||
<template #body="slotProps">
|
|
||||||
<Rating :modelValue="slotProps.data.rating" readonly :cancel="false" />
|
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
<Column header="Status">
|
|
||||||
<template #body="slotProps">
|
|
||||||
<Tag :value="slotProps.data.inventoryStatus" :severity="getSeverity(slotProps.data)" />
|
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
<template #expansion="slotProps">
|
|
||||||
<div class="p-3">
|
|
||||||
<h5>Orders for {{ slotProps.data.name }}</h5>
|
|
||||||
<DataTable :value="slotProps.data.orders">
|
|
||||||
<Column field="id" header="Id" sortable></Column>
|
|
||||||
<Column field="customer" header="Customer" sortable></Column>
|
|
||||||
<Column field="date" header="Date" sortable></Column>
|
|
||||||
<Column field="amount" header="Amount" sortable>
|
|
||||||
<template #body="slotProps">
|
|
||||||
{{ formatCurrency(slotProps.data.amount) }}
|
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
<Column field="status" header="Status" sortable>
|
|
||||||
<template #body="slotProps">
|
|
||||||
<Tag :value="slotProps.data.status.toLowerCase()" :severity="getOrderSeverity(slotProps.data)" />
|
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
<Column headerStyle="width:4rem">
|
|
||||||
<template #body>
|
|
||||||
<Button icon="pi pi-search" />
|
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
</DataTable>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</DataTable>
|
|
||||||
</div>
|
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -426,10 +428,10 @@ const getOrderSeverity = (order) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsWithOrdersSmall().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsWithOrdersSmall().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
onRowExpand(event) {
|
onRowExpand(event) {
|
||||||
this.$toast.add({ severity: 'info', summary: 'Product Expanded', detail: event.data.name, life: 3000 });
|
this.$toast.add({ severity: 'info', summary: 'Product Expanded', detail: event.data.name, life: 3000 });
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,17 +2,19 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>In addition to a regular table, alternatives with alternative sizes are available.</p>
|
<p>In addition to a regular table, alternatives with alternative sizes are available.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<div class="flex justify-content-center mb-4">
|
<div class="card">
|
||||||
<SelectButton v-model="size" :options="sizeOptions" optionLabel="label" dataKey="label" />
|
<div class="flex justify-content-center mb-4">
|
||||||
|
<SelectButton v-model="size" :options="sizeOptions" optionLabel="label" dataKey="label" />
|
||||||
|
</div>
|
||||||
|
<DataTable :value="products" :size="size.value" tableStyle="min-width: 50rem">
|
||||||
|
<Column field="code" header="Code"></Column>
|
||||||
|
<Column field="name" header="Name"></Column>
|
||||||
|
<Column field="category" header="Category"></Column>
|
||||||
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
<DataTable :value="products" :size="size.value" tableStyle="min-width: 50rem">
|
</DeferredDemo>
|
||||||
<Column field="code" header="Code"></Column>
|
|
||||||
<Column field="name" header="Name"></Column>
|
|
||||||
<Column field="category" header="Category"></Column>
|
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
|
||||||
</DataTable>
|
|
||||||
</div>
|
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -126,8 +128,10 @@ const sizeOptions = ref([
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -6,76 +6,78 @@
|
||||||
browser is closed. Other alternative is <i>local</i> referring to <i>localStorage</i> for an extended lifetime.
|
browser is closed. Other alternative is <i>local</i> referring to <i>localStorage</i> for an extended lifetime.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card">
|
||||||
v-model:filters="filters"
|
<DataTable
|
||||||
v-model:selection="selectedCustomer"
|
v-model:filters="filters"
|
||||||
:value="customers"
|
v-model:selection="selectedCustomer"
|
||||||
stateStorage="session"
|
:value="customers"
|
||||||
stateKey="dt-state-demo-session"
|
stateStorage="session"
|
||||||
paginator
|
stateKey="dt-state-demo-session"
|
||||||
:rows="5"
|
paginator
|
||||||
filterDisplay="menu"
|
:rows="5"
|
||||||
selectionMode="single"
|
filterDisplay="menu"
|
||||||
dataKey="id"
|
selectionMode="single"
|
||||||
:globalFilterFields="['name', 'country.name', 'representative.name', 'status']"
|
dataKey="id"
|
||||||
tableStyle="min-width: 50rem"
|
:globalFilterFields="['name', 'country.name', 'representative.name', 'status']"
|
||||||
>
|
tableStyle="min-width: 50rem"
|
||||||
<template #header>
|
>
|
||||||
<span class="p-input-icon-left">
|
<template #header>
|
||||||
<i class="pi pi-search" />
|
<span class="p-input-icon-left">
|
||||||
<InputText v-model="filters['global'].value" placeholder="Global Search" />
|
<i class="pi pi-search" />
|
||||||
</span>
|
<InputText v-model="filters['global'].value" placeholder="Global Search" />
|
||||||
</template>
|
</span>
|
||||||
<Column field="name" header="Name" sortable style="width: 25%">
|
|
||||||
<template #filter="{ filterModel }">
|
|
||||||
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
|
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
<Column field="name" header="Name" sortable style="width: 25%">
|
||||||
<Column header="Country" sortable sortField="country.name" filterField="country.name" filterMatchMode="contains" style="width: 25%">
|
<template #filter="{ filterModel }">
|
||||||
<template #body="{ data }">
|
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
|
||||||
<div class="flex align-items-center gap-2">
|
</template>
|
||||||
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
</Column>
|
||||||
<span>{{ data.country.name }}</span>
|
<Column header="Country" sortable sortField="country.name" filterField="country.name" filterMatchMode="contains" style="width: 25%">
|
||||||
</div>
|
<template #body="{ data }">
|
||||||
</template>
|
<div class="flex align-items-center gap-2">
|
||||||
<template #filter="{ filterModel }">
|
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
||||||
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
|
<span>{{ data.country.name }}</span>
|
||||||
</template>
|
</div>
|
||||||
</Column>
|
</template>
|
||||||
<Column header="Representative" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="width: 25%">
|
<template #filter="{ filterModel }">
|
||||||
<template #body="{ data }">
|
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
|
||||||
<div class="flex align-items-center gap-2">
|
</template>
|
||||||
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
</Column>
|
||||||
<span>{{ data.representative.name }}</span>
|
<Column header="Representative" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="width: 25%">
|
||||||
</div>
|
<template #body="{ data }">
|
||||||
</template>
|
<div class="flex align-items-center gap-2">
|
||||||
<template #filter="{ filterModel }">
|
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
||||||
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
|
<span>{{ data.representative.name }}</span>
|
||||||
<template #option="slotProps">
|
</div>
|
||||||
<div class="flex align-items-center gap-2">
|
</template>
|
||||||
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
|
<template #filter="{ filterModel }">
|
||||||
<span>{{ slotProps.option.name }}</span>
|
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
|
||||||
</div>
|
<template #option="slotProps">
|
||||||
</template>
|
<div class="flex align-items-center gap-2">
|
||||||
</MultiSelect>
|
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
|
||||||
</template>
|
<span>{{ slotProps.option.name }}</span>
|
||||||
</Column>
|
</div>
|
||||||
<Column field="status" header="Status" sortable filterMatchMode="equals" style="width: 25%">
|
</template>
|
||||||
<template #body="{ data }">
|
</MultiSelect>
|
||||||
<Tag :value="data.status" :severity="getSeverity(data.status)" />
|
</template>
|
||||||
</template>
|
</Column>
|
||||||
<template #filter="{ filterModel }">
|
<Column field="status" header="Status" sortable filterMatchMode="equals" style="width: 25%">
|
||||||
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear>
|
<template #body="{ data }">
|
||||||
<template #option="slotProps">
|
<Tag :value="data.status" :severity="getSeverity(data.status)" />
|
||||||
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
|
</template>
|
||||||
</template>
|
<template #filter="{ filterModel }">
|
||||||
</Dropdown>
|
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear>
|
||||||
</template>
|
<template #option="slotProps">
|
||||||
</Column>
|
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
|
||||||
<template #empty> No customers found. </template>
|
</template>
|
||||||
</DataTable>
|
</Dropdown>
|
||||||
</div>
|
</template>
|
||||||
|
</Column>
|
||||||
|
<template #empty> No customers found. </template>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -433,10 +435,10 @@ const getSeverity = (status) => {
|
||||||
created() {
|
created() {
|
||||||
this.initFilters();
|
this.initFilters();
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersSmall().then((data) => (this.customers = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersSmall().then((data) => (this.customers = data));
|
||||||
|
},
|
||||||
initFilters() {
|
initFilters() {
|
||||||
this.filters = {
|
this.filters = {
|
||||||
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Alternating rows are displayed when <i>stripedRows</i> property is present.</p>
|
<p>Alternating rows are displayed when <i>stripedRows</i> property is present.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" stripedRows tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code"></Column>
|
<DataTable :value="products" stripedRows tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
<Column field="category" header="Category"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -98,8 +100,10 @@ const products = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,39 +2,41 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Custom content at <i>header</i> and <i>footer</i> sections are supported via templating.</p>
|
<p>Custom content at <i>header</i> and <i>footer</i> sections are supported via templating.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<template #header>
|
<DataTable :value="products" tableStyle="min-width: 50rem">
|
||||||
<div class="flex flex-wrap align-items-center justify-content-between gap-2">
|
<template #header>
|
||||||
<span class="text-xl text-900 font-bold">Products</span>
|
<div class="flex flex-wrap align-items-center justify-content-between gap-2">
|
||||||
<Button icon="pi pi-refresh" rounded raised />
|
<span class="text-xl text-900 font-bold">Products</span>
|
||||||
</div>
|
<Button icon="pi pi-refresh" rounded raised />
|
||||||
</template>
|
</div>
|
||||||
<Column field="name" header="Name"></Column>
|
|
||||||
<Column header="Image">
|
|
||||||
<template #body="slotProps">
|
|
||||||
<img :src="`https://primefaces.org/cdn/primevue/images/product/${slotProps.data.image}`" :alt="slotProps.data.image" class="w-6rem shadow-2 border-round" />
|
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="price" header="Price">
|
<Column header="Image">
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
{{ formatCurrency(slotProps.data.price) }}
|
<img :src="`https://primefaces.org/cdn/primevue/images/product/${slotProps.data.image}`" :alt="slotProps.data.image" class="w-6rem shadow-2 border-round" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="price" header="Price">
|
||||||
<Column field="rating" header="Reviews">
|
<template #body="slotProps">
|
||||||
<template #body="slotProps">
|
{{ formatCurrency(slotProps.data.price) }}
|
||||||
<Rating :modelValue="slotProps.data.rating" readonly :cancel="false" />
|
</template>
|
||||||
</template>
|
</Column>
|
||||||
</Column>
|
<Column field="category" header="Category"></Column>
|
||||||
<Column header="Status">
|
<Column field="rating" header="Reviews">
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
<Tag :value="slotProps.data.inventoryStatus" :severity="getSeverity(slotProps.data)" />
|
<Rating :modelValue="slotProps.data.rating" readonly :cancel="false" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<template #footer> In total there are {{ products ? products.length : 0 }} products. </template>
|
<Column header="Status">
|
||||||
</DataTable>
|
<template #body="slotProps">
|
||||||
</div>
|
<Tag :value="slotProps.data.inventoryStatus" :severity="getSeverity(slotProps.data)" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<template #footer> In total there are {{ products ? products.length : 0 }} products. </template>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -236,10 +238,10 @@ const getSeverity = (product) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
formatCurrency(value) {
|
formatCurrency(value) {
|
||||||
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Setting <i>columnResizeMode</i> as <i>expand</i> changes the table width as well.</p>
|
<p>Setting <i>columnResizeMode</i> as <i>expand</i> changes the table width as well.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" resizableColumns columnResizeMode="expand" showGridlines tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code"></Column>
|
<DataTable :value="products" resizableColumns columnResizeMode="expand" showGridlines tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
<Column field="category" header="Category"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -96,8 +98,10 @@ const products = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,14 +5,16 @@
|
||||||
that does not change the overall table width.
|
that does not change the overall table width.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" resizableColumns columnResizeMode="fit" showGridlines tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code"></Column>
|
<DataTable :value="products" resizableColumns columnResizeMode="fit" showGridlines tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
<Column field="category" header="Category"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -99,8 +101,10 @@ const products = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,35 +2,37 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card p-fluid">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card p-fluid">
|
||||||
:value="products"
|
<DataTable
|
||||||
editMode="cell"
|
:value="products"
|
||||||
@cell-edit-complete="onCellEditComplete"
|
editMode="cell"
|
||||||
:pt="{
|
@cell-edit-complete="onCellEditComplete"
|
||||||
table: { style: 'min-width: 50rem' },
|
:pt="{
|
||||||
column: {
|
table: { style: 'min-width: 50rem' },
|
||||||
bodycell: ({ state }) => ({
|
column: {
|
||||||
class: [{ 'pt-0 pb-0': state['d_editing'] }]
|
bodycell: ({ state }) => ({
|
||||||
})
|
class: [{ 'pt-0 pb-0': state['d_editing'] }]
|
||||||
}
|
})
|
||||||
}"
|
}
|
||||||
>
|
}"
|
||||||
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header" style="width: 25%">
|
>
|
||||||
<template #body="{ data, field }">
|
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header" style="width: 25%">
|
||||||
{{ field === 'price' ? formatCurrency(data[field]) : data[field] }}
|
<template #body="{ data, field }">
|
||||||
</template>
|
{{ field === 'price' ? formatCurrency(data[field]) : data[field] }}
|
||||||
<template #editor="{ data, field }">
|
|
||||||
<template v-if="field !== 'price'">
|
|
||||||
<InputText v-model="data[field]" autofocus />
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template #editor="{ data, field }">
|
||||||
<InputNumber v-model="data[field]" mode="currency" currency="USD" locale="en-US" autofocus />
|
<template v-if="field !== 'price'">
|
||||||
|
<InputText v-model="data[field]" autofocus />
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<InputNumber v-model="data[field]" mode="currency" currency="USD" locale="en-US" autofocus />
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</Column>
|
||||||
</Column>
|
</DataTable>
|
||||||
</DataTable>
|
</div>
|
||||||
</div>
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" :dependencies="{ sass: '1.45.0', 'sass-loader': '8.0.2' }" />
|
<DocSectionCode :code="code" :service="['ProductService']" :dependencies="{ sass: '1.45.0', 'sass-loader': '8.0.2' }" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -260,10 +262,10 @@ const formatCurrency = (value) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
onCellEditComplete(event) {
|
onCellEditComplete(event) {
|
||||||
let { data, newValue, field } = event;
|
let { data, newValue, field } = event;
|
||||||
|
|
||||||
|
|
|
@ -2,32 +2,34 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Cell Editing with Sorting and Filter</p>
|
<p>Cell Editing with Sorting and Filter</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card p-fluid">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card p-fluid">
|
||||||
v-model:filters="filters"
|
<DataTable
|
||||||
:value="products"
|
v-model:filters="filters"
|
||||||
editMode="cell"
|
:value="products"
|
||||||
@cell-edit-complete="onCellEditComplete"
|
editMode="cell"
|
||||||
filterDisplay="row"
|
@cell-edit-complete="onCellEditComplete"
|
||||||
:pt="{
|
filterDisplay="row"
|
||||||
table: { style: 'min-width: 50rem' },
|
:pt="{
|
||||||
column: {
|
table: { style: 'min-width: 50rem' },
|
||||||
bodycell: ({ state }) => ({
|
column: {
|
||||||
class: [{ 'pt-0 pb-0': state['d_editing'] }]
|
bodycell: ({ state }) => ({
|
||||||
})
|
class: [{ 'pt-0 pb-0': state['d_editing'] }]
|
||||||
}
|
})
|
||||||
}"
|
}
|
||||||
>
|
}"
|
||||||
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header" style="width: 25%" sortable filter>
|
>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header" style="width: 25%" sortable filter>
|
||||||
<InputText v-model="filterModel.value" v-tooltip.top.focus="'Hit enter key to filter'" type="text" @keydown.enter="filterCallback()" class="p-column-filter" />
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
</template>
|
<InputText v-model="filterModel.value" v-tooltip.top.focus="'Hit enter key to filter'" type="text" @keydown.enter="filterCallback()" class="p-column-filter" />
|
||||||
<template #editor="{ data, field }">
|
</template>
|
||||||
<InputText v-model="data[field]" autofocus />
|
<template #editor="{ data, field }">
|
||||||
</template>
|
<InputText v-model="data[field]" autofocus />
|
||||||
</Column>
|
</template>
|
||||||
</DataTable>
|
</Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" :dependencies="{ sass: '1.45.0', 'sass-loader': '8.0.2' }" />
|
<DocSectionCode :code="code" :service="['ProductService']" :dependencies="{ sass: '1.45.0', 'sass-loader': '8.0.2' }" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -271,10 +273,10 @@ const isPositiveInteger = (val) => {
|
||||||
{ field: 'price', header: 'Price' }
|
{ field: 'price', header: 'Price' }
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
onCellEditComplete(event) {
|
onCellEditComplete(event) {
|
||||||
let { data, newValue, field } = event;
|
let { data, newValue, field } = event;
|
||||||
|
|
||||||
|
|
|
@ -5,55 +5,57 @@
|
||||||
<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.
|
<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>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card p-fluid">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card p-fluid">
|
||||||
v-model:editingRows="editingRows"
|
<DataTable
|
||||||
:value="products"
|
v-model:editingRows="editingRows"
|
||||||
editMode="row"
|
:value="products"
|
||||||
dataKey="id"
|
editMode="row"
|
||||||
@row-edit-save="onRowEditSave"
|
dataKey="id"
|
||||||
:pt="{
|
@row-edit-save="onRowEditSave"
|
||||||
table: { style: 'min-width: 50rem' },
|
:pt="{
|
||||||
column: {
|
table: { style: 'min-width: 50rem' },
|
||||||
bodycell: ({ state }) => ({
|
column: {
|
||||||
style: state['d_editing'] && 'padding-top: 0.6rem; padding-bottom: 0.6rem'
|
bodycell: ({ state }) => ({
|
||||||
})
|
style: state['d_editing'] && 'padding-top: 0.6rem; padding-bottom: 0.6rem'
|
||||||
}
|
})
|
||||||
}"
|
}
|
||||||
>
|
}"
|
||||||
<Column field="code" header="Code" style="width: 20%">
|
>
|
||||||
<template #editor="{ data, field }">
|
<Column field="code" header="Code" style="width: 20%">
|
||||||
<InputText v-model="data[field]" />
|
<template #editor="{ data, field }">
|
||||||
</template>
|
<InputText v-model="data[field]" />
|
||||||
</Column>
|
</template>
|
||||||
<Column field="name" header="Name" style="width: 20%">
|
</Column>
|
||||||
<template #editor="{ data, field }">
|
<Column field="name" header="Name" style="width: 20%">
|
||||||
<InputText v-model="data[field]" />
|
<template #editor="{ data, field }">
|
||||||
</template>
|
<InputText v-model="data[field]" />
|
||||||
</Column>
|
</template>
|
||||||
<Column field="inventoryStatus" header="Status" style="width: 20%">
|
</Column>
|
||||||
<template #editor="{ data, field }">
|
<Column field="inventoryStatus" header="Status" style="width: 20%">
|
||||||
<Dropdown v-model="data[field]" :options="statuses" optionLabel="label" optionValue="value" placeholder="Select a Status">
|
<template #editor="{ data, field }">
|
||||||
<template #option="slotProps">
|
<Dropdown v-model="data[field]" :options="statuses" optionLabel="label" optionValue="value" placeholder="Select a Status">
|
||||||
<Tag :value="slotProps.option.value" :severity="getStatusLabel(slotProps.option.value)" />
|
<template #option="slotProps">
|
||||||
</template>
|
<Tag :value="slotProps.option.value" :severity="getStatusLabel(slotProps.option.value)" />
|
||||||
</Dropdown>
|
</template>
|
||||||
</template>
|
</Dropdown>
|
||||||
<template #body="slotProps">
|
</template>
|
||||||
<Tag :value="slotProps.data.inventoryStatus" :severity="getStatusLabel(slotProps.data.inventoryStatus)" />
|
<template #body="slotProps">
|
||||||
</template>
|
<Tag :value="slotProps.data.inventoryStatus" :severity="getStatusLabel(slotProps.data.inventoryStatus)" />
|
||||||
</Column>
|
</template>
|
||||||
<Column field="price" header="Price" style="width: 20%">
|
</Column>
|
||||||
<template #body="{ data, field }">
|
<Column field="price" header="Price" style="width: 20%">
|
||||||
{{ formatCurrency(data[field]) }}
|
<template #body="{ data, field }">
|
||||||
</template>
|
{{ formatCurrency(data[field]) }}
|
||||||
<template #editor="{ data, field }">
|
</template>
|
||||||
<InputNumber v-model="data[field]" mode="currency" currency="USD" locale="en-US" />
|
<template #editor="{ data, field }">
|
||||||
</template>
|
<InputNumber v-model="data[field]" mode="currency" currency="USD" locale="en-US" />
|
||||||
</Column>
|
</template>
|
||||||
<Column :rowEditor="true" style="width: 10%; min-width: 8rem" bodyStyle="text-align:center"></Column>
|
</Column>
|
||||||
</DataTable>
|
<Column :rowEditor="true" style="width: 10%; min-width: 8rem" bodyStyle="text-align:center"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" :dependencies="{ sass: '1.45.0', 'sass-loader': '8.0.2' }" />
|
<DocSectionCode :code="code" :service="['ProductService']" :dependencies="{ sass: '1.45.0', 'sass-loader': '8.0.2' }" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -77,7 +79,7 @@ export default {
|
||||||
table: { style: 'min-width: 50rem' },
|
table: { style: 'min-width: 50rem' },
|
||||||
column: {
|
column: {
|
||||||
bodycell: ({ state }) => ({
|
bodycell: ({ state }) => ({
|
||||||
style: state['d_editing']&&'padding-top: 0.6rem; padding-bottom: 0.6rem'
|
style: state['d_editing']&&'padding-top: 0.6rem; padding-bottom: 0.6rem'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
|
@ -123,7 +125,7 @@ export default {
|
||||||
table: { style: 'min-width: 50rem' },
|
table: { style: 'min-width: 50rem' },
|
||||||
column: {
|
column: {
|
||||||
bodycell: ({ state }) => ({
|
bodycell: ({ state }) => ({
|
||||||
style: state['d_editing']&&'padding-top: 0.6rem; padding-bottom: 0.6rem'
|
style: state['d_editing']&&'padding-top: 0.6rem; padding-bottom: 0.6rem'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
|
@ -217,7 +219,7 @@ export default {
|
||||||
table: { style: 'min-width: 50rem' },
|
table: { style: 'min-width: 50rem' },
|
||||||
column: {
|
column: {
|
||||||
bodycell: ({ state }) => ({
|
bodycell: ({ state }) => ({
|
||||||
style: state['d_editing']&&'padding-top: 0.6rem; padding-bottom: 0.6rem'
|
style: state['d_editing']&&'padding-top: 0.6rem; padding-bottom: 0.6rem'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
|
@ -317,10 +319,10 @@ const formatCurrency = (value) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
onRowEditSave(event) {
|
onRowEditSave(event) {
|
||||||
let { newData, index } = event;
|
let { newData, index } = event;
|
||||||
|
|
||||||
|
|
|
@ -2,116 +2,118 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<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']">
|
<div class="card">
|
||||||
<template #header>
|
<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']">
|
||||||
<div class="flex justify-content-between">
|
<template #header>
|
||||||
<Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" />
|
<div class="flex justify-content-between">
|
||||||
<span class="p-input-icon-left">
|
<Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" />
|
||||||
<i class="pi pi-search" />
|
<span class="p-input-icon-left">
|
||||||
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
|
<i class="pi pi-search" />
|
||||||
</span>
|
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
|
||||||
</div>
|
</span>
|
||||||
</template>
|
|
||||||
<template #empty> No customers found. </template>
|
|
||||||
<template #loading> Loading customers data. Please wait. </template>
|
|
||||||
<Column field="name" header="Name" style="min-width: 12rem">
|
|
||||||
<template #body="{ data }">
|
|
||||||
{{ data.name }}
|
|
||||||
</template>
|
|
||||||
<template #filter="{ filterModel }">
|
|
||||||
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
|
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
<Column header="Country" filterField="country.name" style="min-width: 12rem">
|
|
||||||
<template #body="{ data }">
|
|
||||||
<div class="flex align-items-center gap-2">
|
|
||||||
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
|
||||||
<span>{{ data.country.name }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel }">
|
<template #empty> No customers found. </template>
|
||||||
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
|
<template #loading> Loading customers data. Please wait. </template>
|
||||||
</template>
|
<Column field="name" header="Name" style="min-width: 12rem">
|
||||||
<template #filterclear="{ filterCallback }">
|
<template #body="{ data }">
|
||||||
<Button type="button" icon="pi pi-times" @click="filterCallback()" severity="secondary"></Button>
|
{{ data.name }}
|
||||||
</template>
|
</template>
|
||||||
<template #filterapply="{ filterCallback }">
|
<template #filter="{ filterModel }">
|
||||||
<Button type="button" icon="pi pi-check" @click="filterCallback()" severity="success"></Button>
|
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
|
||||||
</template>
|
</template>
|
||||||
<template #filterfooter>
|
</Column>
|
||||||
<div class="px-3 pt-0 pb-3 text-center">Customized Buttons</div>
|
<Column header="Country" filterField="country.name" style="min-width: 12rem">
|
||||||
</template>
|
<template #body="{ data }">
|
||||||
</Column>
|
<div class="flex align-items-center gap-2">
|
||||||
<Column header="Agent" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
|
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
||||||
<template #body="{ data }">
|
<span>{{ data.country.name }}</span>
|
||||||
<div class="flex align-items-center gap-2">
|
</div>
|
||||||
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
</template>
|
||||||
<span>{{ data.representative.name }}</span>
|
<template #filter="{ filterModel }">
|
||||||
</div>
|
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel }">
|
<template #filterclear="{ filterCallback }">
|
||||||
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
|
<Button type="button" icon="pi pi-times" @click="filterCallback()" severity="secondary"></Button>
|
||||||
<template #option="slotProps">
|
</template>
|
||||||
<div class="flex align-items-center gap-2">
|
<template #filterapply="{ filterCallback }">
|
||||||
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
|
<Button type="button" icon="pi pi-check" @click="filterCallback()" severity="success"></Button>
|
||||||
<span>{{ slotProps.option.name }}</span>
|
</template>
|
||||||
</div>
|
<template #filterfooter>
|
||||||
</template>
|
<div class="px-3 pt-0 pb-3 text-center">Customized Buttons</div>
|
||||||
</MultiSelect>
|
</template>
|
||||||
</template>
|
</Column>
|
||||||
</Column>
|
<Column header="Agent" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
|
||||||
<Column header="Date" filterField="date" dataType="date" style="min-width: 10rem">
|
<template #body="{ data }">
|
||||||
<template #body="{ data }">
|
<div class="flex align-items-center gap-2">
|
||||||
{{ formatDate(data.date) }}
|
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
||||||
</template>
|
<span>{{ data.representative.name }}</span>
|
||||||
<template #filter="{ filterModel }">
|
</div>
|
||||||
<Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />
|
</template>
|
||||||
</template>
|
<template #filter="{ filterModel }">
|
||||||
</Column>
|
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
|
||||||
<Column header="Balance" filterField="balance" dataType="numeric" style="min-width: 10rem">
|
<template #option="slotProps">
|
||||||
<template #body="{ data }">
|
<div class="flex align-items-center gap-2">
|
||||||
{{ formatCurrency(data.balance) }}
|
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
|
||||||
</template>
|
<span>{{ slotProps.option.name }}</span>
|
||||||
<template #filter="{ filterModel }">
|
</div>
|
||||||
<InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" />
|
</template>
|
||||||
</template>
|
</MultiSelect>
|
||||||
</Column>
|
</template>
|
||||||
<Column header="Status" field="status" :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem">
|
</Column>
|
||||||
<template #body="{ data }">
|
<Column header="Date" filterField="date" dataType="date" style="min-width: 10rem">
|
||||||
<Tag :value="data.status" :severity="getSeverity(data.status)" />
|
<template #body="{ data }">
|
||||||
</template>
|
{{ formatDate(data.date) }}
|
||||||
<template #filter="{ filterModel }">
|
</template>
|
||||||
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear>
|
<template #filter="{ filterModel }">
|
||||||
<template #option="slotProps">
|
<Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />
|
||||||
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
|
</template>
|
||||||
</template>
|
</Column>
|
||||||
</Dropdown>
|
<Column header="Balance" filterField="balance" dataType="numeric" style="min-width: 10rem">
|
||||||
</template>
|
<template #body="{ data }">
|
||||||
</Column>
|
{{ formatCurrency(data.balance) }}
|
||||||
<Column field="activity" header="Activity" :showFilterMatchModes="false" style="min-width: 12rem">
|
</template>
|
||||||
<template #body="{ data }">
|
<template #filter="{ filterModel }">
|
||||||
<ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar>
|
<InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" />
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel }">
|
</Column>
|
||||||
<Slider v-model="filterModel.value" range class="m-3"></Slider>
|
<Column header="Status" field="status" :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem">
|
||||||
<div class="flex align-items-center justify-content-between px-2">
|
<template #body="{ data }">
|
||||||
<span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span>
|
<Tag :value="data.status" :severity="getSeverity(data.status)" />
|
||||||
<span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span>
|
</template>
|
||||||
</div>
|
<template #filter="{ filterModel }">
|
||||||
</template>
|
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear>
|
||||||
</Column>
|
<template #option="slotProps">
|
||||||
<Column field="verified" header="Verified" dataType="boolean" bodyClass="text-center" style="min-width: 8rem">
|
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
|
||||||
<template #body="{ data }">
|
</template>
|
||||||
<i class="pi" :class="{ 'pi-check-circle text-green-500 ': data.verified, 'pi-times-circle text-red-500': !data.verified }"></i>
|
</Dropdown>
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel }">
|
</Column>
|
||||||
<label for="verified-filter" class="font-bold"> Verified </label>
|
<Column field="activity" header="Activity" :showFilterMatchModes="false" style="min-width: 12rem">
|
||||||
<TriStateCheckbox v-model="filterModel.value" inputId="verified-filter" />
|
<template #body="{ data }">
|
||||||
</template>
|
<ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar>
|
||||||
</Column>
|
</template>
|
||||||
</DataTable>
|
<template #filter="{ filterModel }">
|
||||||
</div>
|
<Slider v-model="filterModel.value" range class="m-3"></Slider>
|
||||||
|
<div class="flex align-items-center justify-content-between px-2">
|
||||||
|
<span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span>
|
||||||
|
<span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="verified" header="Verified" dataType="boolean" bodyClass="text-center" style="min-width: 8rem">
|
||||||
|
<template #body="{ data }">
|
||||||
|
<i class="pi" :class="{ 'pi-check-circle text-green-500 ': data.verified, 'pi-times-circle text-red-500': !data.verified }"></i>
|
||||||
|
</template>
|
||||||
|
<template #filter="{ filterModel }">
|
||||||
|
<label for="verified-filter" class="font-bold"> Verified </label>
|
||||||
|
<TriStateCheckbox v-model="filterModel.value" inputId="verified-filter" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -682,13 +684,13 @@ const getSeverity = (status) => {
|
||||||
created() {
|
created() {
|
||||||
this.initFilters();
|
this.initFilters();
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersMedium().then((data) => {
|
|
||||||
this.customers = this.getCustomers(data);
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersMedium().then((data) => {
|
||||||
|
this.customers = this.getCustomers(data);
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
formatDate(value) {
|
formatDate(value) {
|
||||||
return value.toLocaleDateString('en-US', {
|
return value.toLocaleDateString('en-US', {
|
||||||
day: '2-digit',
|
day: '2-digit',
|
||||||
|
|
|
@ -6,77 +6,79 @@
|
||||||
</p>
|
</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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable v-model:filters="filters" :value="customers" paginator :rows="10" dataKey="id" filterDisplay="row" :loading="loading" :globalFilterFields="['name', 'country.name', 'representative.name', 'status']">
|
<div class="card">
|
||||||
<template #header>
|
<DataTable v-model:filters="filters" :value="customers" paginator :rows="10" dataKey="id" filterDisplay="row" :loading="loading" :globalFilterFields="['name', 'country.name', 'representative.name', 'status']">
|
||||||
<div class="flex justify-content-end">
|
<template #header>
|
||||||
<span class="p-input-icon-left">
|
<div class="flex justify-content-end">
|
||||||
<i class="pi pi-search" />
|
<span class="p-input-icon-left">
|
||||||
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
|
<i class="pi pi-search" />
|
||||||
</span>
|
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
|
||||||
</div>
|
</span>
|
||||||
</template>
|
|
||||||
<template #empty> No customers found. </template>
|
|
||||||
<template #loading> Loading customers data. Please wait. </template>
|
|
||||||
<Column field="name" header="Name" style="min-width: 12rem">
|
|
||||||
<template #body="{ data }">
|
|
||||||
{{ data.name }}
|
|
||||||
</template>
|
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
|
||||||
<InputText v-model="filterModel.value" type="text" @input="filterCallback()" class="p-column-filter" placeholder="Search by name" />
|
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
<Column header="Country" filterField="country.name" style="min-width: 12rem">
|
|
||||||
<template #body="{ data }">
|
|
||||||
<div class="flex align-items-center gap-2">
|
|
||||||
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
|
||||||
<span>{{ data.country.name }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
<template #empty> No customers found. </template>
|
||||||
<InputText v-model="filterModel.value" type="text" @input="filterCallback()" class="p-column-filter" placeholder="Search by country" />
|
<template #loading> Loading customers data. Please wait. </template>
|
||||||
</template>
|
<Column field="name" header="Name" style="min-width: 12rem">
|
||||||
</Column>
|
<template #body="{ data }">
|
||||||
<Column header="Agent" filterField="representative" :showFilterMenu="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
|
{{ data.name }}
|
||||||
<template #body="{ data }">
|
</template>
|
||||||
<div class="flex align-items-center gap-2">
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()" class="p-column-filter" placeholder="Search by name" />
|
||||||
<span>{{ data.representative.name }}</span>
|
</template>
|
||||||
</div>
|
</Column>
|
||||||
</template>
|
<Column header="Country" filterField="country.name" style="min-width: 12rem">
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
<template #body="{ data }">
|
||||||
<MultiSelect v-model="filterModel.value" @change="filterCallback()" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter" style="min-width: 14rem" :maxSelectedLabels="1">
|
<div class="flex align-items-center gap-2">
|
||||||
<template #option="slotProps">
|
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
||||||
<div class="flex align-items-center gap-2">
|
<span>{{ data.country.name }}</span>
|
||||||
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
|
</div>
|
||||||
<span>{{ slotProps.option.name }}</span>
|
</template>
|
||||||
</div>
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
</template>
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()" class="p-column-filter" placeholder="Search by country" />
|
||||||
</MultiSelect>
|
</template>
|
||||||
</template>
|
</Column>
|
||||||
</Column>
|
<Column header="Agent" filterField="representative" :showFilterMenu="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
|
||||||
<Column field="status" header="Status" :showFilterMenu="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem">
|
<template #body="{ data }">
|
||||||
<template #body="{ data }">
|
<div class="flex align-items-center gap-2">
|
||||||
<Tag :value="data.status" :severity="getSeverity(data.status)" />
|
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
||||||
</template>
|
<span>{{ data.representative.name }}</span>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
</div>
|
||||||
<Dropdown v-model="filterModel.value" @change="filterCallback()" :options="statuses" placeholder="Select One" class="p-column-filter" style="min-width: 12rem" :showClear="true">
|
</template>
|
||||||
<template #option="slotProps">
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
|
<MultiSelect v-model="filterModel.value" @change="filterCallback()" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter" style="min-width: 14rem" :maxSelectedLabels="1">
|
||||||
</template>
|
<template #option="slotProps">
|
||||||
</Dropdown>
|
<div class="flex align-items-center gap-2">
|
||||||
</template>
|
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
|
||||||
</Column>
|
<span>{{ slotProps.option.name }}</span>
|
||||||
<Column field="verified" header="Verified" dataType="boolean" style="min-width: 6rem">
|
</div>
|
||||||
<template #body="{ data }">
|
</template>
|
||||||
<i class="pi" :class="{ 'pi-check-circle text-green-500': data.verified, 'pi-times-circle text-red-400': !data.verified }"></i>
|
</MultiSelect>
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
</Column>
|
||||||
<TriStateCheckbox v-model="filterModel.value" @change="filterCallback()" />
|
<Column field="status" header="Status" :showFilterMenu="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem">
|
||||||
</template>
|
<template #body="{ data }">
|
||||||
</Column>
|
<Tag :value="data.status" :severity="getSeverity(data.status)" />
|
||||||
</DataTable>
|
</template>
|
||||||
</div>
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
|
<Dropdown v-model="filterModel.value" @change="filterCallback()" :options="statuses" placeholder="Select One" class="p-column-filter" style="min-width: 12rem" :showClear="true">
|
||||||
|
<template #option="slotProps">
|
||||||
|
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
|
||||||
|
</template>
|
||||||
|
</Dropdown>
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="verified" header="Verified" dataType="boolean" style="min-width: 6rem">
|
||||||
|
<template #body="{ data }">
|
||||||
|
<i class="pi" :class="{ 'pi-check-circle text-green-500': data.verified, 'pi-times-circle text-red-400': !data.verified }"></i>
|
||||||
|
</template>
|
||||||
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
|
<TriStateCheckbox v-model="filterModel.value" @change="filterCallback()" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -510,13 +512,13 @@ const getSeverity = (status) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersMedium().then((data) => {
|
|
||||||
this.customers = this.getCustomers(data);
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersMedium().then((data) => {
|
||||||
|
this.customers = this.getCustomers(data);
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
getCustomers(data) {
|
getCustomers(data) {
|
||||||
return [...(data || [])].map((d) => {
|
return [...(data || [])].map((d) => {
|
||||||
d.date = new Date(d.date);
|
d.date = new Date(d.date);
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Pagination is enabled by adding <i>paginator</i> property and defining <i>rows</i> per page.</p>
|
<p>Pagination is enabled by adding <i>paginator</i> property and defining <i>rows</i> per page.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="customers" paginator :rows="5" :rowsPerPageOptions="[5, 10, 20, 50]" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="name" header="Name" style="width: 25%"></Column>
|
<DataTable :value="customers" paginator :rows="5" :rowsPerPageOptions="[5, 10, 20, 50]" tableStyle="min-width: 50rem">
|
||||||
<Column field="country.name" header="Country" style="width: 25%"></Column>
|
<Column field="name" header="Name" style="width: 25%"></Column>
|
||||||
<Column field="company" header="Company" style="width: 25%"></Column>
|
<Column field="country.name" header="Country" style="width: 25%"></Column>
|
||||||
<Column field="representative.name" header="Representative" style="width: 25%"></Column>
|
<Column field="company" header="Company" style="width: 25%"></Column>
|
||||||
</DataTable>
|
<Column field="representative.name" header="Representative" style="width: 25%"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -104,8 +106,10 @@ const customers = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,28 +5,30 @@
|
||||||
<PrimeVueNuxtLink to="/paginator">Paginator</PrimeVueNuxtLink> component for more information about the advanced customization options.
|
<PrimeVueNuxtLink to="/paginator">Paginator</PrimeVueNuxtLink> component for more information about the advanced customization options.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card">
|
||||||
:value="customers"
|
<DataTable
|
||||||
paginator
|
:value="customers"
|
||||||
:rows="5"
|
paginator
|
||||||
:rowsPerPageOptions="[5, 10, 20, 50]"
|
:rows="5"
|
||||||
paginatorTemplate="RowsPerPageDropdown FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink"
|
:rowsPerPageOptions="[5, 10, 20, 50]"
|
||||||
currentPageReportTemplate="{first} to {last} of {totalRecords}"
|
paginatorTemplate="RowsPerPageDropdown FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink"
|
||||||
tableStyle="min-width: 50rem"
|
currentPageReportTemplate="{first} to {last} of {totalRecords}"
|
||||||
>
|
tableStyle="min-width: 50rem"
|
||||||
<template #paginatorstart>
|
>
|
||||||
<Button type="button" icon="pi pi-refresh" text />
|
<template #paginatorstart>
|
||||||
</template>
|
<Button type="button" icon="pi pi-refresh" text />
|
||||||
<template #paginatorend>
|
</template>
|
||||||
<Button type="button" icon="pi pi-download" text />
|
<template #paginatorend>
|
||||||
</template>
|
<Button type="button" icon="pi pi-download" text />
|
||||||
<Column field="name" header="Name" style="width: 25%"></Column>
|
</template>
|
||||||
<Column field="country.name" header="Country" style="width: 25%"></Column>
|
<Column field="name" header="Name" style="width: 25%"></Column>
|
||||||
<Column field="company" header="Company" style="width: 25%"></Column>
|
<Column field="country.name" header="Country" style="width: 25%"></Column>
|
||||||
<Column field="representative.name" header="Representative" style="width: 25%"></Column>
|
<Column field="company" header="Company" style="width: 25%"></Column>
|
||||||
</DataTable>
|
<Column field="representative.name" header="Representative" style="width: 25%"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -145,8 +147,10 @@ const customers = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,51 +1,53 @@
|
||||||
<template>
|
<template>
|
||||||
<DocSectionText v-bind="$attrs"></DocSectionText>
|
<DocSectionText v-bind="$attrs"></DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card">
|
||||||
:value="products"
|
<DataTable
|
||||||
sortMode="multiple"
|
:value="products"
|
||||||
:pt="{
|
sortMode="multiple"
|
||||||
table: { style: { minWidth: '50rem' } }
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<Column
|
|
||||||
field="code"
|
|
||||||
header="Code"
|
|
||||||
sortable
|
|
||||||
:pt="{
|
:pt="{
|
||||||
sortBadge: { class: 'bg-primary' },
|
table: { style: { minWidth: '50rem' } }
|
||||||
headerCell: { style: { width: '25%' } }
|
|
||||||
}"
|
}"
|
||||||
/>
|
>
|
||||||
<Column
|
<Column
|
||||||
field="name"
|
field="code"
|
||||||
header="Name"
|
header="Code"
|
||||||
sortable
|
sortable
|
||||||
:pt="{
|
:pt="{
|
||||||
sortBadge: { class: 'bg-primary' },
|
sortBadge: { class: 'bg-primary' },
|
||||||
headerCell: { style: { width: '25%' } }
|
headerCell: { style: { width: '25%' } }
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<Column
|
<Column
|
||||||
field="category"
|
field="name"
|
||||||
header="Category"
|
header="Name"
|
||||||
sortable
|
sortable
|
||||||
:pt="{
|
:pt="{
|
||||||
sortBadge: { class: 'bg-primary' },
|
sortBadge: { class: 'bg-primary' },
|
||||||
headerCell: { style: { width: '25%' } }
|
headerCell: { style: { width: '25%' } }
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<Column
|
<Column
|
||||||
field="quantity"
|
field="category"
|
||||||
header="Quantity"
|
header="Category"
|
||||||
sortable
|
sortable
|
||||||
:pt="{
|
:pt="{
|
||||||
sortBadge: { class: 'bg-primary' },
|
sortBadge: { class: 'bg-primary' },
|
||||||
headerCell: { style: { width: '25%' } }
|
headerCell: { style: { width: '25%' } }
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
</DataTable>
|
<Column
|
||||||
</div>
|
field="quantity"
|
||||||
|
header="Quantity"
|
||||||
|
sortable
|
||||||
|
:pt="{
|
||||||
|
sortBadge: { class: 'bg-primary' },
|
||||||
|
headerCell: { style: { width: '25%' } }
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -248,8 +250,10 @@ const products = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,46 +5,48 @@
|
||||||
<i>rowgroup-collapse</i> events.
|
<i>rowgroup-collapse</i> events.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card">
|
||||||
v-model:expandedRowGroups="expandedRowGroups"
|
<DataTable
|
||||||
:value="customers"
|
v-model:expandedRowGroups="expandedRowGroups"
|
||||||
expandableRowGroups
|
:value="customers"
|
||||||
rowGroupMode="subheader"
|
expandableRowGroups
|
||||||
groupRowsBy="representative.name"
|
rowGroupMode="subheader"
|
||||||
sortMode="single"
|
groupRowsBy="representative.name"
|
||||||
sortField="representative.name"
|
sortMode="single"
|
||||||
:sortOrder="1"
|
sortField="representative.name"
|
||||||
@rowgroup-expand="onRowGroupExpand"
|
:sortOrder="1"
|
||||||
@rowgroup-collapse="onRowGroupCollapse"
|
@rowgroup-expand="onRowGroupExpand"
|
||||||
tableStyle="min-width: 50rem"
|
@rowgroup-collapse="onRowGroupCollapse"
|
||||||
>
|
tableStyle="min-width: 50rem"
|
||||||
<template #groupheader="slotProps">
|
>
|
||||||
<img :alt="slotProps.data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.data.representative.image}`" width="32" style="vertical-align: middle" class="ml-2" />
|
<template #groupheader="slotProps">
|
||||||
<span class="vertical-align-middle ml-2 font-bold line-height-3">{{ slotProps.data.representative.name }}</span>
|
<img :alt="slotProps.data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.data.representative.image}`" width="32" style="vertical-align: middle" class="ml-2" />
|
||||||
</template>
|
<span class="vertical-align-middle ml-2 font-bold line-height-3">{{ slotProps.data.representative.name }}</span>
|
||||||
<Column field="representative.name" header="Representative"></Column>
|
|
||||||
<Column field="name" header="Name" style="width: 20%"></Column>
|
|
||||||
<Column field="country" header="Country" style="width: 20%">
|
|
||||||
<template #body="slotProps">
|
|
||||||
<div class="flex align-items-center gap-2">
|
|
||||||
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${slotProps.data.country.code}`" style="width: 24px" />
|
|
||||||
<span>{{ slotProps.data.country.name }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
<Column field="representative.name" header="Representative"></Column>
|
||||||
<Column field="company" header="Company" style="width: 20%"></Column>
|
<Column field="name" header="Name" style="width: 20%"></Column>
|
||||||
<Column field="status" header="Status" style="width: 20%">
|
<Column field="country" header="Country" style="width: 20%">
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
<Tag :value="slotProps.data.status" :severity="getSeverity(slotProps.data.status)" />
|
<div class="flex align-items-center gap-2">
|
||||||
|
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${slotProps.data.country.code}`" style="width: 24px" />
|
||||||
|
<span>{{ slotProps.data.country.name }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="company" header="Company" style="width: 20%"></Column>
|
||||||
|
<Column field="status" header="Status" style="width: 20%">
|
||||||
|
<template #body="slotProps">
|
||||||
|
<Tag :value="slotProps.data.status" :severity="getSeverity(slotProps.data.status)" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="date" header="Date" style="width: 20%"></Column>
|
||||||
|
<template #groupfooter="slotProps">
|
||||||
|
<div class="flex justify-content-end font-bold w-full">Total Customers: {{ calculateCustomerTotal(slotProps.data.representative.name) }}</div>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</DataTable>
|
||||||
<Column field="date" header="Date" style="width: 20%"></Column>
|
</div>
|
||||||
<template #groupfooter="slotProps">
|
</DeferredDemo>
|
||||||
<div class="flex justify-content-end font-bold w-full">Total Customers: {{ calculateCustomerTotal(slotProps.data.representative.name) }}</div>
|
|
||||||
</template>
|
|
||||||
</DataTable>
|
|
||||||
</div>
|
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -240,7 +242,7 @@ const calculateCustomerTotal = (name) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
};
|
};
|
||||||
const getSeverity = (status) => {
|
const getSeverity = (status) => {
|
||||||
|
@ -286,10 +288,10 @@ const getSeverity = (status) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
||||||
|
},
|
||||||
onRowGroupExpand(event) {
|
onRowGroupExpand(event) {
|
||||||
this.$toast.add({ severity: 'info', summary: 'Row Group Expanded', detail: 'Value: ' + event.data, life: 3000 });
|
this.$toast.add({ severity: 'info', summary: 'Row Group Expanded', detail: 'Value: ' + event.data, life: 3000 });
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,39 +2,41 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>When <i>rowGroupMode</i> is configured to be <i>rowspan</i>, the grouping column spans multiple rows.</p>
|
<p>When <i>rowGroupMode</i> is configured to be <i>rowspan</i>, the grouping column spans multiple rows.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="customers" rowGroupMode="rowspan" groupRowsBy="representative.name" sortMode="single" sortField="representative.name" :sortOrder="1" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column header="#" headerStyle="width:3rem">
|
<DataTable :value="customers" rowGroupMode="rowspan" groupRowsBy="representative.name" sortMode="single" sortField="representative.name" :sortOrder="1" tableStyle="min-width: 50rem">
|
||||||
<template #body="slotProps">
|
<Column header="#" headerStyle="width:3rem">
|
||||||
{{ slotProps.index + 1 }}
|
<template #body="slotProps">
|
||||||
</template>
|
{{ slotProps.index + 1 }}
|
||||||
</Column>
|
</template>
|
||||||
<Column field="representative.name" header="Representative" style="min-width: 200px">
|
</Column>
|
||||||
<template #body="slotProps">
|
<Column field="representative.name" header="Representative" style="min-width: 200px">
|
||||||
<div class="flex align-items-center gap-2">
|
<template #body="slotProps">
|
||||||
<img :alt="slotProps.data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.data.representative.image}`" width="32" style="vertical-align: middle" />
|
<div class="flex align-items-center gap-2">
|
||||||
<span>{{ slotProps.data.representative.name }}</span>
|
<img :alt="slotProps.data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.data.representative.image}`" width="32" style="vertical-align: middle" />
|
||||||
</div>
|
<span>{{ slotProps.data.representative.name }}</span>
|
||||||
</template>
|
</div>
|
||||||
</Column>
|
</template>
|
||||||
<Column field="name" header="Name" style="min-width: 200px"></Column>
|
</Column>
|
||||||
<Column field="country" header="Country" style="min-width: 150px">
|
<Column field="name" header="Name" style="min-width: 200px"></Column>
|
||||||
<template #body="slotProps">
|
<Column field="country" header="Country" style="min-width: 150px">
|
||||||
<div class="flex align-items-center gap-2">
|
<template #body="slotProps">
|
||||||
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${slotProps.data.country.code}`" style="width: 24px" />
|
<div class="flex align-items-center gap-2">
|
||||||
<span>{{ slotProps.data.country.name }}</span>
|
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${slotProps.data.country.code}`" style="width: 24px" />
|
||||||
</div>
|
<span>{{ slotProps.data.country.name }}</span>
|
||||||
</template>
|
</div>
|
||||||
</Column>
|
</template>
|
||||||
<Column field="company" header="Company" style="min-width: 200px"></Column>
|
</Column>
|
||||||
<Column field="status" header="Status" style="min-width: 100px">
|
<Column field="company" header="Company" style="min-width: 200px"></Column>
|
||||||
<template #body="slotProps">
|
<Column field="status" header="Status" style="min-width: 100px">
|
||||||
<Tag :value="slotProps.data.status" :severity="getSeverity(slotProps.data.status)" />
|
<template #body="slotProps">
|
||||||
</template>
|
<Tag :value="slotProps.data.status" :severity="getSeverity(slotProps.data.status)" />
|
||||||
</Column>
|
</template>
|
||||||
<Column field="date" header="Date" style="min-width: 100px"></Column>
|
</Column>
|
||||||
</DataTable>
|
<Column field="date" header="Date" style="min-width: 100px"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -242,10 +244,10 @@ const getSeverity = (status) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
||||||
|
},
|
||||||
onRowGroupExpand(event) {
|
onRowGroupExpand(event) {
|
||||||
this.$toast.add({ severity: 'info', summary: 'Row Group Expanded', detail: 'Value: ' + event.data, life: 3000 });
|
this.$toast.add({ severity: 'info', summary: 'Row Group Expanded', detail: 'Value: ' + event.data, life: 3000 });
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,36 +5,38 @@
|
||||||
with <i>groupfooter</i> slots.
|
with <i>groupfooter</i> slots.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="customers" rowGroupMode="subheader" groupRowsBy="representative.name" sortMode="single" sortField="representative.name" :sortOrder="1" scrollable scrollHeight="400px" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<template #groupheader="slotProps">
|
<DataTable :value="customers" rowGroupMode="subheader" groupRowsBy="representative.name" sortMode="single" sortField="representative.name" :sortOrder="1" scrollable scrollHeight="400px" tableStyle="min-width: 50rem">
|
||||||
<div class="flex align-items-center gap-2">
|
<template #groupheader="slotProps">
|
||||||
<img :alt="slotProps.data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.data.representative.image}`" width="32" style="vertical-align: middle" />
|
|
||||||
<span>{{ slotProps.data.representative.name }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<Column field="representative.name" header="Representative"></Column>
|
|
||||||
<Column field="name" header="Name" style="min-width: 200px"></Column>
|
|
||||||
<Column field="country" header="Country" style="min-width: 200px">
|
|
||||||
<template #body="slotProps">
|
|
||||||
<div class="flex align-items-center gap-2">
|
<div class="flex align-items-center gap-2">
|
||||||
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${slotProps.data.country.code}`" style="width: 24px" />
|
<img :alt="slotProps.data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.data.representative.image}`" width="32" style="vertical-align: middle" />
|
||||||
<span>{{ slotProps.data.country.name }}</span>
|
<span>{{ slotProps.data.representative.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
<Column field="representative.name" header="Representative"></Column>
|
||||||
<Column field="company" header="Company" style="min-width: 200px"></Column>
|
<Column field="name" header="Name" style="min-width: 200px"></Column>
|
||||||
<Column field="status" header="Status" style="min-width: 200px">
|
<Column field="country" header="Country" style="min-width: 200px">
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
<Tag :value="slotProps.data.status" :severity="getSeverity(slotProps.data.status)" />
|
<div class="flex align-items-center gap-2">
|
||||||
|
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${slotProps.data.country.code}`" style="width: 24px" />
|
||||||
|
<span>{{ slotProps.data.country.name }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="company" header="Company" style="min-width: 200px"></Column>
|
||||||
|
<Column field="status" header="Status" style="min-width: 200px">
|
||||||
|
<template #body="slotProps">
|
||||||
|
<Tag :value="slotProps.data.status" :severity="getSeverity(slotProps.data.status)" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="date" header="Date" style="min-width: 200px"></Column>
|
||||||
|
<template #groupfooter="slotProps">
|
||||||
|
<div class="flex justify-content-end font-bold w-full">Total Customers: {{ calculateCustomerTotal(slotProps.data.representative.name) }}</div>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</DataTable>
|
||||||
<Column field="date" header="Date" style="min-width: 200px"></Column>
|
</div>
|
||||||
<template #groupfooter="slotProps">
|
</DeferredDemo>
|
||||||
<div class="flex justify-content-end font-bold w-full">Total Customers: {{ calculateCustomerTotal(slotProps.data.representative.name) }}</div>
|
|
||||||
</template>
|
|
||||||
</DataTable>
|
|
||||||
</div>
|
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -214,7 +216,7 @@ const calculateCustomerTotal = (name) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
};
|
};
|
||||||
const getSeverity = (status) => {
|
const getSeverity = (status) => {
|
||||||
|
@ -260,10 +262,10 @@ const getSeverity = (status) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersMedium().then((data) => (this.customers = data));
|
||||||
|
},
|
||||||
calculateCustomerTotal(name) {
|
calculateCustomerTotal(name) {
|
||||||
let total = 0;
|
let total = 0;
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,17 @@
|
||||||
<p>Specifying <i>selectionMode</i> as <i>multiple</i> on a Column, displays a checkbox inside that column for selection.</p>
|
<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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable v-model:selection="selectedProduct" :value="products" dataKey="id" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
|
<DataTable v-model:selection="selectedProduct" :value="products" dataKey="id" tableStyle="min-width: 50rem">
|
||||||
<Column field="code" header="Code"></Column>
|
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
<Column field="category" header="Category"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -109,8 +111,10 @@ const metaKey = ref(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,18 +5,20 @@
|
||||||
<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.
|
<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>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<div class="flex justify-content-center align-items-center mb-4 gap-2">
|
<div class="card">
|
||||||
<InputSwitch v-model="metaKey" inputId="input-metakey" />
|
<div class="flex justify-content-center align-items-center mb-4 gap-2">
|
||||||
<label for="input-metakey">MetaKey</label>
|
<InputSwitch v-model="metaKey" inputId="input-metakey" />
|
||||||
|
<label for="input-metakey">MetaKey</label>
|
||||||
|
</div>
|
||||||
|
<DataTable v-model:selection="selectedProduct" :value="products" selectionMode="multiple" :metaKeySelection="metaKey" dataKey="id" tableStyle="min-width: 50rem">
|
||||||
|
<Column field="code" header="Code"></Column>
|
||||||
|
<Column field="name" header="Name"></Column>
|
||||||
|
<Column field="category" header="Category"></Column>
|
||||||
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
<DataTable v-model:selection="selectedProduct" :value="products" selectionMode="multiple" :metaKeySelection="metaKey" dataKey="id" tableStyle="min-width: 50rem">
|
</DeferredDemo>
|
||||||
<Column field="code" header="Code"></Column>
|
|
||||||
<Column field="name" header="Name"></Column>
|
|
||||||
<Column field="category" header="Category"></Column>
|
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
|
||||||
</DataTable>
|
|
||||||
</div>
|
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -121,8 +123,10 @@ const metaKey = ref(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,15 +5,17 @@
|
||||||
trigger selection using the radio buttons.
|
trigger selection using the radio buttons.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable v-model:selection="selectedProduct" :value="products" dataKey="id" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column selectionMode="single" headerStyle="width: 3rem"></Column>
|
<DataTable v-model:selection="selectedProduct" :value="products" dataKey="id" tableStyle="min-width: 50rem">
|
||||||
<Column field="code" header="Code"></Column>
|
<Column selectionMode="single" headerStyle="width: 3rem"></Column>
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
<Column field="category" header="Category"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -111,8 +113,10 @@ const metaKey = ref(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>DataTable provides <i>row-select</i> and <i>row-unselect</i> events to listen selection events.</p>
|
<p>DataTable provides <i>row-select</i> and <i>row-unselect</i> events to listen selection events.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable v-model:selection="selectedProduct" :value="products" selectionMode="single" dataKey="id" :metaKeySelection="false" @rowSelect="onRowSelect" @rowUnselect="onRowUnselect" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code"></Column>
|
<DataTable v-model:selection="selectedProduct" :value="products" selectionMode="single" dataKey="id" :metaKeySelection="false" @rowSelect="onRowSelect" @rowUnselect="onRowUnselect" tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="code" header="Code"></Column>
|
||||||
<Column field="category" header="Category"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
<Column field="category" header="Category"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -124,10 +126,10 @@ const onRowUnselect = (event) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
onRowSelect(event) {
|
onRowSelect(event) {
|
||||||
this.$toast.add({ severity: 'info', summary: 'Product Selected', detail: 'Name: ' + event.data.name, life: 3000 });
|
this.$toast.add({ severity: 'info', summary: 'Product Selected', detail: 'Name: ' + event.data.name, life: 3000 });
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,18 +9,20 @@
|
||||||
setting it to false.
|
setting it to false.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<div class="flex justify-content-center align-items-center mb-4 gap-2">
|
<div class="card">
|
||||||
<InputSwitch v-model="metaKey" inputId="input-metakey" />
|
<div class="flex justify-content-center align-items-center mb-4 gap-2">
|
||||||
<label for="input-metakey">MetaKey</label>
|
<InputSwitch v-model="metaKey" inputId="input-metakey" />
|
||||||
|
<label for="input-metakey">MetaKey</label>
|
||||||
|
</div>
|
||||||
|
<DataTable v-model:selection="selectedProduct" :value="products" selectionMode="single" :metaKeySelection="metaKey" dataKey="id" tableStyle="min-width: 50rem">
|
||||||
|
<Column field="code" header="Code"></Column>
|
||||||
|
<Column field="name" header="Name"></Column>
|
||||||
|
<Column field="category" header="Category"></Column>
|
||||||
|
<Column field="quantity" header="Quantity"></Column>
|
||||||
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
<DataTable v-model:selection="selectedProduct" :value="products" selectionMode="single" :metaKeySelection="metaKey" dataKey="id" tableStyle="min-width: 50rem">
|
</DeferredDemo>
|
||||||
<Column field="code" header="Code"></Column>
|
|
||||||
<Column field="name" header="Name"></Column>
|
|
||||||
<Column field="category" header="Category"></Column>
|
|
||||||
<Column field="quantity" header="Quantity"></Column>
|
|
||||||
</DataTable>
|
|
||||||
</div>
|
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -125,8 +127,10 @@ const metaKey = ref(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,103 +2,114 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>DataTable with selection, pagination, filtering, sorting and templating.</p>
|
<p>DataTable with selection, pagination, filtering, sorting and templating.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<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']">
|
<div class="card">
|
||||||
<template #header>
|
<DataTable
|
||||||
<div class="flex justify-content-between">
|
v-model:filters="filters"
|
||||||
<Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" />
|
v-model:selection="selectedCustomers"
|
||||||
<span class="p-input-icon-left">
|
:value="customers"
|
||||||
<i class="pi pi-search" />
|
paginator
|
||||||
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
|
:rows="10"
|
||||||
</span>
|
dataKey="id"
|
||||||
</div>
|
filterDisplay="menu"
|
||||||
</template>
|
:globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']"
|
||||||
<template #empty> No customers found. </template>
|
>
|
||||||
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
|
<template #header>
|
||||||
<Column field="name" header="Name" sortable style="min-width: 14rem">
|
<div class="flex justify-content-between">
|
||||||
<template #body="{ data }">
|
<Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" />
|
||||||
{{ data.name }}
|
<span class="p-input-icon-left">
|
||||||
</template>
|
<i class="pi pi-search" />
|
||||||
<template #filter="{ filterModel }">
|
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
|
||||||
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
|
</span>
|
||||||
</template>
|
|
||||||
</Column>
|
|
||||||
<Column header="Country" sortable sortField="country.name" filterField="country.name" style="min-width: 14rem">
|
|
||||||
<template #body="{ data }">
|
|
||||||
<div class="flex align-items-center gap-2">
|
|
||||||
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
|
||||||
<span>{{ data.country.name }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel }">
|
<template #empty> No customers found. </template>
|
||||||
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
|
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
|
||||||
</template>
|
<Column field="name" header="Name" sortable style="min-width: 14rem">
|
||||||
</Column>
|
<template #body="{ data }">
|
||||||
<Column header="Agent" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
|
{{ data.name }}
|
||||||
<template #body="{ data }">
|
</template>
|
||||||
<div class="flex align-items-center gap-2">
|
<template #filter="{ filterModel }">
|
||||||
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
|
||||||
<span>{{ data.representative.name }}</span>
|
</template>
|
||||||
</div>
|
</Column>
|
||||||
</template>
|
<Column header="Country" sortable sortField="country.name" filterField="country.name" style="min-width: 14rem">
|
||||||
<template #filter="{ filterModel }">
|
<template #body="{ data }">
|
||||||
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
|
<div class="flex align-items-center gap-2">
|
||||||
<template #option="slotProps">
|
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
|
||||||
<div class="flex align-items-center gap-2">
|
<span>{{ data.country.name }}</span>
|
||||||
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
|
</div>
|
||||||
<span>{{ slotProps.option.name }}</span>
|
</template>
|
||||||
</div>
|
<template #filter="{ filterModel }">
|
||||||
</template>
|
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
|
||||||
</MultiSelect>
|
</template>
|
||||||
</template>
|
</Column>
|
||||||
</Column>
|
<Column header="Agent" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
|
||||||
<Column field="date" header="Date" sortable filterField="date" dataType="date" style="min-width: 10rem">
|
<template #body="{ data }">
|
||||||
<template #body="{ data }">
|
<div class="flex align-items-center gap-2">
|
||||||
{{ formatDate(data.date) }}
|
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
|
||||||
</template>
|
<span>{{ data.representative.name }}</span>
|
||||||
<template #filter="{ filterModel }">
|
</div>
|
||||||
<Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />
|
</template>
|
||||||
</template>
|
<template #filter="{ filterModel }">
|
||||||
</Column>
|
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
|
||||||
<Column field="balance" header="Balance" sortable filterField="balance" dataType="numeric" style="min-width: 10rem">
|
<template #option="slotProps">
|
||||||
<template #body="{ data }">
|
<div class="flex align-items-center gap-2">
|
||||||
{{ formatCurrency(data.balance) }}
|
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
|
||||||
</template>
|
<span>{{ slotProps.option.name }}</span>
|
||||||
<template #filter="{ filterModel }">
|
</div>
|
||||||
<InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" />
|
</template>
|
||||||
</template>
|
</MultiSelect>
|
||||||
</Column>
|
</template>
|
||||||
<Column header="Status" sortable field="status" :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem">
|
</Column>
|
||||||
<template #body="{ data }">
|
<Column field="date" header="Date" sortable filterField="date" dataType="date" style="min-width: 10rem">
|
||||||
<Tag :value="data.status" :severity="getSeverity(data.status)" />
|
<template #body="{ data }">
|
||||||
</template>
|
{{ formatDate(data.date) }}
|
||||||
<template #filter="{ filterModel }">
|
</template>
|
||||||
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear>
|
<template #filter="{ filterModel }">
|
||||||
<template #option="slotProps">
|
<Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />
|
||||||
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
|
</template>
|
||||||
</template>
|
</Column>
|
||||||
</Dropdown>
|
<Column field="balance" header="Balance" sortable filterField="balance" dataType="numeric" style="min-width: 10rem">
|
||||||
</template>
|
<template #body="{ data }">
|
||||||
</Column>
|
{{ formatCurrency(data.balance) }}
|
||||||
<Column field="activity" header="Activity" sortable :showFilterMatchModes="false" style="min-width: 12rem">
|
</template>
|
||||||
<template #body="{ data }">
|
<template #filter="{ filterModel }">
|
||||||
<ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar>
|
<InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" />
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel }">
|
</Column>
|
||||||
<Slider v-model="filterModel.value" range class="m-3"></Slider>
|
<Column header="Status" sortable field="status" :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem">
|
||||||
<div class="flex align-items-center justify-content-between px-2">
|
<template #body="{ data }">
|
||||||
<span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span>
|
<Tag :value="data.status" :severity="getSeverity(data.status)" />
|
||||||
<span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span>
|
</template>
|
||||||
</div>
|
<template #filter="{ filterModel }">
|
||||||
</template>
|
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear>
|
||||||
</Column>
|
<template #option="slotProps">
|
||||||
<Column headerStyle="width: 5rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
|
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
|
||||||
<template #body>
|
</template>
|
||||||
<Button type="button" icon="pi pi-cog" rounded />
|
</Dropdown>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</DataTable>
|
<Column field="activity" header="Activity" sortable :showFilterMatchModes="false" style="min-width: 12rem">
|
||||||
</div>
|
<template #body="{ data }">
|
||||||
|
<ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar>
|
||||||
|
</template>
|
||||||
|
<template #filter="{ filterModel }">
|
||||||
|
<Slider v-model="filterModel.value" range class="m-3"></Slider>
|
||||||
|
<div class="flex align-items-center justify-content-between px-2">
|
||||||
|
<span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span>
|
||||||
|
<span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column headerStyle="width: 5rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
|
||||||
|
<template #body>
|
||||||
|
<Button type="button" icon="pi pi-cog" rounded />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -628,12 +639,12 @@ const getSeverity = (status) => {
|
||||||
created() {
|
created() {
|
||||||
this.initFilters();
|
this.initFilters();
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersLarge().then((data) => {
|
|
||||||
this.customers = this.getCustomers(data);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersLarge().then((data) => {
|
||||||
|
this.customers = this.getCustomers(data);
|
||||||
|
});
|
||||||
|
},
|
||||||
formatDate(value) {
|
formatDate(value) {
|
||||||
return value.toLocaleDateString('en-US', {
|
return value.toLocaleDateString('en-US', {
|
||||||
day: '2-digit',
|
day: '2-digit',
|
||||||
|
|
|
@ -2,73 +2,75 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>CRUD implementation example with a Dialog.</p>
|
<p>CRUD implementation example with a Dialog.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<Toolbar class="mb-4">
|
<div class="card">
|
||||||
<template #start>
|
<Toolbar class="mb-4">
|
||||||
<Button label="New" icon="pi pi-plus" severity="success" class="mr-2" @click="openNew" />
|
<template #start>
|
||||||
<Button label="Delete" icon="pi pi-trash" severity="danger" @click="confirmDeleteSelected" :disabled="!selectedProducts || !selectedProducts.length" />
|
<Button label="New" icon="pi pi-plus" severity="success" class="mr-2" @click="openNew" />
|
||||||
</template>
|
<Button label="Delete" icon="pi pi-trash" severity="danger" @click="confirmDeleteSelected" :disabled="!selectedProducts || !selectedProducts.length" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #end>
|
<template #end>
|
||||||
<FileUpload mode="basic" accept="image/*" :maxFileSize="1000000" label="Import" chooseLabel="Import" class="mr-2 inline-block" />
|
<FileUpload mode="basic" accept="image/*" :maxFileSize="1000000" label="Import" chooseLabel="Import" class="mr-2 inline-block" />
|
||||||
<Button label="Export" icon="pi pi-upload" severity="help" @click="exportCSV($event)" />
|
<Button label="Export" icon="pi pi-upload" severity="help" @click="exportCSV($event)" />
|
||||||
</template>
|
</template>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
ref="dt"
|
ref="dt"
|
||||||
v-model:selection="selectedProducts"
|
v-model:selection="selectedProducts"
|
||||||
:value="products"
|
:value="products"
|
||||||
dataKey="id"
|
dataKey="id"
|
||||||
:paginator="true"
|
:paginator="true"
|
||||||
:rows="10"
|
:rows="10"
|
||||||
:filters="filters"
|
:filters="filters"
|
||||||
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
|
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
|
||||||
:rowsPerPageOptions="[5, 10, 25]"
|
:rowsPerPageOptions="[5, 10, 25]"
|
||||||
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products"
|
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="flex flex-wrap gap-2 align-items-center justify-content-between">
|
<div class="flex flex-wrap gap-2 align-items-center justify-content-between">
|
||||||
<h4 class="m-0">Manage Products</h4>
|
<h4 class="m-0">Manage Products</h4>
|
||||||
<span class="p-input-icon-left">
|
<span class="p-input-icon-left">
|
||||||
<i class="pi pi-search" />
|
<i class="pi pi-search" />
|
||||||
<InputText v-model="filters['global'].value" placeholder="Search..." />
|
<InputText v-model="filters['global'].value" placeholder="Search..." />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<Column selectionMode="multiple" style="width: 3rem" :exportable="false"></Column>
|
<Column selectionMode="multiple" style="width: 3rem" :exportable="false"></Column>
|
||||||
<Column field="code" header="Code" sortable style="min-width: 12rem"></Column>
|
<Column field="code" header="Code" sortable style="min-width: 12rem"></Column>
|
||||||
<Column field="name" header="Name" sortable style="min-width: 16rem"></Column>
|
<Column field="name" header="Name" sortable style="min-width: 16rem"></Column>
|
||||||
<Column header="Image">
|
<Column header="Image">
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
<img :src="`https://primefaces.org/cdn/primevue/images/product/${slotProps.data.image}`" :alt="slotProps.data.image" class="shadow-2 border-round" style="width: 64px" />
|
<img :src="`https://primefaces.org/cdn/primevue/images/product/${slotProps.data.image}`" :alt="slotProps.data.image" class="shadow-2 border-round" style="width: 64px" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="price" header="Price" sortable style="min-width: 8rem">
|
<Column field="price" header="Price" sortable style="min-width: 8rem">
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
{{ formatCurrency(slotProps.data.price) }}
|
{{ formatCurrency(slotProps.data.price) }}
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="category" header="Category" sortable style="min-width: 10rem"></Column>
|
<Column field="category" header="Category" sortable style="min-width: 10rem"></Column>
|
||||||
<Column field="rating" header="Reviews" sortable style="min-width: 12rem">
|
<Column field="rating" header="Reviews" sortable style="min-width: 12rem">
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
<Rating :modelValue="slotProps.data.rating" :readonly="true" :cancel="false" />
|
<Rating :modelValue="slotProps.data.rating" :readonly="true" :cancel="false" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="inventoryStatus" header="Status" sortable style="min-width: 12rem">
|
<Column field="inventoryStatus" header="Status" sortable style="min-width: 12rem">
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
<Tag :value="slotProps.data.inventoryStatus" :severity="getStatusLabel(slotProps.data.inventoryStatus)" />
|
<Tag :value="slotProps.data.inventoryStatus" :severity="getStatusLabel(slotProps.data.inventoryStatus)" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column :exportable="false" style="min-width: 12rem">
|
<Column :exportable="false" style="min-width: 12rem">
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
<Button icon="pi pi-pencil" outlined rounded class="mr-2" @click="editProduct(slotProps.data)" />
|
<Button icon="pi pi-pencil" outlined rounded class="mr-2" @click="editProduct(slotProps.data)" />
|
||||||
<Button icon="pi pi-trash" outlined rounded severity="danger" @click="confirmDeleteProduct(slotProps.data)" />
|
<Button icon="pi pi-trash" outlined rounded severity="danger" @click="confirmDeleteProduct(slotProps.data)" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
|
|
||||||
<Dialog v-model:visible="productDialog" :style="{ width: '450px' }" header="Product Details" :modal="true" class="p-fluid">
|
<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" />
|
<img v-if="product.image" :src="`https://primefaces.org/cdn/primevue/images/product/${product.image}`" :alt="product.image" class="block m-auto pb-3" />
|
||||||
|
@ -197,7 +199,7 @@ export default {
|
||||||
<Button label="Export" icon="pi pi-upload" severity="help" @click="exportCSV($event)" />
|
<Button label="Export" icon="pi pi-upload" severity="help" @click="exportCSV($event)" />
|
||||||
</template>
|
</template>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
<DataTable ref="dt" :value="products" v-model:selection="selectedProducts" dataKey="id"
|
<DataTable ref="dt" :value="products" v-model:selection="selectedProducts" dataKey="id"
|
||||||
:paginator="true" :rows="10" :filters="filters"
|
:paginator="true" :rows="10" :filters="filters"
|
||||||
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[5,10,25]"
|
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[5,10,25]"
|
||||||
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products">
|
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products">
|
||||||
|
@ -258,7 +260,7 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
|
||||||
<DataTable ref="dt" :value="products" v-model:selection="selectedProducts" dataKey="id"
|
<DataTable ref="dt" :value="products" v-model:selection="selectedProducts" dataKey="id"
|
||||||
:paginator="true" :rows="10" :filters="filters"
|
:paginator="true" :rows="10" :filters="filters"
|
||||||
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[5,10,25]"
|
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[5,10,25]"
|
||||||
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products">
|
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products">
|
||||||
|
@ -547,7 +549,7 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
|
||||||
<DataTable ref="dt" :value="products" v-model:selection="selectedProducts" dataKey="id"
|
<DataTable ref="dt" :value="products" v-model:selection="selectedProducts" dataKey="id"
|
||||||
:paginator="true" :rows="10" :filters="filters"
|
:paginator="true" :rows="10" :filters="filters"
|
||||||
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[5,10,25]"
|
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[5,10,25]"
|
||||||
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products">
|
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products">
|
||||||
|
@ -830,14 +832,13 @@ const getStatusLabel = (status) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.initFilters();
|
this.initFilters();
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProducts().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProducts().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
formatCurrency(value) {
|
formatCurrency(value) {
|
||||||
if (value) return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
if (value) return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<div class="card flex justify-content-center">
|
<div class="card flex justify-content-center">
|
||||||
<Button label="Show" icon="pi pi-external-link" @click="dialogVisible = true" />
|
<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">
|
<DataTable :value="customers" scrollable scrollHeight="flex" tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="country.name" header="Country"></Column>
|
<Column field="country.name" header="Country"></Column>
|
||||||
|
@ -140,10 +140,12 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
CustomerService.getCustomersMedium().then((data) => {
|
onShow() {
|
||||||
this.customers = data;
|
CustomerService.getCustomersMedium().then((data) => {
|
||||||
});
|
this.customers = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,26 +2,28 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<ToggleButton v-model="balanceFrozen" onIcon="pi pi-lock" offIcon="pi pi-lock-open" onLabel="Balance" offLabel="Balance" />
|
<div class="card">
|
||||||
|
<ToggleButton v-model="balanceFrozen" onIcon="pi pi-lock" offIcon="pi pi-lock-open" onLabel="Balance" offLabel="Balance" />
|
||||||
|
|
||||||
<DataTable :value="customers" scrollable scrollHeight="400px" class="mt-4">
|
<DataTable :value="customers" scrollable scrollHeight="400px" class="mt-4">
|
||||||
<Column field="name" header="Name" style="min-width: 200px" frozen class="font-bold"></Column>
|
<Column field="name" header="Name" style="min-width: 200px" frozen class="font-bold"></Column>
|
||||||
<Column field="id" header="Id" style="min-width: 100px"></Column>
|
<Column field="id" header="Id" style="min-width: 100px"></Column>
|
||||||
<Column field="name" header="Name" style="min-width: 200px"></Column>
|
<Column field="name" header="Name" style="min-width: 200px"></Column>
|
||||||
<Column field="country.name" header="Country" style="min-width: 200px"></Column>
|
<Column field="country.name" header="Country" style="min-width: 200px"></Column>
|
||||||
<Column field="date" header="Date" style="min-width: 200px"></Column>
|
<Column field="date" header="Date" style="min-width: 200px"></Column>
|
||||||
<Column field="company" header="Company" style="min-width: 200px"></Column>
|
<Column field="company" header="Company" style="min-width: 200px"></Column>
|
||||||
<Column field="status" header="Status" style="min-width: 200px"></Column>
|
<Column field="status" header="Status" style="min-width: 200px"></Column>
|
||||||
<Column field="activity" header="Activity" style="min-width: 200px"></Column>
|
<Column field="activity" header="Activity" style="min-width: 200px"></Column>
|
||||||
<Column field="representative.name" header="Representative" style="min-width: 200px"></Column>
|
<Column field="representative.name" header="Representative" style="min-width: 200px"></Column>
|
||||||
<Column field="balance" header="Balance" style="min-width: 200px" alignFrozen="right" :frozen="balanceFrozen">
|
<Column field="balance" header="Balance" style="min-width: 200px" alignFrozen="right" :frozen="balanceFrozen">
|
||||||
<template #body="{ data }">
|
<template #body="{ data }">
|
||||||
<span class="font-bold">{{ formatCurrency(data.balance) }}</span>
|
<span class="font-bold">{{ formatCurrency(data.balance) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -165,12 +167,12 @@ const formatCurrency = (value) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersLarge().then((data) => {
|
|
||||||
this.customers = data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersLarge().then((data) => {
|
||||||
|
this.customers = data;
|
||||||
|
});
|
||||||
|
},
|
||||||
formatCurrency(value) {
|
formatCurrency(value) {
|
||||||
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,30 +2,32 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Rows can be fixed during scrolling by enabling the <i>frozenValue</i> property.</p>
|
<p>Rows can be fixed during scrolling by enabling the <i>frozenValue</i> property.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card">
|
||||||
:value="customers"
|
<DataTable
|
||||||
:frozenValue="lockedCustomers"
|
:value="customers"
|
||||||
scrollable
|
:frozenValue="lockedCustomers"
|
||||||
scrollHeight="400px"
|
scrollable
|
||||||
:pt="{
|
scrollHeight="400px"
|
||||||
table: { style: 'min-width: 50rem' },
|
:pt="{
|
||||||
bodyrow: ({ props }) => ({
|
table: { style: 'min-width: 50rem' },
|
||||||
class: [{ 'font-bold': props.frozenRow }]
|
bodyrow: ({ props }) => ({
|
||||||
})
|
class: [{ 'font-bold': props.frozenRow }]
|
||||||
}"
|
})
|
||||||
>
|
}"
|
||||||
<Column field="name" header="Name"></Column>
|
>
|
||||||
<Column field="country.name" header="Country"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="representative.name" header="Representative"></Column>
|
<Column field="country.name" header="Country"></Column>
|
||||||
<Column field="status" header="Status"></Column>
|
<Column field="representative.name" header="Representative"></Column>
|
||||||
<Column style="flex: 0 0 4rem">
|
<Column field="status" header="Status"></Column>
|
||||||
<template #body="{ data, frozenRow, index }">
|
<Column style="flex: 0 0 4rem">
|
||||||
<Button type="button" :icon="frozenRow ? 'pi pi-lock-open' : 'pi pi-lock'" :disabled="frozenRow ? false : lockedCustomers.length >= 2" text size="small" @click="toggleLock(data, frozenRow, index)" />
|
<template #body="{ data, frozenRow, index }">
|
||||||
</template>
|
<Button type="button" :icon="frozenRow ? 'pi pi-lock-open' : 'pi pi-lock'" :disabled="frozenRow ? false : lockedCustomers.length >= 2" text size="small" @click="toggleLock(data, frozenRow, index)" />
|
||||||
</Column>
|
</template>
|
||||||
</DataTable>
|
</Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -255,12 +257,12 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersMedium().then((data) => {
|
|
||||||
this.customers = data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersMedium().then((data) => {
|
||||||
|
this.customers = data;
|
||||||
|
});
|
||||||
|
},
|
||||||
toggleLock(data, frozen, index) {
|
toggleLock(data, frozen, index) {
|
||||||
if (frozen) {
|
if (frozen) {
|
||||||
this.lockedCustomers = this.lockedCustomers.filter((c, i) => i !== index);
|
this.lockedCustomers = this.lockedCustomers.filter((c, i) => i !== index);
|
||||||
|
|
|
@ -2,23 +2,25 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Horizontal scrollbar is displayed when table width exceeds the parent width.</p>
|
<p>Horizontal scrollbar is displayed when table width exceeds the parent width.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="customers" scrollable scrollHeight="400px">
|
<div class="card">
|
||||||
<Column field="id" header="Id" footer="Id" style="min-width: 100px"></Column>
|
<DataTable :value="customers" scrollable scrollHeight="400px">
|
||||||
<Column field="name" header="Name" footer="Name" style="min-width: 200px"></Column>
|
<Column field="id" header="Id" footer="Id" style="min-width: 100px"></Column>
|
||||||
<Column field="country.name" header="Country" footer="Country" style="min-width: 200px"></Column>
|
<Column field="name" header="Name" footer="Name" style="min-width: 200px"></Column>
|
||||||
<Column field="date" header="Date" footer="Date" style="min-width: 200px"></Column>
|
<Column field="country.name" header="Country" footer="Country" style="min-width: 200px"></Column>
|
||||||
<Column field="balance" header="Balance" footer="Balance" style="min-width: 200px">
|
<Column field="date" header="Date" footer="Date" style="min-width: 200px"></Column>
|
||||||
<template #body="{ data }">
|
<Column field="balance" header="Balance" footer="Balance" style="min-width: 200px">
|
||||||
{{ formatCurrency(data.balance) }}
|
<template #body="{ data }">
|
||||||
</template>
|
{{ formatCurrency(data.balance) }}
|
||||||
</Column>
|
</template>
|
||||||
<Column field="company" header="Company" footer="Company" style="min-width: 200px"></Column>
|
</Column>
|
||||||
<Column field="status" header="Status" footer="Status" style="min-width: 200px"></Column>
|
<Column field="company" header="Company" footer="Company" style="min-width: 200px"></Column>
|
||||||
<Column field="activity" header="Activity" footer="Activity" style="min-width: 200px"></Column>
|
<Column field="status" header="Status" footer="Status" style="min-width: 200px"></Column>
|
||||||
<Column field="representative.name" header="Representative" footer="Representative" style="min-width: 200px"></Column>
|
<Column field="activity" header="Activity" footer="Activity" style="min-width: 200px"></Column>
|
||||||
</DataTable>
|
<Column field="representative.name" header="Representative" footer="Representative" style="min-width: 200px"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -152,12 +154,12 @@ const formatCurrency = (value) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
CustomerService.getCustomersMedium().then((data) => {
|
|
||||||
this.customers = data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
CustomerService.getCustomersMedium().then((data) => {
|
||||||
|
this.customers = data;
|
||||||
|
});
|
||||||
|
},
|
||||||
formatCurrency(value) {
|
formatCurrency(value) {
|
||||||
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<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>
|
<p>Adding <i>scrollable</i> property along with a <i>scrollHeight</i> for the data viewport enables vertical scrolling with fixed headers.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="customers" scrollable scrollHeight="400px" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="name" header="Name"></Column>
|
<DataTable :value="customers" scrollable scrollHeight="400px" tableStyle="min-width: 50rem">
|
||||||
<Column field="country.name" header="Country"></Column>
|
<Column field="name" header="Name"></Column>
|
||||||
<Column field="representative.name" header="Representative"></Column>
|
<Column field="country.name" header="Country"></Column>
|
||||||
<Column field="company" header="Company"></Column>
|
<Column field="representative.name" header="Representative"></Column>
|
||||||
</DataTable>
|
<Column field="company" header="Company"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CustomerService']" />
|
<DocSectionCode :code="code" :service="['CustomerService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -107,10 +109,12 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
CustomerService.getCustomersMedium().then((data) => {
|
loadDemoData() {
|
||||||
this.customers = data;
|
CustomerService.getCustomersMedium().then((data) => {
|
||||||
});
|
this.customers = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" sortMode="multiple" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code" sortable style="width: 25%"></Column>
|
<DataTable :value="products" sortMode="multiple" tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name" sortable style="width: 25%"></Column>
|
<Column field="code" header="Code" sortable style="width: 25%"></Column>
|
||||||
<Column field="category" header="Category" sortable style="width: 25%"></Column>
|
<Column field="name" header="Name" sortable style="width: 25%"></Column>
|
||||||
<Column field="quantity" header="Quantity" sortable style="width: 25%"></Column>
|
<Column field="category" header="Category" sortable style="width: 25%"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity" sortable style="width: 25%"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -98,8 +100,10 @@ const products = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,19 +5,21 @@
|
||||||
<i>DataTableSortMeta</i> objects.
|
<i>DataTableSortMeta</i> objects.
|
||||||
</p>
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" sortField="price" :sortOrder="-1" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code" sortable style="width: 20%"></Column>
|
<DataTable :value="products" sortField="price" :sortOrder="-1" tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name" sortable style="width: 20%"></Column>
|
<Column field="code" header="Code" sortable style="width: 20%"></Column>
|
||||||
<Column field="price" header="Price" :sortable="true">
|
<Column field="name" header="Name" sortable style="width: 20%"></Column>
|
||||||
<template #body="slotProps">
|
<Column field="price" header="Price" :sortable="true">
|
||||||
{{ formatCurrency(slotProps.data.price) }}
|
<template #body="slotProps">
|
||||||
</template>
|
{{ formatCurrency(slotProps.data.price) }}
|
||||||
</Column>
|
</template>
|
||||||
<Column field="category" header="Category" sortable style="width: 20%"></Column>
|
</Column>
|
||||||
<Column field="quantity" header="Quantity" sortable style="width: 20%"></Column>
|
<Column field="category" header="Category" sortable style="width: 20%"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity" sortable style="width: 20%"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -129,10 +131,10 @@ const formatCurrency = (value) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
},
|
||||||
formatCurrency(value) {
|
formatCurrency(value) {
|
||||||
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>When <i>removableSort</i> is present, the third click removes the sorting from the column.</p>
|
<p>When <i>removableSort</i> is present, the third click removes the sorting from the column.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" removableSort tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code" sortable style="width: 25%"></Column>
|
<DataTable :value="products" removableSort tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name" sortable style="width: 25%"></Column>
|
<Column field="code" header="Code" sortable style="width: 25%"></Column>
|
||||||
<Column field="category" header="Category" sortable style="width: 25%"></Column>
|
<Column field="name" header="Name" sortable style="width: 25%"></Column>
|
||||||
<Column field="quantity" header="Quantity" sortable style="width: 25%"></Column>
|
<Column field="category" header="Category" sortable style="width: 25%"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity" sortable style="width: 25%"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -98,8 +100,10 @@ const products = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Sorting on a column is enabled by adding the <i>sortable</i> property.</p>
|
<p>Sorting on a column is enabled by adding the <i>sortable</i> property.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="products" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="code" header="Code" sortable style="width: 25%"></Column>
|
<DataTable :value="products" tableStyle="min-width: 50rem">
|
||||||
<Column field="name" header="Name" sortable style="width: 25%"></Column>
|
<Column field="code" header="Code" sortable style="width: 25%"></Column>
|
||||||
<Column field="category" header="Category" sortable style="width: 25%"></Column>
|
<Column field="name" header="Name" sortable style="width: 25%"></Column>
|
||||||
<Column field="quantity" header="Quantity" sortable style="width: 25%"></Column>
|
<Column field="category" header="Category" sortable style="width: 25%"></Column>
|
||||||
</DataTable>
|
<Column field="quantity" header="Quantity" sortable style="width: 25%"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['ProductService']" />
|
<DocSectionCode :code="code" :service="['ProductService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -98,8 +100,10 @@ const products = ref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
ProductService.getProductsMini().then((data) => (this.products = data));
|
loadDemoData() {
|
||||||
|
ProductService.getProductsMini().then((data) => (this.products = data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -3,51 +3,53 @@
|
||||||
<p>When lazy loading is enabled via the <i>virtualScrollerOptions</i>, data is fetched on demand during scrolling instead of preload.</p>
|
<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>
|
<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>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable
|
<div class="card">
|
||||||
:value="virtualCars"
|
<DataTable
|
||||||
scrollable
|
:value="virtualCars"
|
||||||
scrollHeight="400px"
|
scrollable
|
||||||
:virtualScrollerOptions="{ lazy: true, onLazyLoad: loadCarsLazy, itemSize: 46, delay: 200, showLoader: true, loading: lazyLoading, numToleratedItems: 10 }"
|
scrollHeight="400px"
|
||||||
tableStyle="min-width: 50rem"
|
:virtualScrollerOptions="{ lazy: true, onLazyLoad: loadCarsLazy, itemSize: 46, delay: 200, showLoader: true, loading: lazyLoading, numToleratedItems: 10 }"
|
||||||
>
|
tableStyle="min-width: 50rem"
|
||||||
<Column field="id" header="Id" style="width: 20%">
|
>
|
||||||
<template #loading>
|
<Column field="id" header="Id" style="width: 20%">
|
||||||
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
<template #loading>
|
||||||
<Skeleton width="60%" height="1rem" />
|
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
||||||
</div>
|
<Skeleton width="60%" height="1rem" />
|
||||||
</template>
|
</div>
|
||||||
</Column>
|
</template>
|
||||||
<Column field="vin" header="Vin" style="width: 20%">
|
</Column>
|
||||||
<template #loading>
|
<Column field="vin" header="Vin" style="width: 20%">
|
||||||
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
<template #loading>
|
||||||
<Skeleton width="40%" height="1rem" />
|
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
||||||
</div>
|
<Skeleton width="40%" height="1rem" />
|
||||||
</template>
|
</div>
|
||||||
</Column>
|
</template>
|
||||||
<Column field="year" header="Year" style="width: 20%">
|
</Column>
|
||||||
<template #loading>
|
<Column field="year" header="Year" style="width: 20%">
|
||||||
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
<template #loading>
|
||||||
<Skeleton width="30%" height="1rem" />
|
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
||||||
</div>
|
<Skeleton width="30%" height="1rem" />
|
||||||
</template>
|
</div>
|
||||||
</Column>
|
</template>
|
||||||
<Column field="brand" header="Brand" style="width: 20%">
|
</Column>
|
||||||
<template #loading>
|
<Column field="brand" header="Brand" style="width: 20%">
|
||||||
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
<template #loading>
|
||||||
<Skeleton width="40%" height="1rem" />
|
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
||||||
</div>
|
<Skeleton width="40%" height="1rem" />
|
||||||
</template>
|
</div>
|
||||||
</Column>
|
</template>
|
||||||
<Column field="color" header="Color" style="width: 20%">
|
</Column>
|
||||||
<template #loading>
|
<Column field="color" header="Color" style="width: 20%">
|
||||||
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
<template #loading>
|
||||||
<Skeleton width="60%" height="1rem" />
|
<div class="flex align-items-center" :style="{ height: '17px', 'flex-grow': '1', overflow: 'hidden' }">
|
||||||
</div>
|
<Skeleton width="60%" height="1rem" />
|
||||||
</template>
|
</div>
|
||||||
</Column>
|
</template>
|
||||||
</DataTable>
|
</Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CarService']" />
|
<DocSectionCode :code="code" :service="['CarService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -280,10 +282,10 @@ const loadCarsLazy = (event) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
this.cars = Array.from({ length: 100000 }).map((_, i) => CarService.generateCar(i + 1));
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
loadDemoData() {
|
||||||
|
this.cars = Array.from({ length: 100000 }).map((_, i) => CarService.generateCar(i + 1));
|
||||||
|
},
|
||||||
loadCarsLazy(event) {
|
loadCarsLazy(event) {
|
||||||
!this.lazyLoading && (this.lazyLoading = true);
|
!this.lazyLoading && (this.lazyLoading = true);
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,17 @@
|
||||||
</p>
|
</p>
|
||||||
<p>In this example, <strong>100000</strong> preloaded records are rendered by the Table.</p>
|
<p>In this example, <strong>100000</strong> preloaded records are rendered by the Table.</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<div class="card">
|
<DeferredDemo @load="loadDemoData">
|
||||||
<DataTable :value="cars" scrollable scrollHeight="400px" :virtualScrollerOptions="{ itemSize: 46 }" tableStyle="min-width: 50rem">
|
<div class="card">
|
||||||
<Column field="id" header="Id" style="width: 20%"></Column>
|
<DataTable :value="cars" scrollable scrollHeight="400px" :virtualScrollerOptions="{ itemSize: 46 }" tableStyle="min-width: 50rem">
|
||||||
<Column field="vin" header="Vin" style="width: 20%"></Column>
|
<Column field="id" header="Id" style="width: 20%"></Column>
|
||||||
<Column field="year" header="Year" style="width: 20%"></Column>
|
<Column field="vin" header="Vin" style="width: 20%"></Column>
|
||||||
<Column field="brand" header="Brand" style="width: 20%"></Column>
|
<Column field="year" header="Year" style="width: 20%"></Column>
|
||||||
<Column field="color" header="Color" style="width: 20%"></Column>
|
<Column field="brand" header="Brand" style="width: 20%"></Column>
|
||||||
</DataTable>
|
<Column field="color" header="Color" style="width: 20%"></Column>
|
||||||
</div>
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</DeferredDemo>
|
||||||
<DocSectionCode :code="code" :service="['CarService']" />
|
<DocSectionCode :code="code" :service="['CarService']" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -98,8 +100,10 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
methods: {
|
||||||
this.cars = Array.from({ length: 100000 }).map((_, i) => CarService.generateCar(i + 1));
|
loadDemoData() {
|
||||||
|
this.cars = Array.from({ length: 100000 }).map((_, i) => CarService.generateCar(i + 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
import DeferredDemo from '@/components/demo/DeferredDemo.vue';
|
||||||
import CodeHighlight from '@/directives/CodeHighlight';
|
import CodeHighlight from '@/directives/CodeHighlight';
|
||||||
|
|
||||||
export default defineNuxtPlugin((nuxtApp) => {
|
export default defineNuxtPlugin((nuxtApp) => {
|
||||||
nuxtApp.vueApp.directive('code', CodeHighlight);
|
nuxtApp.vueApp.directive('code', CodeHighlight);
|
||||||
|
nuxtApp.vueApp.component('DeferredDemo', DeferredDemo); // @todo
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue