Melcus's avatar

Vue.JS Vue-Tables Laravel Relationship

I am using https://github.com/matfish2/vue-tables with Laravel. This is the vue code

   Vue.use(VueTables.client, {
    compileTemplates: true,
    highlightMatches: true,
   pagination: {
    dropdown:true,
     chunk:5
    },
    filterByColumn: true,
    texts: {
        filter: "Search:"
    },
    datepickerOptions: {
        showDropdowns: true
    }
});
new Vue({
    el: "#people",
    methods: {
        deleteMe: function(id) {
            alert("Delete " + id);
        }
    },
    data: {
        options: {
            columns: ['created_at', 'name', 'profession', 'footage_date', 'type', 'link', 'note'],
            dateColumns: ['footage_date'],
            headings: {
                created_at: 'Added',
                name: 'Name',
                profession: 'Profesion',
                footage_date: 'Footage Date',
                type: 'Type',
                link: 'Link',
                note: 'Note',
                edit: 'Edit',
                delete: 'Delete'
            },
            templates: {

                edit: "<a href='#!/{id}/edit'><i class='glyphicon glyphicon-edit'></i></a>",
                delete: "<a href='' @click='$parent.deleteMe({id})'><i class='glyphicon glyphicon-erase'></i></a>"
            },
        },
        tableData: [{ InsertDataHere }],
    }
    }); 

How do I get the data from DB for tableData ? Vue-resources? I have a route /api/footage that gives me the following

[
{
"id": 2,
"user_id": 11,
"profession": "profession",
"type": "GvG",
"footage_date": {
"date": "2016-04-01 00:00:00.000000",
"timezone_type": 2,
"timezone": "GMT"
},
"link": "some link",
"note": "description",
"created_at": "1 hour ago",
"updated_at": "2016-04-03 23:06:32"
}
] 

Now, User and Footage have a one to many relationship. How would I go about showing the user for each entry as well? ( also the ID for edit and delete )

This is the blade code

 <div id="people" class="container">
   <v-client-table :data="tableData" :options="options"></v-client-table>
 </div> 

Thank you in advance.

0 likes
10 replies
xdimension's avatar

Maybe you need to return the data from server side in a flat format instead of nested. Then (from the doc) you can use:

<v-server-table url="/api/footage" :options="options"></v-server-table>
1 like
Melcus's avatar

@xdimension Can you please elaborate a bit? I'm not really a vue master or anything :( Also, how could I access the User - Footage relationship?

Edit: I've simplified it a bit. When I create the record, I pass the name directly, so no need to call the relationship anymore.

Melcus's avatar
Melcus
OP
Best Answer
Level 6

This got my result:

created: function(){
    this.$http.get('/api/footage')
        .then(function(response){
            this.tableData = response.data
        }.bind(this))
},
1 like
xdimension's avatar

Sorry, I couldn't get back to you earlier. Glad to see it's resolved.

Maybe just an additional information: If you're using <v-client-table ...>, then yes, you need to retrieve the data from the server using vue-resource (this.$http.get(...)) as you did. But from the doc, I see another option to do it, you can use <v-server-table url="/api/footage" ...>, it requires you to return a JSON from the server-side in this format:

{ 
      data: [
           // row objects of your data and each row should be flattened (not nested)
           {id: 1, name: "John", ... },
           {id: 2, name: "Doe", ... },
           ...
      ],

     count: 5
}

I think internally it would do the same as what you did using <v-client-table> and vue-resource.

Melcus's avatar

@xdimension Thank you for the hint. However, I have another problem with this table now, with the datepicker. Even if the date is in range, it shows as no result. When you hardcore the date column, it works, when I extract it from db, it doesn't. I inspected with vue devtools and I could see that this function ( in the example)

   // Courtesy of Tomasz Nurkiewicz (http://stackoverflow.com/questions/9035627/elegant-method-to-generate-array-of-random-dates-within-two-dates)
function randomDate(start, end) {
 return moment(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
}

gives the following format footage_date: "1974-03-27T18:19:40.364Z" and with $http.get I get footage_date: "01-04-2016 00:00:00"

I used a mutator on footage_date, as it is a normal date field in db

public function getFootageDateAttribute($date)
{

    return Carbon::parse($date)->format('d-m-Y H:i:s' );
}

Any ideas on this?

xdimension's avatar

@Melcus $http.get just retrieves the data from the JSON. As you're using accessor then you can check what it returns to your JSON and changes how you format the date.

rudiwer's avatar

Hello,

Anybody who knows how to sort a numeric id field in a column in numeric sort order ???

matfish2's avatar

@Melcus, dates - which are complex data types - must be passed as moment objects. When you return them from the server they are strings. You need to iterate over the data and turn those plain strings into sortable and filterable moment objects. Alternatively, the plugin offers a toMomentFormat option. You can pass it the format you get back from the server (according to moment's conventions, of course), and it will do the conversion for you.

toMomentFormat docs:

transform date columns string values to moment objects using this format. If this option is not used the consumer is expected to pass moment objects himself

Melcus's avatar

@matfish2 Hello. Thank you for taking your time. If you remember, about 2 months ago I asked you about moment objects on github. Your response solved the problem :) Thanks again

1 like

Please or to participate in this conversation.