File: resources/js/components/DataTable.vue

Recommend this page to a friend!
  Classes of Edward Paul  >  Find PHP Service  >  resources/js/components/DataTable.vue  >  Download  
File: resources/js/components/DataTable.vue
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Find PHP Service
Application to find services in a near location
Author: By
Last change:
Date: 4 months ago
Size: 13,443 bytes
 

Contents

Class file image Download
<template>
    <div>
        <div class="card">
            <div class="card-header">
                {{ response.table | uppercase }}
                <a class="float-right" v-if="response.allow.creation" id="new_record" href="#" @click.prevent="creating.active = !creating.active">
                    {{ creating.active ? 'Cancel' : 'New Record'}}
                </a>
            </div>
            <div class="card-body ">
                <new-record :creating="creating" v-if="response.allow.creation && creating.active" v-on:save:record="store"></new-record>
                <h5 class="card-title">Search/Advanced Search</h5>
                <form action="#" @submit.prevent="getRecords">
                    <div class="row row-fluid">
                        <div class="form-group col-md-3">
                            <select id="" class="form-control" v-model="search.column">
                                <option :value="column" v-for="column in response.displayable">
                                    {{ column}}
                                </option>
                            </select>
                        </div>
                        <div class="form-group col-md-3">
                            <select class="form-control" v-model="search.operator">
                                <option value="equals">=</option>
                                <option value="contains">contains</option>
                                <option value="start_with">Start With</option>
                                <option value="ends_with">End With</option>
                                <option value="greater_than">Greater Than</option>
                                <option value="less_than">Less Than</option>
                            </select>
                        </div>
                        <div class="form-group col-md-6">
                            <div class="input-group">
                                <input type="text" id="search" class="form-control" v-model="search.value">
                                <span class="input-group-btn">
                                    <button class="btn btn-outline-info" type="submit">Search</button>
                                </span>
                            </div>

                        </div>
                    </div>
                </form>
                <div class="row">
                    <div class="form-group col-md-10">
                        <label for="filter" class="form-control-label"> Quick Search Current Results</label>
                        <input type="text" id="filter" class="form-control" v-model="quickSearchQuery"/>
                    </div>
                    <div class="form-group col-md-2">
                        <label for="limit" class="form-control-label">Display Records</label>
                                <select name="" id="limit" class="form-control" v-model="limit" @change="getRecords()">
                                    <option value="10"> 10 </option>
                                    <option value="50"> 50 </option>
                                    <option value="100"> 100 </option>
                                    <option value="1000"> 1000 </option>
                                    <option value=""> All </option>
                                </select>
                    </div>
                </div>
            </div>
        </div>

        <div class="card mt-4" >
            <div class="card-header" v-if="selected.length">
                <div class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"> With Selected</a>
                    <div class="dropdown-menu">
                        <a class="dropdown-item" href="#" @click.prevent="destroy(selected)">Delete {{ selected.length }} record </a>
                    </div>
                </div>
            </div>
            <div class="card-body">

                <div class="table-responsive" v-if="filteredRecords.length">
                    <table class="table table-hover">
                        <thead>
                        <tr>
                            <th  v-if="canSelectItems">
                                    <input
                                        type="checkbox"
                                        @change="toggleSelectAll"
                                        :checked="filteredRecords.length === selected.length"

                                    />

                            </th>
                            <th v-for="column in response.displayable">
                                <span class="sortable" @click="sortBy(column)">{{ response.custom_columns[column] || column|uppercase }}</span>
                                <span class="arrow" v-if="sort.key === column"
                                      :class="{ 'arrow--asc' : sort.order === 'asc', 'arrow--desc' : sort.order === 'desc' }"></span>
                            </th>

                            <th></th>
                        </tr>
                        </thead>
                        <tbody>
                        <tr v-for="record in filteredRecords">
                            <td v-if="canSelectItems">
                                    <input type="checkbox"
                                           v-model="selected"
                                           :value="record.id"

                                    />

                            </td>
                            <td v-for="columnValue, column in record">
                                <template v-if="editing.id === record.id && isUpdatable(column) ">
                                    <div class="form-group" :class="{ ' is-invalid' : editing.errors[column]}">
                                        <input type="text" class="form-control"
                                               v-bind:key="columnValue"
                                               v-model="editing.form[column]"
                                               :readonly="response.read_only_columns.includes(column)"
                                        >
                                        <span class="form-text text-muted" v-if="editing.errors[column]">
                                    {{ editing.errors[column][0]}}
                                </span>
                                    </div>

                                </template>
                                <template v-else>
                                    {{ columnValue }}
                                </template>
                            </td>
                            <td>
                                <a href="#" @click.prevent="edit(record)" v-if="editing.id != record.id" title="Quick Edit">QE</a>
                                <a href="#" @click.prevent="fullEdit(record)" v-if="editing.id != record.id" title="Full Edit">FE</a>
                                <a href="#" @click.prevent="destroy(record.id)" v-if="response.allow.deletion" title="Delete">Del</a>
                                <template v-if="editing.id === record.id">
                                    <a href="#" @click.prevent="update">Save</a><br>
                                    <a href="#" @click.prevent="editing.id = null">Cancel</a>
                                </template>
                            </td>

                        </tr>

                        </tbody>
                    </table>
                </div>
            </div>

        </div>
    </div>

