Data Table Rendering

Inkline's Data Table columns and rows can be rendered using custom render helpers.

Inkline provides four ways to render data table fields:

  • Data Path (default)
  • Render function
  • Custom component
  • Scoped slot

Data Path

By default, table data is rendered using the path property of each column. The path property is a string (i.e. address.country) that points to the data that will be rendered for each row.

export default {
    data() {
        return {
            columns: [
                { title: 'Name', path: 'name' },
                { title: 'Country', path: 'address.country' },
            ],
            rows: [
                { id: '1', name: 'Richard Hendricks', address: { city: 'Cupertino', country: 'United States' } },
                { id: '2', name: 'Bertram Gilfoyle', address: { city: 'Toronto', country: 'Canada' } },
                { id: '3', name: 'Dinesh Chugtai', address: { city: 'Lahore', country: 'Pakistan' } },
                { id: '4', name: 'Jared Dunn', address: { city: 'Berlin', country: 'Germany' } },
                { id: '5', name: 'Erlich Bachman', address: { city: 'Palo Alto', country: 'United States' } }
            ]
        }
    }
}
Data Table Path
Showentries
# Name Country
1 Richard Hendricks United States
2 Bertram Gilfoyle Canada
3 Dinesh Chugtai Pakistan
4 Jared Dunn Germany
5 Erlich Bachman United States
# Name Country

Styling

You can provide classes and inline styles for both columns and rows. Column specific styles and classes will be applied to all <td> table data cells that are under a specific column:

export default {
    data() {
        return {
            columns: [
                { title: 'Name', path: 'name', class: 'column-class' },
                { title: 'Country', path: 'address.country', style: { background: 'red' } },
            ],
            rows: [
                { id: '1', name: 'Richard Hendricks', address: { city: 'Cupertino', country: 'United States' } },
                { id: '2', name: 'Bertram Gilfoyle', address: { city: 'Toronto', country: 'Canada' } },
                { id: '3', name: 'Dinesh Chugtai', address: { city: 'Lahore', country: 'Pakistan' } },
                { id: '4', name: 'Jared Dunn', address: { city: 'Berlin', country: 'Germany' } },
                { id: '5', name: 'Erlich Bachman', address: { city: 'Palo Alto', country: 'United States' } }
            ]
        }
    }
}

Row styles and classes will be applied to the <tr> wrapper if specified using the row.config property.

You can also apply column specific classes and styles to a <td> table data cell of a row using row.config.columns[column.path]. A column path of * will apply to all child table data cells of the row.

export default {
    data() {
        return {
            columns: [
                { title: 'Name', path: 'name' },
                { title: 'Country', path: 'address.country' },
            ],
            rows: [
                { 
                    id: '1', 
                    name: 'Richard Hendricks', 
                    address: { city: 'Cupertino', country: 'United States' },
                    config: {
                        class: 'row-class'
                    }
                },
                { 
                    id: '2', 
                    name: 'Bertram Gilfoyle', 
                    address: { city: 'Toronto', country: 'Canada' },
                    config: {
                        style: { 'font-weight': 'bold' }
                    }
                },
                { 
                    id: '3', 
                    name: 'Dinesh Chugtai', 
                    address: { city: 'Lahore', country: 'Pakistan' },
                    config: {
                        columns: {
                            '*': { class: [ 'column-class-a', 'column-class-b' ] }
                        }   
                    }
                },
                { 
                    id: '4', 
                    name: 'Jared Dunn', 
                    address: { city: 'Berlin', country: 'Germany' },
                    config: {
                        columns: {
                            name: { class: [ 'name-column-class' ] }
                        }   
                    }
                },
                { 
                    id: '5', 
                    name: 'Erlich Bachman', 
                    address: { city: 'Palo Alto', country: 'United States' },
                    config: {
                        columns: {
                            name: { style: { background: 'red' } }
                        }   
                    } 
                }
            ]
        }
    }
}

Render Function

By adding a function in the render property of the column definition, you can easily provide a way to manipulate data or display it differently. This is the simplest option, the perfect choice when working with simple strings.

export default {
    data() {
        return {
            columns: [
                { title: 'Name', path: 'name' },
                { title: 'Address', path: 'address', render: (row) => `${row.address.city}, ${row.address.country}` },
            ],
            rows: [
                { id: '1', name: 'Richard Hendricks', address: { city: 'Cupertino', country: 'United States' } },
                { id: '2', name: 'Bertram Gilfoyle', address: { city: 'Toronto', country: 'Canada' } },
                { id: '3', name: 'Dinesh Chugtai', address: { city: 'Lahore', country: 'Pakistan' } },
                { id: '4', name: 'Jared Dunn', address: { city: 'Berlin', country: 'Germany' } },
                { id: '5', name: 'Erlich Bachman', address: { city: 'Palo Alto', country: 'United States' } }
            ]
        }
    }
}

Keep in mind that, by providing a custom render function, you will need to provide a custom sort function as well.

