Laravel 8 Jet Live
Laravel 8 Jet Live
Laravel 8 Jet Live
3. Buat Database
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* @return void
*/
$table->id();
$table->string('title')->unique();
$table->timestamps();
});
/**
* Reverse the migrations.
* @return void
*/
Schema::dropIfExists('companies');
Run command to create Livewire CRUD files (it will create /app/Http/Livewire/Companies.php and
/resources/views/livewire/companies.blade.php):
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Company;
public $title;
public $company_id;
public $isOpen = 0;
/**
*
* @var array
*/
return view('livewire.companies', [
/**
* @var array
*/
$this->resetInputFields();
$this->openModal();
/**
* @var array
*/
$this->isOpen = true;
}
/**
* @var array
*/
$this->isOpen = false;
/**
* @var array
*/
$this->title = '';
$this->company_id = '';
/**
* @var array
*/
$this->validate([
]);
$data = array(
);
$this->closeModal();
$this->resetInputFields();
/**
* @var array
*/
$company = Company::findOrFail($id);
$this->company_id = $id;
$this->title = $company->title;
$this->openModal();
/**
* @var array
*/
$this->company_id = $id;
Company::find($id)->delete();
<x-slot name="header">
{{ __('Companies') }}
</h2>
</x-slot>
@if (session()->has('message'))
<div id="alert" class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-green-500">
{{ session('message') }}
</span>
<span>×</span>
</button>
</div>
@endif
@if (count($companies)>0)
<div class="py-10">
<thead>
<tr>
<th
class="px-5 py-3 border-b-2 border-black bg-black text-left text-xs font-semibold
text-white uppercase tracking-wider">
{{ __('Title') }}
</th>
<th
</th>
</tr>
</thead>
<tbody>
@foreach($companies as $company)
<tr>
{{ Str::limit($company->title, 25) }}
</td>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
@if($isOpen)
<form>
</div>
</div>
</div>
</span>
</span>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endif
</div>
@push('styles')
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/sweetalert2@10/dist/sweetalert2.min.css">
@endpush
@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.js"></script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
Swal.fire({
type: "warning",
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'Delete!'
}).then((result) => {
if (result.value) {
@this.call('delete',companyId)
} else {
console.log("Canceled");
});
});
})
</script>
@endpush
and style
It means in
/resources/views/layouts/app.blade.php
<!DOCTYPE html>
<head>
<meta charset="utf-8">
@livewireStyles
@stack('styles')
</head>
@livewire('navigation-dropdown')
{{ $header }}
</div>
</header>
<main>
{{ $slot }}
</main>
</div>
@stack('modals')
@livewireScripts
@stack('scripts')
</body>
</html>
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use HasFactory;
protected $fillable = [
'title'
];
Route::middleware(['auth:sanctum', 'verified'])->get('/companies',
App\Http\Livewire\Companies::class)->name('companies');
And in the last step need to add companies pages link to main menu. In
/resources/views/navigation-dropdown.blade.php add menu item:
{{ __('Companies') }}
</x-jet-nav-link>
</div>
And in the same file, where is comment <!-- Responsive Navigation Menu --> add:
{{ __('Companies') }}
</x-jet-responsive-nav-link>
Darius Dauskurdis
We will continue previous Laravel 8 - CRUD basic steps (Livewire and Tailwind) tutorial. But this time,
we will try to make our CRUD more advanced.
Let's add more fields in companies table. We can continue editing old (if didn't migrate) or create
new migration file. We want to add extra fields for information about which user created or updated
company. So migration file should look like:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* @return void
*/
$table->id();
$table->string('title')->unique();
$table->bigInteger('created_by')->nullable()->unsigned();
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$table->bigInteger('updated_by')->nullable()->unsigned();
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
$table->timestamps();
});
/**
* @return void
*/
Schema::dropIfExists('companies');
In app/Models/Company.php file need to add new fillable fields, and add "boot" method to run
specific actions automatically when user will create or update company.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use HasFactory;
protected $fillable = [
];
/**
* This is model Observer which helps to do the same actions automatically when you creating or
updating models
* @var array
*/
parent::boot();
static::creating(function ($model) {
$model->created_by = Auth::id();
$model->updated_by = Auth::id();
});
static::updating(function ($model) {
$model->updated_by = Auth::id();
});
Let's upgrade our /app/Http/Livewire/Companies.php file. At first need to fix error messages. When
user submit form and forgot to fill fields, he will see errors and when if form will be closed and
opened again, these errors still will be visible. So in "openModal()" method need to add two lines of
code:
$this->resetErrorBag();
$this->resetValidation();
If we have only few companies, no problem. But if users will add many companies, we need to add
pages. Let's say we need to show 10 companies per page. At first need to add "WithPagination" trait
provided by Livewire.
use Livewire\WithPagination;
use WithPagination;
Add extra paginate method on an Eloquent query. public function render() { return
view('livewire.companies', [ 'companies' => Company::orderBy('id', 'desc')->paginate(10) ]); }
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Company;
use Livewire\WithPagination;
use Illuminate\Support\Facades\Auth;
use WithPagination;
public $title;
public $company_id;
public $isOpen = 0;
/**
* @var array
*/
return view('livewire.companies', [
]);
/**
* @var array
*/
$this->resetInputFields();
$this->openModal();
/**
* @var array
*/
public function openModal()
$this->isOpen = true;
$this->resetErrorBag();
$this->resetValidation();
/**
* @var array
*/
$this->isOpen = false;
/**
* @var array
*/
$this->title = '';
$this->company_id = '';
/**
*
* @var array
*/
$this->validate([
]);
$data = array(
);
$this->closeModal();
$this->resetInputFields();
/**
* @var array
*/
$company = Company::findOrFail($id);
$this->company_id = $id;
$this->title = $company->title;
$this->openModal();
}
/**
* @var array
*/
$this->company_id = $id;
Company::find($id)->delete();
We are using not default pagination template, we want to use customised with tailwind. So need to
create new file /resources/views/pagination.blade.php and paste inside code:
@if ($paginator->hasPages())
@if ($paginator->onFirstPage())
</span>
@else
@if (isset($is_livewire))
@else
</a>
@endif
@endif
@if ($paginator->hasMorePages())
@if (isset($is_livewire))
</button>
@else
</a>
@endif
@else
<span class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-
500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
</span>
@endif
</div>
<div class="px-5 py-5 bg-white flex flex-col xs:flex-row items-center xs:justify-between">
<div>
</div>
@if ($paginator->onFirstPage())
</svg>
</span>
</span>
@else
@if (isset($is_livewire))
</svg>
</button>
@else
</svg>
</a>
@endif
@endif
@if (is_string($element))
<span aria-disabled="true">
</span>
@endif
@if (is_array($element))
<span aria-current="page">
</span>
@else
@if (isset($is_livewire))
{{ $page }}
</button>
@else
<a href="{{ $url }}" class="relative inline-flex items-center px-4 py-2 -ml-px
text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-500
focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100
active:text-gray-700 transition ease-in-out duration-150" aria-label="{{ __('Go to page :page', ['page'
=> $page]) }}">
{{ $page }}
</a>
@endif
@endif
@endforeach
@endif
@endforeach
@if ($paginator->hasMorePages())
@if (isset($is_livewire))
</svg>
</button>
@else
</svg>
</a>
@endif
@else
</svg>
</span>
</span>
@endif
</span>
</div>
</div>
</nav>
@endif
Let's come back to /resources/views/livewire/companies.blade.php file. When user will click button
"Create new company" will popup modal. If we are thinking to use this modal in other places, need
to create standard modal style (frame), which we can use with different content. For now we need
modal with form fields to set information about company. In Laravel 8 we can easy create
components.
{{ $content }}
</div>
</div>
</div>
</div>
</div>
<?php
namespace App\View\Components;
use Illuminate\View\Component;
/**
* @return void
*/
//
}
/**
* @return \Illuminate\Contracts\View\View|string
*/
return view('components.customised-modal');
Now we can call this component by using tags (tag name x- and name of view)
<x-customised-modal>...</x-customised-modal>
But we have additional variable $content, it means we need to add x-slot tag with name "content"
and add inside our form.
<x-customised-modal>
<x-slot name="content">
My form
</x-slot>
</x-customised-modal>
<x-slot name="header">
{{ __('Companies') }}
</h2>
</x-slot>
@if (session()->has('message'))
<div id="alert" class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-green-500">
</span>
<span>×</span>
</button>
</div>
@endif
@if (count($companies)>0)
<div class="py-10">
<thead>
<tr>
<th
{{ __('Title') }}
</th>
<th
</th>
</tr>
</thead>
<tbody>
@foreach($companies as $company)
<tr>
{{ Str::limit($company->title, 25) }}
</td>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
@if($isOpen)
<x-customised-modal>
<x-slot name="content">
<form>
</div>
</div>
</div>
</span>
</span>
</div>
</form>
</x-slot>
</x-customised-modal>
@endif
</div>
@push('styles')
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/sweetalert2@10/dist/sweetalert2.min.css">
@endpush
@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.js"></script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
Swal.fire({
type: "warning",
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'Delete!'
}).then((result) => {
if (result.value) {
@this.call('delete',companyId)
} else {
console.log("Canceled");
});
});
})
</script>
@endpush