1

Hello everyone I'm new to vue.js and I'm confused whether it is possible to reload a data table (server side rendering) without refreshing the page using a component embedded in a blade.php?

Here is a my code. All of these components are attached in a blade.php file.

Department.vue Component (for adding)

    <template>
      <div class="container">
        <div class="row justify-content-center">
          <div class="col-md-8">
            <div class="card">
              <div class="card-header">Add Department / Section</div>
              <div class="card-body">
                <form @submit.prevent="addData()">

                <div class="form-group">
                  <label class="form-control-label" for="name">Department</label>
                  <input type="text" class="form-control" v-model="department">
                  <div v-if="errors.department" :class="['invalid-feedback']">{{ errors.department[0] }}</div>
                </div>

                <div class="form-group">
                  <label class="form-control-label" for="name">Section</label>
                  <input type="text" class="form-control" v-model="section" v-bind:class="{'is-invalid': validate && attemptSubmit && missingName }">
                  <div v-if="errors.section" :class="['invalid-feedback']">{{ errors.section[0] }}</div>
                </div>

                <button type="submit" class="btn btn-primary btn-block">Submit</button>
                <button class="btn btn-primary btn-block">Edit</button>
                </form>
                <strong>Output:</strong>
                <pre>
                {{output}}
                </pre>
              </div>
            </div>
          </div>
        </div>
      </div>
    </template>

<script>
  export default {
    mounted() {
      axios.get('/api/departments')
      .then(response => this.rows = response.data)
      .catch(error => console.log(error))
        },
    data() {
      return {
        department: '',
        section: '',
        output: '',
        attemptSubmit: false,
        validate: false,
        errors: [],
      };
    },
    computed: {
      missingName() {
        return this.section === ''
      },
    },
    methods: {
      addData() {
        this.attemptSubmit = true;
        this.validate = true;
        this.errors = [];
        if (this.errors) event.preventDefault();

        axios
        .post('/api/department', {
                    department: this.department,
                    section: this.section
        })
        .then(response => {
          this.validate = false;
          this.department = '';
          this.section = '';
          this.errors = '';
          this.output = response.data;
        })
        .catch(error => this.errors = error.response.data.errors)
      },
      deleteData(id) {
        if(confirm('Are you sure?')) {
          axios
          .delete(`/api/department/${id}`)
          .then(response => {this.output = response.data;})
          .catch(error => console.log(error))
        }
      }
    }
  }
</script>

Project.vue Component (data table)

<template>
  <div class="projects">
    <div class="tableFilters">
      <input class="input" type="text" v-model="tableData.search" placeholder="Search Table"
           @input="getProjects()">

      <div class="control">
        <div class="select">
          <select v-model="tableData.length" @change="getProjects()">
            <option v-for="(records, index) in perPage" :key="index" :value="records">{{records}}</option>
          </select>
        </div>
      </div>
    </div>
    <datatable :columns="columns" :sortKey="sortKey" :sortOrders="sortOrders" @sort="sortBy">
      <tbody>
        <tr v-for="project in projects" :key="project.id">
          <td>{{project.id}}</td>
          <td>{{project.department_name}}</td>
          <td>{{project.created_at}}</td>
                    <td> <a href="" @click="deleteData(project.id)"><i class="fas fa-trash" ></i></a></td>
        </tr>
      </tbody>
    </datatable>
    <pagination :pagination="pagination"
          @prev="getProjects(pagination.prevPageUrl)"
          @next="getProjects(pagination.nextPageUrl)">
    </pagination>
  </div>
</template>

<script>
import Datatable from './Datatable.vue';
import Pagination from './Pagination.vue';
export default {
  components: { datatable: Datatable, pagination: Pagination },
  created() {
    this.getProjects();
  },
  data() {
    let sortOrders = {};

    let columns = [
      {width: '33%', label: 'Deadline', name: 'id' },
      {width: '33%', label: 'Budget', name: 'department_name'},
      {width: '33%', label: 'Status', name: 'created_at'}
    ];

    columns.forEach((column) => {
       sortOrders[column.name] = -1;
    });
    return {
      projects: [],
      columns: columns,
      sortKey: 'id',
      sortOrders: sortOrders,
      perPage: ['5', '20', '30'],
      tableData: {
        draw: 0,
        length: 5,
        search: '',
        column: 0,
        dir: 'desc',
      },
      pagination: {
        lastPage: '',
        currentPage: '',
        total: '',
        lastPageUrl: '',
        nextPageUrl: '',
        prevPageUrl: '',
        from: '',
        to: ''
      },
    }
  },
  methods: {
    getProjects(url = '/api/departments') {
      this.tableData.draw++;
      axios
        .get(url, {params: this.tableData})
        .then(response => {
          let data = response.data;
          if (this.tableData.draw == data.draw) {
            this.projects = data.data.data;
            this.configPagination(data.data);
          }
        })
        .catch(errors => {
          console.log(errors);
        });
    },
    configPagination(data) {
      this.pagination.lastPage = data.last_page;
      this.pagination.currentPage = data.current_page;
      this.pagination.total = data.total;
      this.pagination.lastPageUrl = data.last_page_url;
      this.pagination.nextPageUrl = data.next_page_url;
      this.pagination.prevPageUrl = data.prev_page_url;
      this.pagination.from = data.from;
      this.pagination.to = data.to;
    },
    sortBy(key) {
      this.sortKey = key;
      this.sortOrders[key] = this.sortOrders[key] * -1;
      this.tableData.column = this.getIndex(this.columns, 'name', key);
      this.tableData.dir = this.sortOrders[key] === 1 ? 'asc' : 'desc';
      this.getProjects();
    },
    getIndex(array, key, value) {
      return array.findIndex(i => i[key] == value)
        },
         deleteData(id) {
        if(confirm('Are you sure?')) {
          axios.delete(`/api/department/${id}`)
          .then(response => {
            this.output = response.data;
            this.$parent.reload();
          })
          .catch(error => console.log(error))
                }
         }
  }
};
</script>
0

1 Answer 1

2

If you want to use laravel routing then it will refresh when you change the route. There is few ways to create SPA.

  1. Using separate vuejs project
  2. You can use https://inertiajs.com/
  3. You can use laravel livewire. Livewire

I will prefer to use inertiajs/livewire in your case and it can easily integrate with laravel and vuejs.

Sign up to request clarification or add additional context in comments.

1 Comment

So SPA would only be the real solution for not refreshing a page. Thank you very much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.