Skip to content

Using `vuetable` with Twitter's Bootstrap

Rati Wannapanop edited this page May 14, 2016 · 3 revisions

Using vuetable with Twitter's Bootstrap

You can checkout the more updated version of this example at https://github.com/ratiw/vuetable-example-vueify-bootstrap. With the updated version, VuetablePagination is already working with Bootstrap. You just need to specified the appropriate styling via paginationConfig callback.

Just right-click and select View Source form within your browser.


If you look at the source code, you'll see that vuetable uses normal table and div tags primarily. And all css styles can be overridden via properties.

So, all you need to do is to provide Bootstrap's css like so.

	<body>
		<vuetable
			api-url="http://example.app:8000/api/users"
			:fields="fields"
			:sort-order="sortOrder"
			table-class="table table-bordered table-striped table-hover"
			ascending-icon="glyphicon glyphicon-chevron-up"
			descending-icon="glyphicon glyphicon-chevron-down"
			pagination-class=""
			pagination-info-class=""
			pagination-component-class=""
			pagination-component="vuetable-pagination-bootstrap"
			:item-actions="itemActions"
		></vuetable>

        <template id="vuetable-pagination-bootstrap-template">
            <nav>
                <ul class="pagination">
                    <li class="{{isOnFirstPage ? disabledClass : ''}}">
                        <a @click="loadPage('prev')"><i class="glyphicon glyphicon-chevron-left"></i></a>
                    </li>
                    <template v-for="n in totalPage">
                        <li class="{{isCurrentPage(n+1) ? ' active' : ''}}">
                            <a @click="loadPage(n+1)"> {{ n+1 }}</a>
                        </li>
                    </template>
                    <li class="{{isOnLastPage ? disabledClass : ''}}">
                        <a @click="loadPage('next')"><i class="glyphicon glyphicon-chevron-right"></i></a>
                    </li>
                </ul>
            </nav>
        </template>
    </body>

In this example, we also create a new pagination component vuetable-pagination-bootstrap to display the pagination in Bootstrap's style using nav and tells vuetable to use this new pagination component, instead of the default one.

main.js

	// fields definition
    var tableColumns = [
        'name',
        'email',
        {
            name: 'nickname',
            callback: 'allCap'
        },
        {
            name: 'birthdate',
            callback: 'formatDate|D/MM/Y'
        },
        {
            name: 'gender',
            sortField: 'gender',
            titleClass: 'center aligned',
            dataClass: 'center aligned',
            callback: 'gender'
        },
        {
            name: '__actions',
            dataClass: 'center aligned',
            callback: null
        }
    ]

	// create pagination component using bootstrap styling
    Vue.component('vuetable-pagination-bootstrap', {
        template: '#vuetable-pagination-bootstrap-template',
        mixins: [paginationMixin],
        methods: {
            loadPage: function(page) {
                this.$dispatch('vuetable-pagination:change-page', page)
            },
        },
    })

    new Vue({
        el: '#app',
        data: {
            fields: tableColumns,
            paginationInfoTemplate: 'แสดง {from} ถึง {to} จากทั้งหมด {total} รายการ',
            itemActions: [
                { name: 'view-item', label: '', icon: 'glyphicon glyphicon-zoom-in', class: 'btn btn-info' },
                { name: 'edit-item', label: '', icon: 'glyphicon glyphicon-pencil', class: 'btn btn-warning'},
                { name: 'delete-item', label: '', icon: 'glyphicon glyphicon-remove', class: 'btn btn-danger' }
            ]
        },
        methods: {
            /**
             * Callback functions
             */
            allCap: function(value) {
                return value.toUpperCase()
            },
            gender: function(value) {
              return value == 'M'
                ? '<span class="label label-info"><i class="glyphicon glyphicon-star"></i> Male</span>'
                : '<span class="label label-success"><i class="glyphicon glyphicon-heart"></i> Female</span>'
            },
            formatDate: function(value, fmt) {
                if (value == null) return ''
                fmt = (typeof fmt == 'undefined') ? 'D MMM YYYY' : fmt
                return moment(value, 'YYYY-MM-DD').format(fmt)
            },
            /**
             * Other functions
             */
            viewProfile: function(id) {
                window.location.href = '/staffs/profile/'+id
            }
        },
        events: {
            'vuetable:action': function(action, data) {
                console.log('vuetable:action', action, data)
            },
            'vuetable:load-error': function(response) {
            	console.log('load-error: ', response)
            }
        }
    })

main.css

	<style>
        .vuetable th.sortable:hover {
            color: #2185d0;
            cursor: pointer;
        }
        .vuetable-actions {
            width: 11%;
            padding: 12px 0px;
            text-align: center;
        }
        .vuetable-actions > button {
          padding: 3px 6px;
          margin-right: 4px;
        }
        .vuetable-pagination {
        }
        .vuetable-pagination-info {
            float: left;
            margin-top: auto;
            margin-bottom: auto;
        }
        ul.pagination {
          margin: 0px;
        }
        .vuetable-pagination-component {
          float: right;
        }
    </style>

image