Nameless_0's avatar

Laravel + Vuejs autocomplete with one to many relationship

Hi everyone! I need some help in adding a autocomplete function in this app. I'd like the data from my other table (employees table) to be displayed when ever the user inputs inside the text box and displayed along the class cards when selected. I am having a hard time since i'm really new to using one to many relationships in laravel and vuejs. Thanks!

I already fixed both tables models.

Employee model:

<?php

namespace App;
 
use Illuminate\Database\Eloquent\Model;

class Employee extends Model
{
    public function invsystem()
    {
         return $this->hasMany('App\Invsystem');
    }
}

Inventory model:

<?php

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class Invsystem extends Model
{
    public function employee()
    {
         return $this->belongsTo('App\Employee');
    }
}

I am also using pagination, here is the controller:

public function index()
    {
        $invsystems = Invsystem::orderBy('created_at', 'desc')->with('Employee')->paginate(5);
        return InvsystemResource::collection($invsystems);
    }

Here is the .vue:

<form @submit.prevent="addInvsystem" class="mb-3">
            <div class="form-group">
                <input type="text" class="form-control" placeholder="stock name" v-model="invsystem.stock_name">
            </div>
            <div class="form-group">
                <input type="text" class="form-control" placeholder="serial number" v-model="invsystem.serial">
            </div>
            <div class="form-group">
                <input type="text" class="form-control" placeholder="model" v-model="invsystem.model">
            </div>
            <div class="form-group">
                <input type="text" class="form-control" placeholder="product number" v-model="invsystem.product_no">
            </div>
            <div class="form-group">
                <textarea class="form-control" placeholder="remarks" v-model="invsystem.remarks"></textarea>
            </div>
            
            <center>
            <button type="submit" class="btn btn btn-success w-75 p-2">SAVE</button>
            </center>
            <h4 class="mb-3">Inventory</h4>
        </form>
        <nav aria-label="Page navigation example">
        <ul class="pagination">
               <li  v-bind:class="[{disabled: !pagination.prev_page_url}]" class="page-item"><a class="page-link" href="#" @click="fetchInvsystems(pagination.prev_page_url)">Previous</a></li>
               
                <li class="page-item disabled"><a class="page-link text-dark" href="#">Page {{ pagination.current_page }} of {{ pagination.last_page }}</a></li>

               <li v-bind:class="[{disabled: !pagination.next_page_url}]" class="page-item"><a class="page-link" href="#" @click="fetchInvsystems(pagination.next_page_url)">Next</a></li>
              </ul>
        </nav>
            <div class="card card-body border-success text-green mb-2" v-for="invsystem in invsystems" v-bind:key="invsystem.id">
                <h5><b>stock name:</b> {{ invsystem.stock_name }}</h5>
                <h5><b>serial number:</b> {{ invsystem.serial }}</h5>
                <h5><b>model:</b> {{ invsystem.model }} </h5>
                <h5><b>product number: </b> {{ invsystem.product_no }}</h5>
                <p><b>remarks:</b> {{ invsystem.remarks }} </p>
                <!-- <p>{{ $employee->employee->email }} </p> -->
                <hr>
            </div>
0 likes
3 replies
edward1995's avatar

$invsystems = Invsystem::orderBy('created_at', 'desc')->with('employee')->paginate(5); return InvsystemResource::collection($invsystems);

1 like
Nameless_0's avatar

.vue script:

<script>
    export default {
        data() {
            return {
                invsystems: [],
                invsystem: {
                    id: '',
                    stock_name: '',
                    serial: '',
                    model: '',
                    product_no: '',
                    remarks: ''
                },
                invsystem_id: '',
                pagination: {},
                edit: false
            };
        },

        created() {
            this.fetchInvsystems();
        },

        methods: {
            fetchInvsystems(page_url) {
                let vm = this;
                page_url = page_url || '/api/invsystems'
                fetch(page_url)
                .then(res => res.json())
                .then(res => {
                  this.invsystems = res.data;
                  vm.makePagination(res.meta, res.links);
                })
                .catch(err => console.log(err));
            },
            makePagination(meta, links) {
                let pagination = {
                    current_page: meta.current_page,
                    last_page: meta.last_page,
                    next_page_url: links.next,
                    prev_page_url: links.prev
                }

                this.pagination = pagination; 
            },
            deleteInvsystem(id) {
                if(confirm('Are You Sure?')) {
                    fetch(`api/invsystem/${id}`, {
                        method: 'delete'
                    })
                    .then(res => res.json())
                    .then(data => {
                        alert('Inventory info deleted');
                        this.fetchInvsystems();
                    })
                    .catch(err => console.log(err));
                }
            },
            addInvsystem() {
                if(this.edit === false) {
                    //Add
                    fetch('api/invsystem', {
                        method: 'post',
                        body: JSON.stringify(this.invsystem),
                        headers: {
                            'content-type': 'application/json'
                        }
                    })
                    .then(res => res.json())
                    .then(data => {
                        this.invsystem.stock_name = '';
                        this.invsystem.serial = '';
                        this.invsystem.model = '';
                        this.invsystem.product_no = '';
                        this.invsystem.remarks = '';
                        alert('Inventory info Added');
                        this.fetchInvsystems();
                    })
                    .catch(err => console.log(err));
                }   else {
                    // Update
                    fetch('api/invsystem', {
                        method: 'put',
                        body: JSON.stringify(this.invsystem),
                        headers: {
                            'content-type': 'application/json'
                        }
                    })
                    .then(res => res.json())
                    .then(data => {
                        this.invsystem.stock_name   = '';
                        this.invsystem.serial       = '';
                        this.invsystem.model        = '';
                        this.invsystem.product_no   = '';
                        this.invsystem.remarks      = '';
                        alert('Inventory info updated');
                        this.fetchInvsystems();
                    })
                    .catch(err => console.log(err));
                }
            },
            editInvsystem(invsystem) {
                this.edit = true;
                this.invsystem.id           = invsystem.id;
                this.invsystem.invsystem_id = invsystem.id;
                this.invsystem.stock_name   = invsystem.stock_name;
                this.invsystem.serial       = invsystem.serial;
                this.invsystem.model        = invsystem.model;
                this.invsystem.product_no   = invsystem.product_no;
                this.invsystem.remarks      = invsystem.remarks;  
            }
        }
    };
</script>

Please or to participate in this conversation.