</template>

<script>
    import queryString from 'query-string'
    import NewRecord from './NewRecord.vue'
    import ServiceEdit from './ServiceEdit.vue'

    export default {
        props: ['endpoint'],
        data(){
            return {
                response:{
                    table:'',
                    displayable: [],
                    updatable:[],
                    records: [],
                    allow:{}
                },
                sort:{
                    key:'id',
                    order:'desc'
                },
                editing:{
                  id: null,
                  form:{},
                  errors: []
                },
                search:{
                  value:'',
                  operator: 'equals',
                  column:'id'
                },
                creating:{
                  active:false,
                  form:{
                      city: null,
                      state:null,
                      latitude:null,
                      longitude:null,
                      zip_code:null,
                      address:null
                  },
                  errors: []
                },
                quickSearchQuery: '',
                limit:10,
                selected:[],
                autocomplete:null

            }

        },
        components:{
            NewRecord,
            ServiceEdit
        },
        computed:{
            filteredRecords(){
                let data = this.response.records.data
                if(this.response.records.data){
                    data = data.filter((row) => {
                        return Object.keys(row).some((key) => {
                            return String(row[key]).toLowerCase().indexOf(this.quickSearchQuery.toLowerCase()) > -1
                        })
                    })
                }


                if(this.sort.key){
                    data = _.orderBy(data, (i) => {
                        let value = i[this.sort.key]
                        if(!isNaN(parseFloat(value))){
                            return parseFloat(value)
                        }

                        return String(i[this.sort.key]).toLowerCase()
                    }, this.sort.order)
                }
                return data
            },
            canSelectItems(){
                return this.filteredRecords.length <= 90
            }
        },
        filters: {
            uppercase: function(s) {
                if (typeof s !== 'string') return ''
                return s.charAt(0).toUpperCase() + s.slice(1)
            }
        },
        methods:{
          getRecords(){
              return axios.get(`${this.endpoint}?${this.getQueryParameters()}`).then((response) => {
                  this.response = response.data.data
                  //console.log(response.data.data)
              })
          },
            getQueryParameters(){
                return queryString.stringify({
                    limit:this.limit,
                    page:1,
                    ...this.search
                })
            },
            sortBy(column){
              this.sort.key = column
              this.sort.order = this.sort.order === 'asc' ? 'desc' : 'asc'

            },
            edit(record){
              this.editing.errors = []
              this.editing.id = record.id
              this.editing.form = _.pick(record, this.response.updatable)
            },
            fullEdit(record){
                window.location.replace('/edit_service/'+record.id);
            },
            isUpdatable(column){
              return this.response.updatable.includes(column)
            },
            update(){
              axios.patch(`${this.endpoint}/${this.editing.id}`, this.editing.form).then(()=>{
                    this.getRecords().then(() => {
                        this.editing.id = null
                        this.editing.form = {}
                    })
              }).catch((error)=> {
                    this.editing.errors = error.response.data.errors
                })
            },
            store(){
              axios.post(`${this.endpoint}`, this.creating.form).then(()=>{
                  this.getRecords().then(() => {
                      this.creating.active = false
                      this.creating.form = {}
                      this.creating.errors = []
                  })
              }).catch((error) => {
                  if(error.response.status === 422){
                      this.creating.errors = error.response.data.errors
                  }

              })
            },
            destroy(record){
              if(!window.confirm('Are You sure you want to Delete this')){
                  return
              }
              axios.delete(`${this.endpoint}/${record}`).then(()=>{
                  this.selected = []
                  this.getRecords()
              })
            },
            toggleSelectAll(){
              if(this.selected.length > 0){
                  this.selected = []
                  return
              }
                this.selected = _.map(this.filteredRecords, 'id')
            }
        },
        mounted() {
            this.getRecords()
        }
    }
</script>

<style lang="scss">
    .sortable {
        cursor: pointer;
    }

    .arrow{
        display: inline-block;
        vertical-align: middle;
        width: 0;
        height: 0;
        margin-left: 5px;
        opacity: .6;

        &--asc {
            border-left: 4px solid transparent;
            border-right: 4px solid transparent;
            border-bottom: 4px solid #222;
         }


        &--desc {
            border-left: 4px solid transparent;
            border-right: 4px solid transparent;
            border-top: 4px solid #222;
        }
    }
</style>

For more information send a message to info at phpclasses dot org.