Data Table Render Function
Showentries
# Name Address
1 Richard Hendricks Cupertino, United States
2 Bertram Gilfoyle Toronto, Canada
3 Dinesh Chugtai Lahore, Pakistan
4 Jared Dunn Berlin, Germany
5 Erlich Bachman Palo Alto, United States
# Name Address

Custom Component

You can render a table field using a component by specifying a component field in the table columns definition.

The rendered component will have table data passed to it using the row, column and index props.

export default {
    name: 'MyCustomComponent',
    props: ['row', 'column', 'index'],
    template: '<div>{{row.data}}</div>'
};
import MyCustomComponent from '@components/MyCustomComponent';

export default {
    data() {
        return {
            columns: [
                { title: 'Data', path: 'data', component: MyCustomComponent },
            ],
            rows: [
                { id: '1', data: 100 },
                { id: '2', data: 55 },
                { id: '3', data: 70 }
            ]
        }
    }
}

Here's an example for how to display a progress bar component on each row:

Data Table Custom Component
Showentries
# Name Progress
1 Richard Hendricks
2 Bertram Gilfoyle
3 Dinesh Chugtai
4 Jared Dunn
5 Erlich Bachman
# Name Progress

The component field can either contain the component object (most common) or the component tag as a string (i.e. my-custom-component), if it has been globally registered.

Scoped Slot

By providing a scoped row slot, you can render rows as you see fit.

<i-datatable :columns="columns" :rows="rows">
    <template v-slot:row="{ row, index }">
        <td align="right">{{index + 1}}</td>
        <td>{{row.name}}</td>
        <td>{{row.address.city}}, {{row.address.country}}</td>
    </template>
</i-datatable>

Keep in mind that, by providing a custom render function, you will need to provide a custom sort function as well.

Data Table Scoped Slot
Showentries
# Name Address
1 Richard Hendricks Cupertino, United States
2 Bertram Gilfoyle Toronto, Canada
3 Dinesh Chugtai Lahore, Pakistan
4 Jared Dunn Berlin, Germany
5 Erlich Bachman Palo Alto, United States
# Name Address

Render Header Function

By adding a function in the renderHeader property of the column definition, you can easily manipulate table headers. This is the simplest option, the perfect choice when working with simple strings.

export default {
    data() {
        return {
            columns: [
                { title: 'Name', path: 'name' },
                { title: 'Address', path: 'address', renderHeader: (column) => column.title.toUpperCase() },
            ],
            rows: [ ... ]
        }
    }
}
Data Table Render Header Function
Showentries
# Name COUNTRY
1 Richard Hendricks United States
2 Bertram Gilfoyle Canada
3 Dinesh Chugtai Pakistan
4 Jared Dunn Germany
5 Erlich Bachman United States
# Name Country

Custom Header Component

You can render a table field using a component by specifying a headerComponent field in the table columns definition. This field will contain the component tag.

The rendered component will have table data passed to it using the row, column and index props.

export default {
    name: 'MyCustomComponent',
    props: ['column', 'index'],
    template: '<div>{{column.title}}</div>'
};
import MyCustomComponent from '@components/MyCustomComponent';

export default {
    data() {
        return {
            columns: [
                { title: 'Name', path: 'name' },
                { title: 'Progress', path: 'progress', headerComponent: MyCustomComponent },
            ],
            rows: [
                { id: '1', name: 'Richard Hendricks', progress: 82 },
                { id: '2', name: 'Bertram Gilfoyle', progress: 55 },
                { id: '3', name: 'Dinesh Chugtai', progress: 70 },
                { id: '4', name: 'Jared Dunn', progress: 36 },
                { id: '5', name: 'Erlich Bachman', progress: 95 }
            ]
        }
    }
}

Here's a practical example where the header component contains a dropdown:

Data Table Custom Header Component
Showentries
# Name
1 Richard Hendricks United States
2 Bertram Gilfoyle Canada
3 Dinesh Chugtai Pakistan
4 Jared Dunn Germany
5 Erlich Bachman United States
# Name Country

The headerComponent field can either contain the component object (most common) or the component tag as a string (i.e. my-custom-component), if it has been globally registered.

Scoped Header Slot

By providing a scoped header slot, you can render the datatable header as you see fit.

<i-datatable :columns="columns" :rows="rows">
    <template v-slot:header="{ sortBy }">
        <td class="_text-right">No.</td>
        <td>Name</td>
        <td>Country</td>
    </template>
</i-datatable>

Keep in mind that, by providing a custom render function, you will need to provide a custom sort function as well.

Data Table Scoped Header Slot
Showentries
No. Name Country
1 Richard Hendricks United States
2 Bertram Gilfoyle Canada
3 Dinesh Chugtai Pakistan
4 Jared Dunn Germany
5 Erlich Bachman United States
# Name Country

Header Wrapper Slot

By providing a scoped header-wrapper slot, you can render the datatable search, entries selector and pagination as you see fit.

