Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ratiw's avatar
Level 25

vuetable - data table simplify!

I have been working on Vue.js table component for my own work for quite sometime. And I think it's good enough to share and hoping it might be helpful to the others.

Please check it out at https://github.com/ratiw/vue-table Any comment and suggestions are very welcome.

http://s20.postimg.org/lf470bkd7/vuetable_short.gif

  • No need to render the table yourself
  • One simple vuetable tag
  • Display data retrieved from server with sort options
  • Pagination component included, swap-able and extensible
  • Define fields to map your JSON data structure
  • Define row actions and capture the click event to do whatever you want
  • Field display customizable via callback function inside Vue.js instance
  • Programmatically show/hide any field via reactivity of fields definition
  • Use your favorite CSS framework classes to nicely format your table and dispalyed data
  • Events to allow control from Vue.js instance programmatically
  • Capture events from vuetable to manipulate your table and your data
  • Should work with any pre-defined JSON data structure
  • Should work with any CSS Framework, e.g. Semantic UI, Twitter's Bootstrap
0 likes
54 replies
ZetecVan's avatar

@ratiw I've been giving it a go, and got it up and running very quickly.

However I have one suggestion. I can't change the column headings (or it's not clear how to do it). I have a field called 'goals_for'. It renders the column heading as 'Goals_for'. I would like to change that to 'For' or 'Goals For'.

Other than that, good work.

ratiw's avatar
Level 25

I think I may have missed it in the documentation. In order to change the title, you just have to specify the title option in your field definition, like so:

    {
        name: 'goals_for',
        title: 'Goals For'
    }

Thanks for reporting back. :)

1 like
ZetecVan's avatar

Excellent. Thank you. I'll continue using it for my project, and let you know if I come across anything else.

devchops's avatar

Thank you for sharing - Ive not tried it out yet, but this does look very promising for something im working on currently. Thanks ratiw!

ratiw's avatar
Level 25

@devchops You're welcome. This is nothing compare to what've learned from the community. :) I would love for any suggestion on the documentation as well. I've tried my best but English is not my primary language and I'm just afraid it would not be clear enough.

ZetecVan's avatar

@ratiw One thing I would like, which, looking at the code, is probably just a few lines of code change, is to have the whole dataset that is returned from the GET put into a field.

Lets say the data returned from one of my GETs is in the format

{
    "links": {
        "pagination": {
            "total": 50,
            "per_page": 15,
            "current_page": 1,
            "last_page": 4,
            "from": 1,
            "to": 15,
        }
    },
    "data" : {
    "Title" : "Some title",
     "Descr" : "Some description",
    "subdata": [
        {
            "id": 1,
            "name": "xxxxxxxxx",
            "nickname": "xxxxxxx",
            "email": "xxx@xxx.xxx",
            "birthdate": "xxxx-xx-xx",
            "gender": "X",
            "group_id": 1,
    
        },

        {
            "id": 50,
            "name": "xxxxxxxxx",
            "nickname": "xxxxxxx",
            "email": "xxx@xxx.xxx",
            "birthdate": "xxxx-xx-xx",
            "gender": "X",
            "group_id": 3,
        }
}
    ]
}

where the repeating element is within the main data. My datapath is data-path="data.subdata", but I would also like to be able to display the title and description on the page. If it could return the whole dataset in a field, that would be great. eg:

this.$http.get(url)
                .then(function(response) {
                    this.dataset = this.getObjectValue(response.data, null, null)
                    this.tableData = this.getObjectValue(response.data, this.dataPath, null)
                    this.tablePagination = this.getObjectValue(response.data, this.paginationPath)
ratiw's avatar
Level 25

@ZetecVan Actually, you could tap into vuetable:load-success event and use the pass-in response argument to do just that. The whole dataset will be in the response.data. Then, you can use it from main Vue.js instance to set your UI title and description. Or, you could fork the project and make changes as you see fit. :)

new Vue({
    data: {
        dataset: null,
    },
    events: {
        'vuetable:load-success': function(response) {
            this.dataset = response.data
            this.title = this.dataset.data.Title
            this.description = this.dataset.data.Descr
        }
    }
})
1 like
ZetecVan's avatar

Excellent, thanks again for the quick reply. I'm still learning Vue, so thanks for that information. As it's a simple solution with no code changes, no need to fork your project ;-)

davestewart's avatar

Looks great!

Have you thought about moving the contents of the readme into a GitHub wiki?

It's really nice as you can break out sections into pages.

1 like
jimmck's avatar

