[LARAVEL] Crud Vuejs full ❤️❤️ (ok)

Front-end

C:\xampp\htdocs\vl\resources\js\app.js

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */
require('./bootstrap');
window.Vue = require('vue').default;
/**
 * The following block of code may be used to automatically register your
 * Vue components. It will recursively scan this directory for the Vue
 * components and automatically register them with their "basename".
 *
 * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
 */
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('customers', require('./components/Customers.vue').default);
Vue.component('navbar', require('./components/Nav.vue').default);
Vue.component('foot', require('./components/Footer.vue').default);
/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */
const app = new Vue({
    el: '#app',
});

C:\xampp\htdocs\vl\resources\js\components\Nav.vue

<template>
  <div class="container">
    <ul class="nav  mb-3">
      <li class="nav-item">
        <a class="nav-link active" aria-current="page" href="#">Active</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
    </ul>
  </div>
</template>
<script type="text/javascript">
  export default {
    
  }
</script>

C:\xampp\htdocs\vl\resources\js\components\Footer.vue

<template>
  <div class="container">
    <div class="row justify-content-center">
      <div class="col-md-12 col-lg-12">
        <div class="card">
            <p class="text-center">I'm an Footer.</p>
        </div>
      </div>
    </div>
  </div>
</template>
<script type="text/javascript">
  export default {
    
  }
</script>

C:\xampp\htdocs\vl\resources\js\components\Customers.vue

<template>
  <div class="container">
    <form @submit.prevent="addCustomer">
      <div class="form-group">
        <input type="text" name="form-control" placeholder="Name" v-model="customer.name_customer">
        <input type="text" name="form-control" placeholder="Phone" v-model="customer.phone_customer">
        <input type="text" name="form-control" placeholder="Email" v-model="customer.email_customer">
        <input type="text" name="form-control" placeholder="City" v-model="customer.city_customer">
        <input type="text" name="form-control" placeholder="Address" v-model="customer.address_customer">
        <input type="file" name="form-control-file" ref="fileUpload" @change="onFileChange" placeholder="File" id="image">
        <div id="preview" class="mt-3">
          <img style="width: 350px;" v-if="url" :src="url" alt="Image">
        </div>
      </div>      
      <button type="submit" class="btn btn-primary mt-3">{{ this.button }}</button>
    </form>
    <ul class="pagination mt-3">
      <li class="page-item">
        <a class="page-link" href="#" @click="fetchCustomers(pagination.first_page_url)">First</a>
      </li>
      <li class="page-item" :class="{disabled:!pagination.next_page_url}">
        <a class="page-link" href="#" @click="fetchCustomers(pagination.next_page_url)">Next</a>
      </li>
      <li class="page-item disabled">
        <a class="page-link" href="#">{{ pagination.current_page }} ... {{ pagination.last_page }}</a>
      </li>
      <li class="page-item" :class="{disabled:!pagination.prev_page_url}">
        <a class="page-link" href="#" @click="fetchCustomers(pagination.prev_page_url)">Previous</a>
      </li>
      <li class="page-item">
        <a class="page-link" href="#" @click="fetchCustomers(pagination.last_page_url)">Last</a>
      </li>
    </ul>
    <div class="row justify-content-center">
      <div class="col-md-12 col-lg-12">
        <div class="card">
          <div class="card-header">Customer</div>
          <div class="card-body pb-0" v-for="ctm in customers">
            <p>Name: {{ctm.name_customer}}</p>
            <p>Address: {{ctm.address_customer}}</p>
            <p>City: {{ctm.city_customer}}</p>
            <p>Email: {{ctm.email_customer}}</p>
            <div>Phone: {{ctm.phone_customer}}</div>
            <p id="preview" style="width: 350px;" class="mt-3">
              <img style="width: 100%;object-fit: cover;" :src="'public/uploads/' + ctm.image_customer" alt="buildings">
            </p>
            <button class="btn btn-danger mt-3" @click="deleteCustomer(ctm.id)">Delete</button>
            <button class="btn btn-warning mt-3" @click="editCustomer(ctm)">Edit</button>
            <hr />
          </div>
        </div>
      </div>
    </div>
    <ul class="pagination mt-3">
      <li class="page-item">
        <a class="page-link" href="#" @click="fetchCustomers(pagination.first_page_url)">First</a>
      </li>
      <li class="page-item" :class="{disabled:!pagination.next_page_url}">
        <a class="page-link" href="#" @click="fetchCustomers(pagination.next_page_url)">Next</a>
      </li>
      <li class="page-item disabled">
        <a class="page-link" href="#">{{ pagination.current_page }} ... {{ pagination.last_page }}</a>
      </li>
      <li class="page-item" :class="{disabled:!pagination.prev_page_url}">
        <a class="page-link" href="#" @click="fetchCustomers(pagination.prev_page_url)">Previous</a>
      </li>
      <li class="page-item">
        <a class="page-link" href="#" @click="fetchCustomers(pagination.last_page_url)">Last</a>
      </li>
    </ul>
  </div>
