import DataView from 'primevue/dataview';
<script src="https://unpkg.com/primevue@^3/core/core.min.js"></script>
<script src="https://unpkg.com/primevue@^3/dataview/dataview.min.js"></script>
DataView utilizes PrimeFlex library so it needs to be installed before getting started. Refer to PrimeFlex documentation for details.
DataView requires a collection of items as its value and one or more templates depending on the layout mode e.g. list and grid. Throughout the samples, a car interface having vin, brand, year and color properties are used to define an object to be displayed by the dataview. Cars are loaded by a CarService that connects to a server to fetch the cars.
export default {
data() {
return {
cars: null,
}
},
carService: null,
created() {
this.carService = new CarService();
},
mounted() {
this.carService.getCarsLarge().then(data => this.cars = data);
}
}
DataView has two layout modes; list and grid where a separate template is used to render an item in each mode. In list mode name of the template is "list" whereas in grid mode it is "grid".
Note that there is no restriction to use both layouts at the same time, you may configure only one layout using the layout property with the corresponding template.
<template #list="slotProps">
<div class="col-12">
<div class="car-details">
<div>
<img :src="'images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/>
<div class="grid">
<div class="col-12">Vin: <b>{{slotProps.data.vin}}</b></div>
<div class="col-12">Year: <b>{{slotProps.data.year}}</b></div>
<div class="col-12">Brand: <b>{{slotProps.data.brand}}</b></div>
<div class="col-12">Color: <b>{{slotProps.data.color}}</b></div>
</div>
</div>
<Button icon="pi pi-search"></Button>
</div>
</div>
</template>
<template #grid="slotProps">
<div style="padding: .5em" class="col-12 md:col-3">
<Panel :header="slotProps.data.vin" style="text-align: center">
<img :src="'images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/>
<div class="car-detail">{{slotProps.data.year}} - {{slotProps.data.color}}</div>
<Button icon="pi pi-search"></Button>
</Panel>
</div>
</template>
Header and Footer are the two templates that are capable of displaying custom content.
<template #header>Header Content</template>
<template #footer>Footer Content</template>
Where there is no data to display, the optional empty template can be used to display information.
<template #empty>No records found.</template>
When both layout modes are enabled in DataView, a UI element would be necessary to let the user toggle between the view. DataViewLayoutOptions is a helper component to display a buttonset to choose the layout mode in DataView. Location of the DataViewLayoutOptions should be inside the DataView component. If you prefer a different UI element you can create your own that updates the layout property of the DataView.
<DataView :value="cars" :layout="layout">
<template #header>
<DataViewLayoutOptions v-model="layout"></DataViewLayoutOptions>
</template>
<template #list="slotProps" >
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
<template #grid="slotProps">
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
</DataView>
Pagination is enabled by setting paginator property to true, rows attribute defines the number of rows per page and pageLinks specify the the number of page links to display. To customize the left and right side of the paginators, use paginatorstart and paginatorend templates.
<DataView :value="cars" :layout="layout" paginatorPosition="both" :paginator="true" :rows="20">
<template #paginatorstart>
<Button type="button" icon="pi pi-refresh"/>
</template>
<template #paginatorend>
<Button type="button" icon="pi pi-search" />
</template>
<template #list="slotProps" >
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
<template #grid="slotProps">
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
</DataView>
sortField and sortOrder properties are available for the sorting functionality, for flexibility there is no built-in UI available so that a custom UI can be used for the sorting element. Here is an example that uses a dropdown where simply updating the sortField-sortOrder bindings of the DataView initiates sorting.
<DataView :value="cars" :layout="layout" :sortOrder="sortOrder" :sortField="sortField">
<template #header>
<div class="grid grid-nogutter">
<div class="col-6" style="text-align: left">
<Dropdown v-model="sortKey" :options="sortOptions" optionLabel="label" placeholder="Sort By" @change="onSortChange($event)"/>
</div>
<div class="col-6" style="text-align: right">
<DataViewLayoutOptions v-model="layout" />
</div>
</div>
</template>
<template #list="slotProps" >
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
<template #grid="slotProps">
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
</DataView>
export default {
data() {
return {
cars: null,
layout: 'list',
sortKey: null,
sortOrder: null,
sortField: null,
sortOptions: [
{label: 'Newest First', value: '!year'},
{label: 'Oldest First', value: 'year'},
{label: 'Brand', value: 'brand'}
]
}
},
carService: null,
created() {
this.carService = new CarService();
},
mounted() {
this.carService.getCarsLarge().then(data => this.cars = data);
},
methods: {
onSortChange(event){
const value = event.value.value;
const sortValue = event.value;
if (value.indexOf('!') === 0) {
this.sortOrder = -1;
this.sortField = value.substring(1, value.length);
this.sortKey = sortValue;
}
else {
this.sortOrder = 1;
this.sortField = value;
this.sortKey = sortValue;
}
}
}
}
Lazy loading is useful to deal with huge datasets, in order to implement lazy loading use the pagination and utilize the page callback to load your data from the backend. Pagination in this case needs to display the logical number of records bound to the totalRecords property so that paginator can display itself according to the total records although you'd only need to load the data of the current page.
<DataView :value="cars" :layout="layout" :paginator="true" :rows="20" :lazy="true" @page="onPage($event)">
<template #list="slotProps" >
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
<template #grid="slotProps">
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
</DataView>
export default {
data() {
return {
cars: null,
layout: 'list'
}
},
carService: null,
mounted() {
this.cars = //initialize the first chunk of data between 0 and 20
},
methods: {
onPage(event){
this.cars = //load the data between (event.first) and (event.first + event.rows) from a remote datasource
}
}
}
Name | Type | Default | Description |
---|---|---|---|
value | array | null | An array of objects to display. |
layout | string | list | Layout of the items, valid values are "list" and "grid". |
rows | number | 0 | Number of rows to display per page. |
first | number | 0 | Index of the first record to render. |
totalRecords | number | null | Number of total records, defaults to length of value when not defined. |
paginator | boolean | false | When specified as true, enables the pagination. |
paginatorPosition | string | bottom | Position of the paginator, options are "top","bottom" or "both". |
alwaysShowPaginator | boolean | true | Whether to show it even there is only one page. |
paginatorTemplate | string | FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown | Template of the paginator. See the |
pageLinkSize | number | 5 | Number of page links to display. |
rowsPerPageOptions | array | null | Array of integer values to display inside rows per page dropdown. |
currentPageReportTemplate | string | ({currentPage} of {totalPages}) | Template of the current page report element. |
sortField | string | null | Property name or a getter function of data to use in sorting by default. |
sortOrder | number | null | Order to sort the data by default. |
lazy | boolean | false | Defines if data is loaded and interacted with in lazy manner. |
dataKey | string | null | Name of the data that uniquely identifies the a record in the data. |
Name | Parameters | Description |
---|---|---|
page |
event.page: New page number event.first: Index of first record event.rows: Number of rows to display in new page event.pageCount: Total number of pages |
Callback to invoke when page changes, the event object contains information about the new state. |
Name | Parameters |
---|---|
header | - |
paginatorstart | - |
paginatorend | - |
list |
data: Value of the component index: Index of the list |
grid |
data: Value of the component index: Index of the grid |
empty | - |
footer | - |
Following is the list of structural style classes, for theming classes visit
Name | Element |
---|---|
p-dataview | Container element. |
p-dataview-list | Container element in list layout. |
p-dataview-grid | Container element in grid layout. |
p-dataview-header | Header section. |
p-dataview-footer | Footer section. |
p-dataview-content | Container of items. |
p-dataview-emptymessage | Empty message element. |
The container element that wraps the layout options buttons has a group role whereas each button element uses button role and aria-pressed is updated depending on selection state. Values to describe the buttons are
derived from the aria.listView and aria.gridView properties of the
Refer to
Key | Function |
---|---|
tab | Moves focus to the buttons. |
space | Toggles the checked state of a button. |
PrimeFlex