@ratiw Hi. Does your component have any dependency on Laravel? Can you setup the component to have no style dependancies, i.e. no external CDN's etc? And (Being lazy have only briefly read the Git repo) can you build the JS manually with preferred VueJS? Finally, turn off of the Vue Resource dependancies and supply data via an interface of method implementations?

Thanks!

ratiw's avatar
Level 25

@jimmck It doesn't have any dependency on Laravel. The backend can be anything as long as it sends out JSON formatted data.

It does, however as it is being Vue.js component, require vue and vue-resource. For styling, as I mention in the document that I personally prefer Semantic UI. So, the default styling are all based on that, but you can easily override them via vuetable's props. Please look at the examples section where you'll find an example using vuetable with Twitter's Bootstrap.

Theoretically, you can use any AJAX library to fetch the data from the server (e.g. jquery.getJson()) instead of using vue-resource. But I really like Vue.js eco-system, so I'm gonna stick with it. But you can fork the repo and try things that you like. :)

jimmck's avatar

@ratiw Hi and thanks for the quick response! Already got the repo. I have to read lots. Not a big fan of components with data source specifics, but its designers choice! Are there JSON specifications or just read the code?

Thanks Again!

ratiw's avatar
Level 25

@jimmck No JSON specifications. You can tell vuetable where to look for the actual data inside that returned JSON structure using data-path property. You can also specify the pagination-path inside the JSON strucuture as well.

Please see Data Format (JSON) section first, it should answer your question. But if you're still unclear, just let me know. :)

jimmck's avatar

@ratiw Thanks! Need to read more at this point to ask specific questions.

ratiw's avatar
Level 25

I've added more features to the vuetable component and updated the examples to demonstrate it. Please open the javascript console output to see the logs from the examples as well.

  • No need to render the table yourself
  • One simple vuetable tag
  • Display data retrieved from server with sort options
  • Pagination component included, swap-able and extensible
  • Define fields to map your JSON data structure
  • Define row actions and capture the click event to do whatever you want
  • Field display customizable via callback function inside Vue.js instance
  • Programmatically show/hide any field via reactivity of fields definition
  • Use your favorite CSS framework classes to nicely format your table and dispalyed data
  • Events to allow control from Vue.js instance programmatically
  • Capture events from vuetable to manipulate your table and your data
  • Should work with any pre-defined JSON data structure
  • Should work with any CSS Framework, e.g. Semantic UI, Twitter's Bootstrap
EmilMoe's avatar

I was gonna make this myself but now I will give yours a go first. Thanks :-)

davestewart's avatar

Started the Vue lessons this weekend (and how does @JeffreyWay build everything so bloody quickly!?) and I'm sure this will come in super useful, both from the point of view of a great component, and something to pick apart to see how things should be done.

Thanks!

ratiw's avatar
Level 25

Vue.js is really amazing!!

I've started from normal table rendering and got it working quite ok. Then, things turned really tedious and fun at the same time when I started converting it into workable component.

Researching what I wanted to do and finding the solution to do it with Vue could really be some chapters in a book. I still don't know everything about Vue, but I've learned a lot building this component. :)

1 like
jimmck's avatar

@ratiw Why can't you scroll the list? The table refreshes the whole screen when you change pages? Are you dynamically updating the DOM?

EmilMoe's avatar

I think it's because it only loads a chunk of the data instead of having all data stored in the cache, therefor it needs to make a server request every time.

ratiw's avatar
Level 25

@jimmck I want it to be simple and never expect it to grow to something like DataTables. And I don't see myself needing to use the "endless scroll" feature. The whole table refreshes because a new small data chuck is requested when you interact with the pagination control. This is the reactive nature of Vue.

1 like
EmilMoe's avatar

I suggest, @jimmck, that you extend the VueTable to something like VueTableScrollabe and add that functionality. Then it's an inheritance of the @ratiw code.

EmilMoe's avatar

When I try to import your product I get a Vue is not found. I'm using Browserify, maybe your script don't support this?

ratiw's avatar
Level 25

@EmilMoe Right now it is only possible to include it directly in your html page. I'm currently working on the Vueify version that could be import using require(..), but I'm quite new to Browserify and Webpack and I'm not sure whether I will get the right the first time. Splitting the library into smaller .vue file is easy enough, but the workflow of both Browserify and Webpack is really messing with my head! Will post the update in this thread anyway. :)

EmilMoe's avatar

Hope it will work for you soon :-)

Btw.. I don't use require(), I use import, because then I can import it in those components that use it.

Next

Please or to participate in this conversation.