</template>
<script type="text/javascript">
export default {
  data() {
    return {
      customers: [],
      url: "",
      customer: {
        "name_customer": "",
        "phone_customer": "",
        "address_customer": "",
        "email_customer": "",
        "city_customer": ""
      },
      id_customer: "",
      pagination: {},
      edit: false,
      currentPage: 1,
      button: "Add"
    }
  },
  mounted() {
    this.fetchCustomers();
  },
  methods: {
    fetchCustomers: function(page_url = null) {
      let vm = this;
      let meta = {};
      let links = {};
      page_url = page_url || 'api/customers';
      fetch(page_url)
      .then(response => response.json())
      .then(json => {
        this.customers = json.data;
        meta.current_page = json.current_page;
        meta.from = json.from;
        meta.last_page = json.last_page;
        meta.per_page = json.per_page;
        meta.to = json.to;
        meta.total = json.total;
        links.first_page_url = json.first_page_url;
        links.last_page_url = json.last_page_url;
        links.next_page_url = json.next_page_url;
        links.prev_page_url = json.prev_page_url;
        vm.makePagination(meta, links);
      })
      .catch(err => console.log('Request Failed', err));
    },
    makePagination: function(meta, links) {
      let pagination = {
        current_page: meta.current_page,
        first_page_url: links.first_page_url,
        last_page_url: links.last_page_url,
        next_page_url: links.next_page_url,
        next_page_url_disabled: links.next_page_url,
        prev_page_url: links.prev_page_url
      }
      this.pagination = pagination;
    },
    deleteCustomer: function(id) {
      if(confirm("Are you sure you want Delete 😒")) {
        axios.delete(`api/customers/${id}`)
        .then((res) => {
          this.fetchCustomers();
        }).catch((error)=>{
          console.log(error);
        });
      }
    },
    addCustomer: function() {
      if(!this.edit) {
        let formData = new FormData();
        formData.append('name_customer',this.customer.name_customer);
        formData.append('phone_customer',this.customer.phone_customer);
        formData.append('email_customer',this.customer.email_customer);
        formData.append('city_customer',this.customer.city_customer);
        formData.append('address_customer',this.customer.address_customer);
        if(document.getElementById("image").files[0]) {
          formData.append('image_customer',document.getElementById("image").files[0]);
        }
        axios.post('api/customers',formData,{
          'Content-Type': 'multipart/form-data'
        })
        .then((res)=>{
          this.customer.name_customer = "";
          this.customer.phone_customer = "";
          this.customer.email_customer = "";
          this.customer.city_customer = "";
          this.customer.address_customer = "";
          this.$refs.fileUpload.value = "";
          this.fetchCustomers();
        }).catch((error)=>{
          console.log(error);
        });
      }else {
        let formData = new FormData();
        formData.append('name_customer',this.customer.name_customer);
        formData.append('phone_customer',this.customer.phone_customer);
        formData.append('email_customer',this.customer.email_customer);
        formData.append('city_customer',this.customer.city_customer);
        formData.append('address_customer',this.customer.address_customer);
        axios.put(`api/customers/${this.customer.id}`,{
          name_customer: this.customer.name_customer,
          phone_customer: this.customer.phone_customer,
          email_customer: this.customer.email_customer,
          city_customer: this.customer.city_customer,
          address_customer: this.customer.address_customer
        })
        .then((res)=>{
          this.fetchCustomers();
        }).catch((error)=>{
          console.log(error);
        });
      }
    },
    editCustomer: function(ctm) {
      this.edit = true;
      this.button = "Edit";
      this.customer.id = ctm.id;
      this.customer.name_customer = ctm.name_customer;
      this.customer.phone_customer = ctm.phone_customer;
      this.customer.email_customer = ctm.email_customer;
      this.customer.city_customer = ctm.city_customer;
      this.customer.address_customer = ctm.address_customer;
      this.url = `public/uploads/${ctm.image_customer}`;
      const el = this.$el.querySelector(".card");
      let rect = el.getBoundingClientRect();
      window.scrollTo(rect.left,rect.top);
    },
    onFileChange: function(e) {
      const file = e.target.files[0];
      this.url = URL.createObjectURL(file)
    }
  },
}
</script>

