Fixed #1022 - New Table Responsive layout

pull/1047/head
Cagatay Civici 2021-02-25 12:44:29 +03:00
parent 68389f03d0
commit 48ae20bef1
13 changed files with 221 additions and 548 deletions

View File

@ -362,7 +362,8 @@
},
{
"name": "Responsive",
"to": "/datatable/responsive"
"to": "/datatable/responsive",
"badge": "New"
},
{
"name": "Export",

View File

@ -1,5 +1,6 @@
<template>
<td :style="containerStyle" :class="containerClass" @click="onClick" @keydown="onKeyDown" role="cell">
<span v-if="responsiveLayout === 'stack'" class="p-column-title">{{columnProp('header')}}</span>
<component :is="column.children.body" :data="rowData" :column="column" :index="index" :frozenRow="frozenRow" v-if="column.children && column.children.body && !d_editing" />
<component :is="column.children.editor" :data="rowData" :column="column" :index="index" :frozenRow="frozenRow" v-else-if="column.children && column.children.editor && d_editing" />
<template v-else-if="columnProp('selectionMode')">
@ -71,6 +72,10 @@ export default {
editMode: {
type: String,
default: null
},
responsiveLayout: {
type: String,
default: 'stack'
}
},
documentEditListener: null,

View File

@ -54,7 +54,8 @@ interface DataTableProps {
scrollable?: boolean;
scrollHeight?: string;
frozenValue?: any[];
frozenWidth?: string;
responsiveLayout?: string;
breakpoing?: string;
}
declare class DataTable {

View File

@ -27,7 +27,7 @@
<DTTableBody v-if="frozenValue" :value="frozenValue" :frozenRow="true" class="p-datatable-frozen-tbody" :columns="columns" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection"
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :expandableRowGroups="expandableRowGroups" :rowClass="rowClass" :editMode="editMode" :compareSelectionBy="compareSelectionBy" :scrollable="scrollable"
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$slots" :loading="loading"
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$slots" :loading="loading" :responsiveLayout="responsiveLayout"
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-rightclick="onRowRightClick($event)" @row-touchend="onRowTouchEnd" @row-keydown="onRowKeyDown"
@row-mousedown="onRowMouseDown" @row-dragstart="onRowDragStart($event)" @row-dragover="onRowDragOver($event)" @row-dragleave="onRowDragLeave($event)" @row-dragend="onRowDragEnd($event)" @row-drop="onRowDrop($event)"
@row-toggle="toggleRow($event)" @radio-change="toggleRowWithRadio($event)" @checkbox-change="toggleRowWithCheckbox($event)"
@ -36,7 +36,7 @@
<DTTableBody :value="dataToRender" :columns="columns" :empty="empty" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection"
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :expandableRowGroups="expandableRowGroups" :rowClass="rowClass" :editMode="editMode" :compareSelectionBy="compareSelectionBy" :scrollable="scrollable"
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$slots" :loading="loading"
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$slots" :loading="loading" :responsiveLayout="responsiveLayout"
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-rightclick="onRowRightClick($event)" @row-touchend="onRowTouchEnd" @row-keydown="onRowKeyDown"
@row-mousedown="onRowMouseDown" @row-dragstart="onRowDragStart($event)" @row-dragover="onRowDragOver($event)" @row-dragleave="onRowDragLeave($event)" @row-dragend="onRowDragEnd($event)" @row-drop="onRowDrop($event)"
@row-toggle="toggleRow($event)" @radio-change="toggleRowWithRadio($event)" @checkbox-change="toggleRowWithCheckbox($event)"
@ -64,7 +64,7 @@
</template>
<script>
import {ObjectUtils,DomHandler} from 'primevue/utils';
import {ObjectUtils,DomHandler,UniqueComponentId} from 'primevue/utils';
import {FilterMatchMode,FilterOperator,FilterService} from 'primevue/api';
import Paginator from 'primevue/paginator';
import TableHeader from './TableHeader.vue';
@ -293,6 +293,14 @@ export default {
frozenValue: {
type: Array,
default: null
},
responsiveLayout: {
type: String,
default: 'stack'
},
breakpoint: {
type: String,
default: '960px'
}
},
data() {
@ -376,9 +384,14 @@ export default {
if (this.scrollable && this.scrollDirection !== 'vertical') {
this.updateScrollWidth();
}
if (this.responsiveLayout === 'stack') {
this.createResponsiveStyle();
}
},
beforeUnmount() {
this.unbindColumnResizeEvents();
this.destroyResponsiveStyle();
},
updated() {
if (this.isStateful()) {
@ -1552,6 +1565,47 @@ export default {
},
updateScrollWidth() {
this.$refs.table.style.width = this.$refs.table.scrollWidth + 'px';
},
createResponsiveStyle() {
if (!this.styleElement) {
this.$el.setAttribute(this.attributeSelector, '');
this.styleElement = document.createElement('style');
this.styleElement.type = 'text/css';
document.head.appendChild(this.styleElement);
let innerHTML = `
@media screen and (max-width: ${this.breakpoint}) {
.p-datatable[${this.attributeSelector}] .p-datatable-thead > tr > th,
.p-datatable[${this.attributeSelector}] .p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable[${this.attributeSelector}] .p-datatable-tbody > tr {
border-bottom: 1px solid var(--surface-d);
}
.p-datatable[${this.attributeSelector}] .p-datatable-tbody > tr > td {
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
border: 0 none;
}
.p-datatable[${this.attributeSelector}] .p-datatable-tbody > tr > td > .p-column-title {
display: block;
}
}
`;
this.styleElement.innerHTML = innerHTML;
}
},
destroyResponsiveStyle() {
if (this.styleElement) {
document.head.removeChild(this.styleElement);
this.styleElement = null;
}
}
},
computed: {
@ -1563,10 +1617,12 @@ export default {
'p-datatable-resizable': this.resizableColumns,
'p-datatable-resizable-fit': this.resizableColumns && this.columnResizeMode === 'fit',
'p-datatable-scrollable': this.scrollable,
'p-datatable-scrollable-vertical': this.scrollDirection === 'vertical',
'p-datatable-scrollable-horizontal': this.scrollDirection === 'horizontal',
'p-datatable-scrollable-both': this.scrollDirection === 'both',
'p-datatable-flex-scrollable': (this.scrollable && this.scrollHeight === 'flex')
'p-datatable-scrollable-vertical': this.scrollable && this.scrollDirection === 'vertical',
'p-datatable-scrollable-horizontal': this.scrollable && this.scrollDirection === 'horizontal',
'p-datatable-scrollable-both': this.scrollable && this.scrollDirection === 'both',
'p-datatable-flex-scrollable': (this.scrollable && this.scrollHeight === 'flex'),
'p-datatable-responsive-stack': this.responsiveLayout === 'stack',
'p-datatable-responsive-scroll': this.responsiveLayout === 'scroll'
}
];
},
@ -1691,6 +1747,9 @@ export default {
allRowsSelected() {
const val = this.processedData;
return (val && val.length > 0 && this.selection && this.selection.length > 0 && this.selection.length === val.length);
},
attributeSelector() {
return UniqueComponentId();
}
},
components: {
@ -1711,6 +1770,7 @@ export default {
border-collapse: collapse;
width: 100%;
table-layout: fixed;
white-space: nowrap;
}
.p-datatable .p-sortable-column {
@ -1730,10 +1790,11 @@ export default {
justify-content: center;
}
/*.p-datatable-auto-layout > .p-datatable-wrapper {
.p-datatable-responsive-scroll > .p-datatable-wrapper {
overflow-x: auto;
}*/
}
.p-datatable-responsive-scroll > .p-datatable-wrapper > table,
.p-datatable-auto-layout > .p-datatable-wrapper > table {
table-layout: auto;
}
@ -1964,4 +2025,9 @@ export default {
.p-column-filter-buttonbar .p-button:not(.p-button-icon-only) {
width: auto;
}
/* Responsive */
.p-datatable .p-datatable-tbody .p-column-title {
display: none;
}
</style>

View File

@ -18,7 +18,7 @@
<DTBodyCell v-if="shouldRenderBodyCell(value, col, index)" :rowData="rowData" :column="col" :index="index" :selected="isSelected(rowData)"
:rowTogglerIcon="columnProp(col,'expander') ? rowTogglerIcon(rowData): null" :frozenRow="frozenRow"
:rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(value, col, index) : null"
:editMode="editMode" :editing="editMode === 'row' && isRowEditing(rowData)"
:editMode="editMode" :editing="editMode === 'row' && isRowEditing(rowData)" :responsiveLayout="responsiveLayout"
@radio-change="onRadioChange($event)" @checkbox-change="onCheckboxChange($event)" @row-toggle="onRowToggle($event)"
@cell-edit-init="onCellEditInit($event)" @cell-edit-complete="onCellEditComplete($event)" @cell-edit-cancel="onCellEditCancel($event)"
@row-edit-init="onRowEditInit($event)" @row-edit-save="onRowEditSave($event)" @row-edit-cancel="onRowEditCancel($event)"/>
@ -156,6 +156,10 @@ export default {
scrollable: {
type: Boolean,
default: false
},
responsiveLayout: {
type: String,
default: 'stack'
}
},
mounted() {

View File

@ -22,7 +22,7 @@
<TabView>
<TabPanel header="Source">
<div class="p-d-flex p-jc-end">
<LiveEditor name="DataTableDemo" :sources="sources" service="ProductService" data="products-small"/>
<LiveEditor name="DataTableDemo" :sources="sources" service="ProductService" data="products-small" :components="['Column']" />
</div>
<pre v-code><code><template v-pre>
&lt;DataTable :value="products"&gt;
@ -69,18 +69,18 @@ export default {
sources: {
'template': {
content: `<template>
<div class="layout-content">
<div class="content-section implementation">
<div class="card">
<DataTable :value="products">
<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>
<div class="layout-content">
<div class="content-section implementation">
<div class="card">
<DataTable :value="products">
<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>
</div>
</template>
<script>
import ProductService from '../service/ProductService';

View File

@ -32,7 +32,6 @@
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
<Column field="name" header="Name" sortable>
<template #body="{data}">
<span class="p-column-title">Name</span>
{{data.name}}
</template>
<template #filter="{filterModel}">
@ -41,7 +40,6 @@
</Column>
<Column field="country.name" header="Country" sortable filterMatchMode="contains">
<template #body="{data}">
<span class="p-column-title">Country</span>
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + data.country.code" width="30" />
<span class="image-text">{{data.country.name}}</span>
</template>
@ -51,7 +49,6 @@
</Column>
<Column header="Agent" sortable sortField="representative.name" :showFilterMatchModes="false" :filterMenuStyle="{'width':'14rem'}">
<template #body="{data}">
<span class="p-column-title">Agent</span>
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{data.representative.name}}</span>
</template>
@ -69,7 +66,6 @@
</Column>
<Column field="date" header="Date" sortable dataType="date">
<template #body="{data}">
<span class="p-column-title">Date</span>
{{formatDate(data.date)}}
</template>
<template #filter="{filterModel}">
@ -78,7 +74,6 @@
</Column>
<Column field="balance" header="Balance" sortable dataType="numeric">
<template #body="{data}">
<span class="p-column-title">Balance</span>
{{formatCurrency(data.balance)}}
</template>
<template #filter="{filterModel}">
@ -87,7 +82,6 @@
</Column>
<Column field="status" header="Status" sortable :filterMenuStyle="{'width':'14rem'}">
<template #body="{data}">
<span class="p-column-title">Status</span>
<span :class="'customer-badge status-' + data.status">{{data.status}}</span>
</template>
<template #filter="{filterModel}">
@ -103,7 +97,6 @@
</Column>
<Column field="activity" header="Activity" sortable :showFilterMatchModes="false">
<template #body="{data}">
<span class="p-column-title">Activity</span>
<ProgressBar :value="data.activity" :showValue="false" />
</template>
<template #filter="{filterModel}">
@ -241,46 +234,4 @@ export default {
text-transform: uppercase;
}
}
/* Responsive */
.p-datatable-customers .p-datatable-tbody > tr > td .p-column-title {
display: none;
}
@media screen and (max-width: 1200px) {
::v-deep(.p-datatable) {
&.p-datatable-customers {
.p-datatable-thead > tr > th,
.p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable-tbody > tr {
border-bottom: 1px solid var(--layer-2);
> td {
text-align: left;
display: block;
border: 0 none !important;
width: 100% !important;
float: left;
clear: left;
border: 0 none;
.p-column-title {
padding: .4rem;
min-width: 30%;
display: inline-block;
margin: -.4rem 1rem -.4rem -.4rem;
font-weight: bold;
}
.p-progressbar {
margin-top: .5rem;
}
}
}
}
}
}
</style>

View File

@ -1779,95 +1779,29 @@ export default {
</code></pre>
<h5>Responsive</h5>
<p>DataTable display can be optimized according to screen sizes, this example demonstrates a sample demo where columns are stacked on small screens.</p>
<h5>Responsive</h5>
<p>DataTable responsive layout can be achieved in two ways; first approach is displaying a horizontal scrollbar for smaller screens
and second one is defining a breakpoint to display the cells of a row as stacked.</p>
<h6>Scroll Layout</h6>
<p>Set <i>responsiveLayout</i> to scroll to enabled this layout. Note that, when scroll mode is enabled table-layout automatically switches to auto from fixed
as a result table widths are likely to differ and resizable columns are not supported. Read more about <a href="https://www.w3schools.com/cssref/pr_tab_table-layout.asp">table-layout</a> for more details.</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" class="p-datatable-responsive-demo"&gt;
&lt;template #header&gt;
Responsive
&lt;/template&gt;
&lt;Column field="vin" header="Vin"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Vin&lt;/span&gt;
&#123;&#123;slotProps.data.vin&#125;&#125;
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="year" header="Year"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Year&lt;/span&gt;
&#123;&#123;slotProps.data.year&#125;&#125;
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="brand" header="Brand"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Brand&lt;/span&gt;
&#123;&#123;slotProps.data.brand&#125;&#125;
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="color" header="Color"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Color&lt;/span&gt;
&#123;&#123;slotProps.data.color&#125;&#125;
&lt;/template&gt;
&lt;/Column&gt;
&lt;DataTable :value="products" responsiveLayout="scroll"&gt;
&lt;/DataTable&gt;
</template>
</code></pre>
<pre v-code.script><code>
import CarService from '../../service/CarService';
export default {
data() {
return {
cars: null
}
},
carService: null,
created() {
this.carService = new CarService();
},
mounted() {
this.carService.getCarsSmall().then(data => this.cars = data);
}
}
</code></pre>
<pre v-code.css><code>
.p-datatable-responsive-demo .p-datatable-tbody > tr > td .p-column-title {
display: none;
}
@media screen and (max-width: 40rem) {
::v-deep(.p-datatable) {
&.p-datatable-responsive-demo {
.p-datatable-thead > tr > th,
.p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable-tbody > tr > td {
text-align: left;
display: block;
border: 0 none !important;
width: 100% !important;
float: left;
clear: left;
.p-column-title {
padding: .4rem;
min-width: 30%;
display: inline-block;
margin: -.4em 1em -.4em -.4rem;
font-weight: bold;
}
}
}
}
}
</code></pre>
<h6>Stack Layout</h6>
<p>In stack layout, columns are displayed as stacked after a certain breakpoint. Default is '960px'.</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="products" responsiveLayout="stack" breakpoint="640px"&gt;
&lt;/DataTable&gt;
</template>
</code></pre>
<h5>Row and Cell Styling</h5>
<p>Certain rows or cells can easily be styled based on conditions. Cell styling is implemented with templating whereas row styling utilizes the <i>rowClass</i> property which takes the
@ -2265,6 +2199,18 @@ export default {
<td>null</td>
<td>Items of the frozen part in scrollable DataTable.</td>
</tr>
<tr>
<td>responsiveLayout</td>
<td>string</td>
<td>stack</td>
<td>Defines the responsive mode, valid options are "stack" and "scroll".</td>
</tr>
<tr>
<td>breakpoint</td>
<td>string</td>
<td>960px</td>
<td>The breakpoint to define the maximum width boundary when using stack responsive layout.</td>
</tr>
</tbody>
</table>
</div>
@ -2684,7 +2630,6 @@ export default {
&lt;Column selectionMode="multiple" headerStyle="width: 3rem"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name" sortable&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Name&lt;/span&gt;
{{data.name}}
&lt;/template&gt;
&lt;template #filter="{filterModel}"&gt;
@ -2693,7 +2638,6 @@ export default {
&lt;/Column&gt;
&lt;Column field="country.name" header="Country" sortable filterMatchMode="contains"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Country&lt;/span&gt;
&lt;img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + data.country.code" width="30" /&gt;
&lt;span class="image-text"&gt;{{data.country.name}}&lt;/span&gt;
&lt;/template&gt;
@ -2703,7 +2647,6 @@ export default {
&lt;/Column&gt;
&lt;Column header="Agent" sortable sortField="representative.name" :showFilterMatchModes="false" :filterMenuStyle="{'width':'14rem'}"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Agent&lt;/span&gt;
&lt;img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" /&gt;
&lt;span class="image-text"&gt;{{data.representative.name}}&lt;/span&gt;
&lt;/template&gt;
@ -2721,7 +2664,6 @@ export default {
&lt;/Column&gt;
&lt;Column field="date" header="Date" sortable dataType="date"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Date&lt;/span&gt;
{{formatDate(data.date)}}
&lt;/template&gt;
&lt;template #filter="{filterModel}"&gt;
@ -2730,7 +2672,6 @@ export default {
&lt;/Column&gt;
&lt;Column field="balance" header="Balance" sortable dataType="numeric"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Balance&lt;/span&gt;
{{formatCurrency(data.balance)}}
&lt;/template&gt;
&lt;template #filter="{filterModel}"&gt;
@ -2739,7 +2680,6 @@ export default {
&lt;/Column&gt;
&lt;Column field="status" header="Status" sortable :filterMenuStyle="{'width':'14rem'}"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Status&lt;/span&gt;
&lt;span :class="'customer-badge status-' + data.status"&gt;{{data.status}}&lt;/span&gt;
&lt;/template&gt;
&lt;template #filter="{filterModel}"&gt;
@ -2755,7 +2695,6 @@ export default {
&lt;/Column&gt;
&lt;Column field="activity" header="Activity" sortable :showFilterMatchModes="false"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Activity&lt;/span&gt;
&lt;ProgressBar :value="data.activity" :showValue="false" /&gt;
&lt;/template&gt;
&lt;template #filter="{filterModel}"&gt;
@ -2878,7 +2817,6 @@ export default {
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
<Column field="name" header="Name" sortable>
<template #body="{data}">
<span class="p-column-title">Name</span>
{{data.name}}
</template>
<template #filter="{filterModel}">
@ -2887,7 +2825,6 @@ export default {
</Column>
<Column field="country.name" header="Country" sortable filterMatchMode="contains">
<template #body="{data}">
<span class="p-column-title">Country</span>
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" :class="'flag flag-' + data.country.code" width="30" />
<span class="image-text">{{data.country.name}}</span>
</template>
@ -2897,7 +2834,6 @@ export default {
</Column>
<Column header="Agent" sortable sortField="representative.name" :showFilterMatchModes="false" :filterMenuStyle="{'width':'14rem'}">
<template #body="{data}">
<span class="p-column-title">Agent</span>
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{data.representative.name}}</span>
</template>
@ -2915,7 +2851,6 @@ export default {
</Column>
<Column field="date" header="Date" sortable dataType="date">
<template #body="{data}">
<span class="p-column-title">Date</span>
{{formatDate(data.date)}}
</template>
<template #filter="{filterModel}">
@ -2924,7 +2859,6 @@ export default {
</Column>
<Column field="balance" header="Balance" sortable dataType="numeric">
<template #body="{data}">
<span class="p-column-title">Balance</span>
{{formatCurrency(data.balance)}}
</template>
<template #filter="{filterModel}">
@ -2933,7 +2867,6 @@ export default {
</Column>
<Column field="status" header="Status" sortable :filterMenuStyle="{'width':'14rem'}">
<template #body="{data}">
<span class="p-column-title">Status</span>
<span :class="'customer-badge status-' + data.status">{{data.status}}</span>
</template>
<template #filter="{filterModel}">
@ -2949,7 +2882,6 @@ export default {
</Column>
<Column field="activity" header="Activity" sortable :showFilterMatchModes="false">
<template #body="{data}">
<span class="p-column-title">Activity</span>
<ProgressBar :value="data.activity" :showValue="false" />
</template>
<template #filter="{filterModel}">
@ -3079,48 +3011,6 @@ export default {
text-transform: uppercase;
}
}
/* Responsive */
.p-datatable-customers .p-datatable-tbody > tr > td .p-column-title {
display: none;
}
@media screen and (max-width: 1200px) {
::v-deep(.p-datatable) {
&.p-datatable-customers {
.p-datatable-thead > tr > th,
.p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable-tbody > tr {
border-bottom: 1px solid var(--layer-2);
> td {
text-align: left;
display: block;
border: 0 none !important;
width: 100% !important;
float: left;
clear: left;
border: 0 none;
.p-column-title {
padding: .4rem;
min-width: 30%;
display: inline-block;
margin: -.4rem 1rem -.4rem -.4rem;
font-weight: bold;
}
.p-progressbar {
margin-top: .5rem;
}
}
}
}
}
}
</style>`
}
}

View File

@ -31,7 +31,6 @@
</template>
<Column field="name" header="Name">
<template #body="{data}">
<span class="p-column-title">Name</span>
{{data.name}}
</template>
<template #filter="{filterModel}">
@ -40,7 +39,6 @@
</Column>
<Column header="Country" filterField="country.name">
<template #body="{data}">
<span class="p-column-title">Country</span>
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + data.country.code" width="30" />
<span class="image-text">{{data.country.name}}</span>
</template>
@ -59,7 +57,6 @@
</Column>
<Column header="Agent" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{'width':'14rem'}">
<template #body="{data}">
<span class="p-column-title">Agent</span>
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{data.representative.name}}</span>
</template>
@ -77,7 +74,6 @@
</Column>
<Column header="Date" filterField="date" dataType="date">
<template #body="{data}">
<span class="p-column-title">Date</span>
{{formatDate(data.date)}}
</template>
<template #filter="{filterModel}">
@ -86,7 +82,6 @@
</Column>
<Column header="Balance" filterField="balance" dataType="numeric">
<template #body="{data}">
<span class="p-column-title">Balance</span>
{{formatCurrency(data.balance)}}
</template>
<template #filter="{filterModel}">
@ -95,7 +90,6 @@
</Column>
<Column field="status" header="Status" :filterMenuStyle="{'width':'14rem'}">
<template #body="{data}">
<span class="p-column-title">Status</span>
<span :class="'customer-badge status-' + data.status">{{data.status}}</span>
</template>
<template #filter="{filterModel}">
@ -112,7 +106,6 @@
</Column>
<Column field="activity" header="Activity" :showFilterMatchModes="false">
<template #body="{data}">
<span class="p-column-title">Status</span>
<ProgressBar :value="data.activity" :showValue="false"></ProgressBar>
</template>
<template #filter={filterModel}>
@ -125,7 +118,6 @@
</Column>
<Column field="verified" header="Verified" dataType="boolean" headerStyle="width: 8rem" bodyClass="p-text-center">
<template #body="{data}">
<span class="p-column-title">Verified</span>
<i class="pi" :class="{'true-icon pi-check-circle': data.verified, 'false-icon pi-times-circle': !data.verified}"></i>
</template>
<template #filter={filterModel}>
@ -157,7 +149,6 @@
</template>
<Column field="name" header="Name">
<template #body="{data}">
<span class="p-column-title">Name</span>
{{data.name}}
</template>
<template #filter="{filterModel,filterCallback}">
@ -166,7 +157,6 @@
</Column>
<Column header="Country" filterField="country.name">
<template #body="{data}">
<span class="p-column-title">Country</span>
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + data.country.code" width="30" />
<span class="image-text">{{data.country.name}}</span>
</template>
@ -176,7 +166,6 @@
</Column>
<Column header="Agent" filterField="representative" :showFilterMenu="false">
<template #body="{data}">
<span class="p-column-title">Agent</span>
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{data.representative.name}}</span>
</template>
@ -193,7 +182,6 @@
</Column>
<Column field="status" header="Status" :showFilterMenu="false">
<template #body="{data}">
<span class="p-column-title">Status</span>
<span :class="'customer-badge status-' + data.status">{{data.status}}</span>
</template>
<template #filter="{filterModel,filterCallback}">
@ -210,7 +198,6 @@
</Column>
<Column field="verified" header="Verified" dataType="boolean" headerStyle="width: 6rem">
<template #body="{data}">
<span class="p-column-title">Verified</span>
<i class="pi" :class="{'true-icon pi-check-circle': data.verified, 'false-icon pi-times-circle': !data.verified}"></i>
</template>
<template #filter="{filterModel,filterCallback}">
@ -248,7 +235,6 @@
&lt;/template&gt;
&lt;Column field="name" header="Name"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Name&lt;/span&gt;
{{data.name}}
&lt;/template&gt;
&lt;template #filter="{filterModel}"&gt;
@ -257,7 +243,6 @@
&lt;/Column&gt;
&lt;Column header="Country" filterField="country.name"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Country&lt;/span&gt;
&lt;img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + data.country.code" width="30" /&gt;
&lt;span class="image-text"&gt;{{data.country.name}}&lt;/span&gt;
&lt;/template&gt;
@ -276,7 +261,6 @@
&lt;/Column&gt;
&lt;Column header="Agent" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{'width':'14rem'}"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Agent&lt;/span&gt;
&lt;img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" /&gt;
&lt;span class="image-text"&gt;{{data.representative.name}}&lt;/span&gt;
&lt;/template&gt;
@ -294,7 +278,6 @@
&lt;/Column&gt;
&lt;Column header="Date" filterField="date" dataType="date"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Date&lt;/span&gt;
{{formatDate(data.date)}}
&lt;/template&gt;
&lt;template #filter="{filterModel}"&gt;
@ -303,7 +286,6 @@
&lt;/Column&gt;
&lt;Column header="Balance" filterField="balance" dataType="numeric"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Balance&lt;/span&gt;
{{formatCurrency(data.balance)}}
&lt;/template&gt;
&lt;template #filter="{filterModel}"&gt;
@ -312,7 +294,6 @@
&lt;/Column&gt;
&lt;Column field="status" header="Status" :filterMenuStyle="{'width':'14rem'}"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Status&lt;/span&gt;
&lt;span :class="'customer-badge status-' + data.status"&gt;{{data.status}}&lt;/span&gt;
&lt;/template&gt;
&lt;template #filter="{filterModel}"&gt;
@ -329,7 +310,6 @@
&lt;/Column&gt;
&lt;Column field="activity" header="Activity" :showFilterMatchModes="false"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Status&lt;/span&gt;
&lt;ProgressBar :value="data.activity" :showValue="false"&gt;&lt;/ProgressBar&gt;
&lt;/template&gt;
&lt;template #filter={filterModel}&gt;
@ -342,7 +322,6 @@
&lt;/Column&gt;
&lt;Column field="verified" header="Verified" dataType="boolean" headerStyle="width: 8rem" bodyClass="p-text-center"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Verified&lt;/span&gt;
&lt;i class="pi" :class="{'true-icon pi-check-circle': data.verified, 'false-icon pi-times-circle': !data.verified}"&gt;&lt;/i&gt;
&lt;/template&gt;
&lt;template #filter={filterModel}&gt;
@ -374,7 +353,6 @@
&lt;/template&gt;
&lt;Column field="name" header="Name"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Name&lt;/span&gt;
{{data.name}}
&lt;/template&gt;
&lt;template #filter="{filterModel,filterCallback}"&gt;
@ -383,7 +361,6 @@
&lt;/Column&gt;
&lt;Column header="Country" filterField="country.name"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Country&lt;/span&gt;
&lt;img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + data.country.code" width="30" /&gt;
&lt;span class="image-text"&gt;{{data.country.name}}&lt;/span&gt;
&lt;/template&gt;
@ -393,7 +370,6 @@
&lt;/Column&gt;
&lt;Column header="Agent" filterField="representative" :showFilterMenu="false"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Agent&lt;/span&gt;
&lt;img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" /&gt;
&lt;span class="image-text"&gt;{{data.representative.name}}&lt;/span&gt;
&lt;/template&gt;
@ -410,7 +386,6 @@
&lt;/Column&gt;
&lt;Column field="status" header="Status" :showFilterMenu="false"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Status&lt;/span&gt;
&lt;span :class="'customer-badge status-' + data.status"&gt;{{data.status}}&lt;/span&gt;
&lt;/template&gt;
&lt;template #filter="{filterModel,filterCallback}"&gt;
@ -427,7 +402,6 @@
&lt;/Column&gt;
&lt;Column field="verified" header="Verified" dataType="boolean" headerStyle="width: 6rem"&gt;
&lt;template #body="{data}"&gt;
&lt;span class="p-column-title"&gt;Verified&lt;/span&gt;
&lt;i class="pi" :class="{'true-icon pi-check-circle': data.verified, 'false-icon pi-times-circle': !data.verified}"&gt;&lt;/i&gt;
&lt;/template&gt;
&lt;template #filter="{filterModel,filterCallback}"&gt;
@ -661,46 +635,4 @@ export default {
text-transform: uppercase;
}
}
/* Responsive */
.p-datatable-customers .p-datatable-tbody > tr > td .p-column-title {
display: none;
}
@media screen and (max-width: 960px) {
::v-deep(.p-datatable) {
&.p-datatable-customers {
.p-datatable-thead > tr > th,
.p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable-tbody > tr {
border-bottom: 1px solid var(--layer-2);
> td {
text-align: left;
display: block;
border: 0 none !important;
width: 100% !important;
float: left;
clear: left;
border: 0 none;
.p-column-title {
padding: .4rem;
min-width: 30%;
display: inline-block;
margin: -.4rem 1rem -.4rem -.4rem;
font-weight: bold;
}
.p-progressbar {
margin-top: .5rem;
}
}
}
}
}
}
</style>

View File

@ -3,40 +3,37 @@
<div class="content-section introduction">
<div class="feature-intro">
<h1>DataTable <span>Responsive</span></h1>
<p>DataTable display can be optimized according for different screen sizes, this example demonstrates a demo where columns are stacked on a small screens.</p>
<p>DataTable responsive layout can be achieved in two ways; first approach is displaying a horizontal scrollbar for smaller screens
and second one is defining a breakpoint to display the cells of a row as stacked.</p>
</div>
</div>
<div class="content-section implementation">
<div class="card">
<DataTable :value="products" class="p-datatable-responsive-demo" :paginator="true" :rows="10">
<DataTable :value="products" responsiveLayout="scroll">
<template #header>
Responsive
Scroll
</template>
<Column field="code" header="Code">
<template #body="slotProps">
<span class="p-column-title">Code</span>
{{slotProps.data.code}}
</template>
</Column>
<Column field="name" header="Name">
<template #body="slotProps">
<span class="p-column-title">Name</span>
{{slotProps.data.name}}
</template>
</Column>
<Column field="category" header="Category">
<template #body="slotProps">
<span class="p-column-title">Category</span>
{{slotProps.data.category}}
</template>
</Column>
<Column field="quantity" header="Quantity">
<template #body="slotProps">
<span class="p-column-title">Quantity</span>
{{slotProps.data.quantity}}
</template>
</Column>
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
<Column field="category" header="Category"></Column>
<Column field="quantity" header="Quantity"></Column>
<Column field="inventoryStatus" header="Status"></Column>
<Column field="rating" header="Rating"></Column>
</DataTable>
</div>
<div class="card">
<DataTable :value="products" responsiveLayout="stack" breakpoint="960px">
<template #header>
Stack
</template>
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
<Column field="category" header="Category"></Column>
<Column field="quantity" header="Quantity"></Column>
<Column field="inventoryStatus" header="Status"></Column>
<Column field="rating" header="Rating"></Column>
</DataTable>
</div>
</div>
@ -45,38 +42,36 @@
<TabView>
<TabPanel header="Source">
<div class="p-d-flex p-jc-end">
<LiveEditor name="DataTableDemo" :sources="sources" service="ProductService" data="products" :components="['Column']" />
<LiveEditor name="DataTableDemo" :sources="sources" service="ProductService" data="products-small" :components="['Column']" />
</div>
<pre v-code><code><template v-pre>
&lt;DataTable :value="products" class="p-datatable-responsive-demo" :paginator="true" :rows="10"&gt;
&lt;template #header&gt;
Responsive
&lt;/template&gt;
&lt;Column field="code" header="Code"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Code&lt;/span&gt;
{{slotProps.data.code}}
&lt;div class="card"&gt;
&lt;DataTable :value="products" responsiveLayout="scroll"&gt;
&lt;template #header&gt;
Scroll
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="name" header="Name"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Name&lt;/span&gt;
{{slotProps.data.name}}
&lt;Column field="code" header="Code"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name"&gt;&lt;/Column&gt;
&lt;Column field="category" header="Category"&gt;&lt;/Column&gt;
&lt;Column field="quantity" header="Quantity"&gt;&lt;/Column&gt;
&lt;Column field="inventoryStatus" header="Status"&gt;&lt;/Column&gt;
&lt;Column field="rating" header="Rating"&gt;&lt;/Column&gt;
&lt;/DataTable&gt;
&lt;/div&gt;
&lt;div class="card"&gt;
&lt;DataTable :value="products" responsiveLayout="stack" breakpoint="960px"&gt;
&lt;template #header&gt;
Stack
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="category" header="Category"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Category&lt;/span&gt;
{{slotProps.data.category}}
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="quantity" header="Quantity"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Quantity&lt;/span&gt;
{{slotProps.data.quantity}}
&lt;/template&gt;
&lt;/Column&gt;
&lt;/DataTable&gt;
&lt;Column field="code" header="Code"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name"&gt;&lt;/Column&gt;
&lt;Column field="category" header="Category"&gt;&lt;/Column&gt;
&lt;Column field="quantity" header="Quantity"&gt;&lt;/Column&gt;
&lt;Column field="inventoryStatus" header="Status"&gt;&lt;/Column&gt;
&lt;Column field="rating" header="Rating"&gt;&lt;/Column&gt;
&lt;/DataTable&gt;
&lt;/div&gt;
</template>
</code></pre>
@ -94,49 +89,10 @@ export default {
this.productService = new ProductService();
},
mounted() {
this.productService.getProducts().then(data => this.products = data);
this.productService.getProductsSmall().then(data => this.products = data);
}
}
</code></pre>
<pre v-code.css><code>
.p-datatable-responsive-demo .p-datatable-tbody > tr > td .p-column-title {
display: none;
}
@media screen and (max-width: 40em) {
::v-deep(.p-datatable) {
&.p-datatable-responsive-demo {
.p-datatable-thead > tr > th,
.p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable-tbody > tr > td {
text-align: left;
display: block;
width: 100%;
float: left;
clear: left;
border: 0 none;
.p-column-title {
padding: .4rem;
min-width: 30%;
display: inline-block;
margin: -.4em 1em -.4em -.4rem;
font-weight: bold;
}
&:last-child {
border-bottom: 1px solid var(--surface-d);
}
}
}
}
}
</code></pre>
</TabPanel>
</TabView>
@ -155,41 +111,37 @@ export default {
sources: {
'template': {
content: `<template>
<div class="layout-content">
<div class="content-section implementation">
<div class="card">
<DataTable :value="products" class="p-datatable-responsive-demo" :paginator="true" :rows="10">
<template #header>
Responsive
</template>
<Column field="code" header="Code">
<template #body="slotProps">
<span class="p-column-title">Code</span>
{{slotProps.data.code}}
</template>
</Column>
<Column field="name" header="Name">
<template #body="slotProps">
<span class="p-column-title">Name</span>
{{slotProps.data.name}}
</template>
</Column>
<Column field="category" header="Category">
<template #body="slotProps">
<span class="p-column-title">Category</span>
{{slotProps.data.category}}
</template>
</Column>
<Column field="quantity" header="Quantity">
<template #body="slotProps">
<span class="p-column-title">Quantity</span>
{{slotProps.data.quantity}}
</template>
</Column>
</DataTable>
</div>
</div>
<div class="layout-content">
<div class="content-section implementation">
<div class="card">
<DataTable :value="products" responsiveLayout="scroll">
<template #header>
Scroll
</template>
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
<Column field="category" header="Category"></Column>
<Column field="quantity" header="Quantity"></Column>
<Column field="inventoryStatus" header="Status"></Column>
<Column field="rating" header="Rating"></Column>
</DataTable>
</div>
<div class="card">
<DataTable :value="products" responsiveLayout="stack" breakpoint="960px">
<template #header>
Stack
</template>
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
<Column field="category" header="Category"></Column>
<Column field="quantity" header="Quantity"></Column>
<Column field="inventoryStatus" header="Status"></Column>
<Column field="rating" header="Rating"></Column>
</DataTable>
</div>
</div>
</div>
</template>
<script>
@ -206,46 +158,9 @@ export default {
this.productService = new ProductService();
},
mounted() {
this.productService.getProducts().then(data => this.products = data);
this.productService.getProductsSmall().then(data => this.products = data);
}
}`,
style: `<style lang="scss" scoped>
.p-datatable-responsive-demo .p-datatable-tbody > tr > td .p-column-title {
display: none;
}
@media screen and (max-width: 40em) {
::v-deep(.p-datatable) {
&.p-datatable-responsive-demo {
.p-datatable-thead > tr > th,
.p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable-tbody > tr > td {
text-align: left;
display: block;
width: 100%;
float: left;
clear: left;
border: 0 none;
.p-column-title {
padding: .4rem;
min-width: 30%;
display: inline-block;
margin: -.4em 1em -.4em -.4rem;
font-weight: bold;
}
&:last-child {
border-bottom: 1px solid var(--surface-d);
}
}
}
}
}
</style>`
}`
}
}
}
@ -255,48 +170,10 @@ export default {
this.productService = new ProductService();
},
mounted() {
this.productService.getProducts().then(data => this.products = data);
this.productService.getProductsSmall().then(data => this.products = data);
},
components: {
LiveEditor
}
}
</script>
<style lang="scss" scoped>
.p-datatable-responsive-demo .p-datatable-tbody > tr > td .p-column-title {
display: none;
}
@media screen and (max-width: 40em) {
::v-deep(.p-datatable) {
&.p-datatable-responsive-demo {
.p-datatable-thead > tr > th,
.p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable-tbody > tr > td {
text-align: left;
display: block;
width: 100%;
float: left;
clear: left;
border: 0 none;
.p-column-title {
padding: .4rem;
min-width: 30%;
display: inline-block;
margin: -.4em 1em -.4em -.4rem;
font-weight: bold;
}
&:last-child {
border-bottom: 1px solid var(--surface-d);
}
}
}
}
}
</style>
</script>

View File

@ -12,7 +12,7 @@
<h5>Table Integration</h5>
<p>A custom equals filter that checks for exact case sensitive value is registered and defined as a match mode of a column filter.</p>
<DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
<DataTable :value="customers" :paginator="true" :rows="10"
dataKey="id" v-model:filters="filters" filterDisplay="row" :loading="loading">
<template #empty>
No customers found.

View File

@ -206,7 +206,7 @@ FilterService.filters['isPrimeNumber'](568985673); //false
</a>
</div>
<pre v-code><code><template v-pre>
&lt;DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
&lt;DataTable :value="customers" :paginator="true" :rows="10"
dataKey="id" v-model:filters="filters" filterDisplay="row" :loading="loading"&gt;
&lt;template #empty&gt;
No customers found.

View File

@ -260,7 +260,7 @@
<div class="p-col-12">
<div class="card">
<DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
<DataTable :value="customers" :paginator="true" :rows="10"
dataKey="id" :rowHover="true" v-model:selection="selectedCustomers" :filters="filters"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[10,25,50]"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries">
@ -279,39 +279,33 @@
<Column selectionMode="multiple" headerStyle="width: 3em"></Column>
<Column field="name" header="Name" :sortable="true">
<template #body="slotProps">
<span class="p-column-title">Name</span>
{{slotProps.data.name}}
</template>
</Column>
<Column header="Country" :sortable="true" sortField="country.name" filterField="country.name" filterMatchMode="contains">
<template #body="slotProps">
<span class="p-column-title">Country</span>
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.data.country.code" width="30" class="p-mr-2" />
<span class="image-text">{{slotProps.data.country.name}}</span>
</template>
</Column>
<Column header="Representative" :sortable="true" sortField="representative.name" filterField="representative.name" filterMatchMode="in">
<template #body="slotProps">
<span class="p-column-title">Representative</span>
<img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text p-ml-2">{{slotProps.data.representative.name}}</span>
</template>
</Column>
<Column field="date" header="Date" :sortable="true" filterMatchMode="equals">
<template #body="slotProps">
<span class="p-column-title">Date</span>
<span>{{slotProps.data.date}}</span>
</template>
</Column>
<Column field="status" header="Status" :sortable="true" filterMatchMode="equals">
<template #body="slotProps">
<span class="p-column-title">Status</span>
<span :class="'customer-badge status-' + slotProps.data.status">{{slotProps.data.status}}</span>
</template>
</Column>
<Column field="activity" header="Activity" :sortable="true" filterMatchMode="gte">
<template #body="slotProps">
<span class="p-column-title">Activity</span>
<ProgressBar :value="slotProps.data.activity" :showValue="false" />
</template>
</Column>
@ -794,7 +788,7 @@
&lt;div class="p-col-12"&gt;
&lt;div class="card"&gt;
&lt;DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
&lt;DataTable :value="customers" :paginator="true" :rows="10"
dataKey="id" :rowHover="true" v-model:selection="selectedCustomers" :filters="filters"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[10,25,50]"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"&gt;
@ -813,39 +807,33 @@
&lt;Column selectionMode="multiple" headerStyle="width: 3em"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name" :sortable="true"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Name&lt;/span&gt;
{{slotProps.data.name}}
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column header="Country" :sortable="true" sortField="country.name" filterField="country.name" filterMatchMode="contains"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Country&lt;/span&gt;
&lt;img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.data.country.code" width="30" class="p-mr-2" /&gt;
&lt;span class="image-text"&gt;{{slotProps.data.country.name}}&lt;/span&gt;
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column header="Representative" :sortable="true" sortField="representative.name" filterField="representative.name" filterMatchMode="in"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Representative&lt;/span&gt;
&lt;img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" /&gt;
&lt;span class="image-text p-ml-2"&gt;{{slotProps.data.representative.name}}&lt;/span&gt;
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="date" header="Date" :sortable="true" filterMatchMode="equals"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Date&lt;/span&gt;
&lt;span&gt;{{slotProps.data.date}}&lt;/span&gt;
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="status" header="Status" :sortable="true" filterMatchMode="equals"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Status&lt;/span&gt;
&lt;span :class="'customer-badge status-' + slotProps.data.status"&gt;{{slotProps.data.status}}&lt;/span&gt;
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="activity" header="Activity" :sortable="true" filterMatchMode="gte"&gt;
&lt;template #body="slotProps"&gt;
&lt;span class="p-column-title"&gt;Activity&lt;/span&gt;
&lt;ProgressBar :value="slotProps.data.activity" :showValue="false" /&gt;
&lt;/template&gt;
&lt;/Column&gt;
@ -1722,48 +1710,6 @@ export default {
box-shadow: 0 3px 6px rgba(0,0,0,.16), 0 3px 6px rgba(0,0,0,.23);
}
/* Responsive */
.p-datatable-customers .p-datatable-tbody > tr > td .p-column-title {
display: none;
}
@media screen and (max-width: 960px) {
::v-deep(.p-datatable) {
&.p-datatable-customers {
.p-datatable-thead > tr > th,
.p-datatable-tfoot > tr > td {
display: none !important;
}
.p-datatable-tbody > tr {
border-bottom: 1px solid var(--layer-2);
> td {
text-align: left;
display: block;
border: 0 none !important;
width: 100% !important;
float: left;
clear: left;
border: 0 none;
.p-column-title {
padding: .4rem;
min-width: 30%;
display: inline-block;
margin: -.4rem 1rem -.4rem -.4rem;
font-weight: bold;
}
.p-progressbar {
margin-top: .5rem;
}
}
}
}
}
}
::v-deep(.p-paginator) {
.p-paginator-current {
margin-left: auto;