Search code examples
vue.jsvue-tables-2

How to show data in vue table that is in an array of arrays


I'am trying to show received data from serve in vue table but the data are in complex form. server returns an array of arrays. So it is a little bit tough to show them in vue table.

This is the response I got

enter image description here

Field defination of vue table

`

    export const FieldsDef_doctor_schedule = [
    {
        name:'doctor_id',
        title: 'doctor ID',
        sortField: 'id',
        callback: 'scheduleId'
    },
    {
        name:'department',
        title: 'Department',
        sortField: 'department'
    },
    {
        name:'date',
        title:'Available Time',
        callback:'schedueleCall'
    },
    {
                 name: '__slot:actions',
                 title: 'Actions',
                 dataClass: 'center aligned'
         }
    ]

`

Vue Table

enter image description here

As the date and time information is correspondence to the each doctor_id and department. I want vue table to show eache 3 arrays named date_time in one row according to the doctor id departmrnt.

Demo

enter image description here

May anyone help?

Template Code

<template>
  <div id="schedule">
    <div class="page-wrapper">
      <div class="container" style="margin-top: 25px;margin-left: 50px;">
        <div class="row">
          <div class="col-md-7">
            <h4 class="page-title">Schedule</h4>
          </div>
          <div class="col-md-4 text-right m-b-20">
            <router-link class="ui button positive" to="/admin/doctors_schedule/addschedule">
              <i class="plus icon"></i>
              <strong>
                Add
                Schedule
              </strong>
            </router-link>
          </div>
        </div>
        <div class="row">
          <div class="col-md-11">
            <hr />
          </div>
        </div>
        <div class="row">
          <div class="col-md-11 border">
            <div class="ui container">
              <filter-bar></filter-bar>
              <vuetable
                ref="vuetable"
                api-url="https://vuetable.ratiw.net/api/users"
                :fields="fields"
                pagination-path
                :per-page="5"
                :multi-sort="true"
                :sort-order="sortOrder"
                :append-params="moreParams"
                @vuetable:pagination-data="onPaginationData"
              >
                <template slot="actions" slot-scope="props">
                  <div class="custom-actions">
                    <router-link to="/admin/doctors_schedule/editschedule" class="ui button yellow">
                      <i class="edit icon"></i>
                    </router-link>
                    <button
                      class="ui button red"
                      @click="onAction('delete-item', props.rowData, 
      props.rowIndex)"
                    >
                      <i class="trash alternate icon"></i>
                    </button>
                  </div>
                </template>
              </vuetable>
              <div class="vuetable-pagination ui basic segment grid">
                <vuetable-pagination-info ref="paginationInfo"></vuetable-pagination-info>
                <vuetable-pagination
                  ref="pagination"
                  @vuetable-pagination:change-page="onChangePage"
                ></vuetable-pagination>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
  <script>
import Vue from "vue";
import VueEvents from "vue-events";
import Vuetable from "vuetable-2/src/components/Vuetable";
import VuetablePagination from "vuetable-2/src/components/VuetablePagination";
import VuetablePaginationInfo from "vuetable-2/src/components/VuetablePaginationInfo";
import FilterBar from "@/components/Pages/Admin/import_details/FilterBar";
import { FieldsDef_doctor_schedule } from "@/components/Pages/Admin/import_details/FieldsDef_doctor_schedule";
import { apiDomain } from "@/components/Pages/Authentication/config";

Vue.use(VueEvents);
Vue.component("filter-bar", FilterBar);

export default {
  components: {
    Vuetable,
    VuetablePagination,
    VuetablePaginationInfo
  },
  data() {
    return {
      fields: FieldsDef_doctor_schedule,
      sortOrder: [],
      moreParams: {},
      apiURL: ""
    };
  },
  mounted() {
    this.$events.$on("filter-set", eventData => this.onFilterSet(eventData));
    this.$events.$on("filter-reset", e => this.onFilterReset());
  },
  methods: {
    scheduleId(value) {
      return value;
      console.log(value);
    },
    onPaginationData(paginationData) {
      this.$refs.pagination.setPaginationData(paginationData);
      this.$refs.paginationInfo.setPaginationData(paginationData);
    },
    onChangePage(page) {
      this.$refs.vuetable.changePage(page);
    },
    onAction(action, data, index) {
      console.log("slot action: " + action, data.name, index);
    },
    onFilterSet(filterText) {
      this.moreParams.filter = filterText;
      Vue.nextTick(() => this.$refs.vuetable.refresh());
    },
    onFilterReset() {
      delete this.moreParams.filter;
      Vue.nextTick(() => this.$refs.vuetable.refresh());
    }
  },
  created() {
    this.apiURL = apiDomain + "api/getDoctorScheduleInfo";
    this.$http
      .get(this.apiURL)
      .then(response => {
        // console.log(response.body.scheduleInfo)
        console.log(response);
        response.body.scheduleInfo.forEach(function(val) {
          // console.log(val.date_time)
          val.date_time.forEach(function(val2) {
            console.log(
              "Date: " +
                val2.date +
                ", Time: " +
                val2.time_from +
                " To " +
                val2.time_to
            );
          });
        });
      })
      .catch(e => {
        console.log(e);
      });
  }
};
</script>

Solution

  • few things I noticed...

    • you're missing the data-path attribute, which you need because your data is inside sheduleInfo variable
      ie: data-path="sheduleInfo"

    • ...but, you can also use the transform property to handle/transform the data. Because you want to loop over the content, this isn't (alone) going to solve the multiple entries issue.

    • add additional slot to template and update the config (update date field to use __slot:availableTimes instead)

      <template slot="availableTimes" slot-scope="props">
        <div v-for="(dt, i)props.rowData.date_time" :key="i">
          Date {{dt.date}} ...etc
        </div>
      </template>