C:\xampp\htdocs\vl\composer.json

Back-end

C:\xampp\htdocs\vl\routes\api.php

<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\CustomerController;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});
Route::resource('customers', CustomerController::class);

C:\xampp\htdocs\vl\app\Models\Customer.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model {
  use HasFactory;
  public $timestamps = false;
  protected $table = 'customer';
  protected $primaryKey = 'id';
  protected $fillable = ['name_customer', 'phone_customer', 'address_customer','email_customer','city_customer','image_customer'];
}

C:\xampp\htdocs\vl\app\Http\Controllers\CustomerController.php

<?php
namespace App\Http\Controllers;
use App\Models\Customer;
use Illuminate\Http\Request;

class CustomerController extends Controller {
  /**
   * Display a listing of the resource.
   *
   * @return \Illuminate\Http\Response
   */
  public function index() {
    return Customer::orderBy('id', "DESC")->paginate(5);
  }
  /**
   * Show the form for creating a new resource.
   *
   * @return \Illuminate\Http\Response
   */
  public function create() {
    //
  }
  /**
   * Store a newly created resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @return \Illuminate\Http\Response
   */
  public function store(Request $request) {
    $customer                   = new Customer();
    $customer->name_customer    = $request->name_customer;
    $customer->phone_customer   = $request->phone_customer;
    $customer->email_customer   = $request->email_customer;
    $customer->city_customer    = $request->city_customer;
    $customer->address_customer = $request->address_customer;
    if ($request->image_customer) {
      $get_image      = $request->image_customer;
      $path           = 'public/uploads/';
      $get_name_image = $get_image->getClientOriginalName();
      $name_image     = current(explode('.', $get_name_image));
      $new_image      = $name_image . rand(0, 99) . '.' . $get_image->getClientOriginalExtension();
      $get_image->move($path, $new_image);
      $customer->image_customer = $new_image;
    }else {
      $customer->image_customer = "default.png";
    }
    $customer->save();
  }
  /**
   * Display the specified resource.
   *
   * @param  \App\Models\Customer  $customer
   * @return \Illuminate\Http\Response
   */
  public function show(Customer $customer) {
    return Customer::find($customer);
  }
  /**
   * Show the form for editing the specified resource.
   *
   * @param  \App\Models\Customer  $customer
   * @return \Illuminate\Http\Response
   */
  public function edit(Customer $customer) {
    //
  }
  /**
   * Update the specified resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \App\Models\Customer  $customer
   * @return \Illuminate\Http\Response
   */
  public function update(Request $request, $customer) {
    $customer                   = Customer::find($customer);
    $customer->name_customer    = $request->name_customer;
    $customer->phone_customer   = $request->phone_customer;
    $customer->email_customer   = $request->email_customer;
    $customer->city_customer    = $request->city_customer;
    $customer->address_customer = $request->address_customer;
    $customer->save();
  }
  /**
   * Remove the specified resource from storage.
   *
   * @param  \App\Models\Customer  $customer
   * @return \Illuminate\Http\Response
   */
  public function destroy(Customer $customer) {
    return $customer->delete();
  }
}

Source

Last updated