<i-datatable :columns="columns" :rows="rows">
    <template v-slot:header-wrapper="{ rowsFrom, rowsTo, rowsCount, page, rowsPerPage, filter, onPageChange, onRowsPerPageChange, onFilterChange }">
        <i-input @input="onFilterChange" placeholder="Search.." />
        <div>
            <i-button :active="rowsPerPage === 10" @click="onRowsPerPageChange(10)">10</i-button>
            <i-button :active="rowsPerPage === 25" @click="onRowsPerPageChange(25)">25</i-button>
            <i-button :active="rowsPerPage === 50" @click="onRowsPerPageChange(50)">50</i-button>
        </div>
    </template>
</i-datatable>
Data Table Header Wrapper Slot
# Name Country
1 Bertram Gilfoyle Canada
2 Richard Hendricks United States
3 Dinesh Chugtai Pakistan
4 Jared Dunn Germany
5 Erlich Bachman United States
6 Nelson Bighetti United States
7 Richard Hendricks United States
8 Bertram Gilfoyle Canada
9 Dinesh Chugtai Pakistan
10 Jared Dunn Germany
# Name Country

By adding a function in the renderFooter property of the column definition, you can easily manipulate table footers. This is the simplest option, the perfect choice when working with simple strings.

export default {
    data() {
        return {
            columns: [
                { title: 'Name', path: 'name' },
                { title: 'Address', path: 'address', renderFooter: (column) => column.title.toUpperCase() },
            ],
            rows: [ ... ]
        }
    }
}
Data Table Render Header Function
Showentries
# Name Country
1 Richard Hendricks United States
2 Bertram Gilfoyle Canada
3 Dinesh Chugtai Pakistan
4 Jared Dunn Germany
5 Erlich Bachman United States
# Name COUNTRY

You can render a table field using a component by specifying a footerComponent field in the table columns definition. This field will contain the component tag.

The rendered component will have table data passed to it using the row, column and index props.

export default {
    name: 'MyCustomComponent',
    props: ['column', 'index'],
    template: '<div>{{column.title}}</div>'
};
import MyCustomComponent from '@components/MyCustomComponent';

export default {
    data() {
        return {
            columns: [
                { title: 'Name', path: 'name' },
                { title: 'Progress', path: 'progress', footerComponent: MyCustomComponent },
            ],
            rows: [
                { id: '1', name: 'Richard Hendricks', progress: 82 },
                { id: '2', name: 'Bertram Gilfoyle', progress: 55 },
                { id: '3', name: 'Dinesh Chugtai', progress: 70 },
                { id: '4', name: 'Jared Dunn', progress: 36 },
                { id: '5', name: 'Erlich Bachman', progress: 95 }
            ]
        }
    }
}

Here's a practical example where the header component contains a dropdown:

Data Table Custom Footer Component
Showentries
# Name Country
1 Richard Hendricks United States
2 Bertram Gilfoyle Canada
3 Dinesh Chugtai Pakistan
4 Jared Dunn Germany
5 Erlich Bachman United States
# Name

The footerComponent field can either contain the component object (most common) or the component tag as a string (i.e. my-custom-component), if it has been globally registered.

By providing a scoped footer slot, you can render the datatable footer as you see fit.

<i-datatable :columns="columns" :rows="rows">
    <template slot="footer">
        <td class="_text-right">No.</td>
        <td>Name</td>
        <td>Country</td>
    </template>
</i-datatable>

Keep in mind that, by providing a custom render function, you will need to provide a custom sort function as well.

Data Table Scoped Footer Slot
Showentries
# Name Country
1 Richard Hendricks United States
2 Bertram Gilfoyle Canada
3 Dinesh Chugtai Pakistan
4 Jared Dunn Germany
5 Erlich Bachman United States
No. Name Country

By providing a scoped footer-wrapper slot, you can render the datatable search, entries selector and pagination as you see fit.

<i-datatable :columns="columns" :rows="rows">
    <template v-slot:footer-wrapper="{ rowsFrom, rowsTo, rowsCount, page, rowsPerPage, filter, onPageChange, onRowsPerPageChange, onFilterChange }">
        <i-input @input="onFilterChange" placeholder="Search.." />
        <div>
            <i-button :active="rowsPerPage === 10" @click="onRowsPerPageChange(10)">10</i-button>
            <i-button :active="rowsPerPage === 25" @click="onRowsPerPageChange(25)">25</i-button>
            <i-button :active="rowsPerPage === 50" @click="onRowsPerPageChange(50)">50</i-button>
        </div>
    </template>
</i-datatable>
Data Table Footer Wrapper Slot
Showentries
# Name Country
1 Bertram Gilfoyle Canada
2 Richard Hendricks United States
3 Dinesh Chugtai Pakistan
4 Jared Dunn Germany
5 Erlich Bachman United States
6 Nelson Bighetti United States
7 Richard Hendricks United States
8 Bertram Gilfoyle Canada
9 Dinesh Chugtai Pakistan
10 Jared Dunn Germany
# Name Country