ratiw / vue-table

data table simplify! -- vuetable is a Vue.js component that will automatically request (JSON) data from the server and display them nicely in html table with swappable/extensible pagination component.
MIT License
1.83k stars 302 forks source link

Accessing nested object data from laravel blade #44

Open securit opened 8 years ago

securit commented 8 years ago

Looking at the latest bootstrap example you have added detail rows. What is the correct way to access nested objects. Whenever I try to do so, I get a response

Properties:
{{ old_list.$key }} - {{ old_list.$value }}
{{ new_list.$key }} - {{ new_list.$value }} 

which is basically returning the text of my javascript, not the list of attributes in that object.

In my definition I have a template:

<vuetable v-ref:vuetable
                  api-url="/log"
                  data-path="data"
                  pagination-path=""
                  searchFor="searchFor"
                  :fields="tableColumns" ,
                  :sort-order="sortOrder"
                  :multi-sort="multiSort"
                  table-class="table table-striped table-hover table-condensed table-font"
                  ascending-icon="glyphicon glyphicon-chevron-up"
                  descending-icon="glyphicon glyphicon-chevron-down"
                  :append-params="moreParams" pagination-class=""
                  pagination-info-class=""
                  pagination-component-class=""
                  pagination-info-no-data-template="The requested query return no result"
                  :per-page="perPage"
                  :append-params="moreParams"
                  wrapper-class="vuetable-wrapper "
                  table-wrapper=".vuetable-wrapper"
                  loading-class="loading"
                  detail-row="makeDetailRow"
                  detail-row-id="id"
                  detail-row-transition="expand"
                  row-class-callback="rowClassCB"
        >
</vuetable>

and a script

export default {
        props: {},

        data() {
            return {
                searchFor: '',
                sortOrder: [{
                    field: 'id',
                    direction: 'desc'
                }],
                moreParams: [],
                multiSort: true,
                perPage: 30,
                paginationComponent: 'vuetable-pagination',
                paginationInfoTemplate: 'Displaying {from} to {to} of {total} items',
                tableColumns: [
                    {
                        name: 'properties',
                        title: '',
                        titleClass: 'center aligned',
                        dataClass: 'center aligned',
                        callback: 'showDetailRow'
                    },
                    {
                        name: 'id',
                        title: 'ID',
                        sortField: 'id',
                        titleClass: 'center aligned',
                        dataClass: 'center aligned'
                    },
                    {
                        name: 'log_name',
                        title: 'Log',
                        sortField: 'log',
                        titleClass: 'left aligned',
                        dataClass: 'left aligned'
                    },
                    {
                        name: 'description',
                        title: 'Description',
                        sortField: 'description',
                        titleClass: 'left aligned',
                        dataClass: 'left aligned'
                    },
                    {
                        name: 'subject_id',
                        title: 'Subject ID',
                        titleClass: 'center aligned',
                        dataClass: 'center aligned'
                    },
                    {
                        name: 'subject_type',
                        title: 'Subject Type',
                        titleClass: 'left aligned',
                        dataClass: 'left aligned'
                    },
                ]
            }
        },

        watch: {
            'perPage': function (val, oldVal) {
                this.$broadcast('vuetable:refresh')
            }
        },

        methods: {
            /**
             * Callback functions
             */
            showDetailRow: function (value) {
                var icon = this.$refs.vuetable.isVisibleDetailRow(value) ? 'glyphicon glyphicon-minus-sign' : 'glyphicon glyphicon-plus-sign'

                return [
                    '<a class="show-detail-row">',
                    '<i class="' + icon + '"></i>',
                    '</a>'
                ].join('')

            },
           makeDetailRow: function (data) {
                return [
                    '<td colspan="7">',
                    '<div class="detail-row">',
                    '<div class="form-group">',
                    '<label>Properties: </label>',
                    '<ul><li v-for="new_list in data.properties.new_attributes">{{ new_list.$key }} - {{ new_list.$value }}</li></ul>',
                    '<ul><li v-for="old_list in data.properties.old_attributes">{{ old_list.$key }} - {{ old_list.$value }}</li></ul>',
                    '</div>',
                    '</div>',
                    '</td>'
                ].join('')

Sorry, a real Noob with Vue.JS, just learning and not sure where to go to next..

ratiw commented 8 years ago

@securit The detail row is another table row directly underneath the current data row. It is supposed to be used to display additional information pertain to the given data row which may not have enough space or irrelevant to show on normal row, e.g. the contact info of a customer, etc.

The detail row callback makeDetailRow can only contain valid constructed html. The callback cannot processes any Vue related code, so it will just display what you return back to it. So, v-for will in your code will never work and gets ignore since it is not a known html attributes.

I'm not sure how you picture your log table output, so I can't really suggest anything. Sorry.

securit commented 8 years ago

Modifying makeDetailRow a little works a bit better, however it strips the <table> tag and doesnt take up the full width of the parent table

makeDetailRow: function (data) {
                var returnStr = '<div class="detail-row"><div class="form-group"><label>Properties: </label><table><tr>';

                for (var key in data.properties) {
                    if (data.properties.hasOwnProperty(key)) {
                        returnStr += '<td><ul>';
                        for (var attribute in data.properties[key]) {
                            returnStr += '<li><strong>' + attribute + ': </strong>' + data.properties[key][attribute] + '</li>';
                        }
                        returnStr += '</ul></td>';
                    }
                }

                returnStr += '</tr></table></div></div>';
                return (returnStr);
ratiw commented 8 years ago

@securit Your code looks fine. I really have no idea why the <table> tag was stripped.

In order for the inside table to take up the full width, you may need to use CSS to target it and set the width to 100%.