DEV Community

Cover image for Laravel 8 - advanced CRUD (Livewire and Tailwind)
Darius Dauskurdis
Darius Dauskurdis

Posted on • Edited on

Laravel 8 - advanced CRUD (Livewire and Tailwind)

  • 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;

class CreateCompaniesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('companies', function (Blueprint $table) {
            $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();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('companies');
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Run command to add table in database:

php artisan migrate

  • 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;

class Company extends Model
{
    use HasFactory;

    protected $fillable = [
        'title', 'created_by', 'updated_by'
    ];

    /**
     * This is model Observer which helps to do the same actions automatically when you creating or updating models
     *
     * @var array
     */
    protected static function boot()
    {
        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();
        });
    }
}
Enter fullscreen mode Exit fullscreen mode
  • 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();
Enter fullscreen mode Exit fullscreen mode
  • 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;
Enter fullscreen mode Exit fullscreen mode
  • And inside class "Companies" add
use WithPagination;
Enter fullscreen mode Exit fullscreen mode
  • Add extra paginate method on an Eloquent query. public function render() { return view('livewire.companies', [ 'companies' => Company::orderBy('id', 'desc')->paginate(10) ]); }
  • So now our /app/Http/Livewire/Companies.php file looks like:
<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Company;

use Livewire\WithPagination;

use Illuminate\Support\Facades\Auth;

class Companies extends Component
{

    use WithPagination;

    public $title;
    public $company_id;
    public $isOpen = 0;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */

    public function render()
    {
        return view('livewire.companies', [
            'companies' => Company::orderBy('id', 'desc')->paginate(10)
        ]);
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */

    public function create()
    {
        $this->resetInputFields();
        $this->openModal();
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function openModal()
    {
        $this->isOpen = true;
        // Clean errors if were visible before
        $this->resetErrorBag();
        $this->resetValidation();
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function closeModal()
    {
        $this->isOpen = false;
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    private function resetInputFields(){
        $this->title = '';
        $this->company_id = '';
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */

    public function store()
    {
        $this->validate([
            'title' => 'required|unique:companies,title,'.$this->company_id,
        ]);
        $data = array(
            'title' => $this->title
        );
        $company = Company::updateOrCreate(['id' => $this->company_id],$data);
        session()->flash('message', $this->company_id ? 'Company updated successfully.' : 'Company created successfully.');
        $this->closeModal();
        $this->resetInputFields();
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function edit($id)
    {
        $company = Company::findOrFail($id);
        $this->company_id = $id;
        $this->title = $company->title;
        $this->openModal();
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function delete($id)
    {
        $this->company_id = $id;
        Company::find($id)->delete();
        session()->flash('message', 'Company deleted successfully.');
    }

}
Enter fullscreen mode Exit fullscreen mode
  • In /resources/views/livewire/companies.blade.php file under the table need to add pagination.
{{ $companies->links('pagination',['is_livewire' => true]) }}
Enter fullscreen mode Exit fullscreen mode
  • 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())
    <nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="px-5 py-5 bg-white border-t flex flex-col xs:flex-row items-center xs:justify-between ">
        <div class="flex justify-between flex-1 sm:hidden">
            @if ($paginator->onFirstPage())
                <span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
                    {!! __('pagination.previous') !!}
                </span>
            @else
                @if (isset($is_livewire))
                    <button wire:click="previousPage" dusk="previousPage.before" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
                        {!! __('pagination.previous') !!}
                    </button>
                @else
                    <a href="{{ $paginator->previousPageUrl() }}" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
                        {!! __('pagination.previous') !!}
                    </a>
                @endif
            @endif

            @if ($paginator->hasMorePages())
                @if (isset($is_livewire))
                    <button wire:click="nextPage" dusk="nextPage.before" class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
                        {!! __('pagination.next') !!}
                    </button>
                @else
                    <a href="{{ $paginator->nextPageUrl() }}" class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
                        {!! __('pagination.next') !!}
                    </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">
                    {!! __('pagination.next') !!}
                </span>
            @endif
        </div>

        <div class="px-5 py-5 bg-white flex flex-col xs:flex-row items-center xs:justify-between">
            <div>
                <p class="text-xs xs:text-sm text-gray-900">{!! __('Showing') !!} <span class="font-medium">{{ $paginator->firstItem() }}</span> {!! __('to') !!} <span class="font-medium">{{ $paginator->lastItem() }}</span> {!! __('of') !!} <span></span><span class="font-medium">{{ $paginator->total() }}</span> {!! __('results') !!}</p>
            </div>

            <div class="inline-flex mt-2 xs:mt-0">
                <span class="relative z-0 inline-flex shadow-sm rounded-md">
                    {{-- Previous Page Link --}}
                    @if ($paginator->onFirstPage())
                        <span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
                            <span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5" aria-hidden="true">
                                <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
                                </svg>
                            </span>
                        </span>
                    @else
                        @if (isset($is_livewire))
                            <button wire:click="previousPage" dusk="previousPage.after" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
                                <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
                                </svg>
                            </button>
                        @else
                            <a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
                                <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
                                </svg>
                            </a>
                        @endif
                    @endif

                    {{-- Pagination Elements --}}
                    @foreach ($elements as $element)
                        {{-- "Three Dots" Separator --}}
                        @if (is_string($element))
                            <span aria-disabled="true">
                                <span 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 cursor-default leading-5">{{ $element }}</span>
                            </span>
                        @endif

                        {{-- Array Of Links --}}
                        @if (is_array($element))
                            @foreach ($element as $page => $url)
                                @if ($page == $paginator->currentPage())
                                    <span aria-current="page">
                                        <span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5">{{ $page }}</span>
                                    </span>
                                @else
                                    @if (isset($is_livewire))
                                        <button wire:click="gotoPage({{ $page }})" 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 }}
                                        </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

                    {{-- Next Page Link --}}
                    @if ($paginator->hasMorePages())
                        @if (isset($is_livewire))
                            <button wire:click="nextPage" dusk="nextPage.after" rel="next" class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
                                <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
                                </svg>
                            </button>
                        @else
                            <a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
                                <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
                                </svg>
                            </a>
                        @endif
                    @else
                        <span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
                            <span class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5" aria-hidden="true">
                                <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                                    <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
                                </svg>
                            </span>
                        </span>
                    @endif
                </span>
            </div>
        </div>
    </nav>
@endif
Enter fullscreen mode Exit fullscreen mode
  • 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.
php artisan make:component CustomisedModal
Enter fullscreen mode Exit fullscreen mode
  • It will create two files: /app/View/Components/CustomisedModal.php and /resources/views/components/customised-modal.blade.php. In resources/views/components/customised-modal.blade.php add code:
<div class="fixed z-100 w-full h-full bg-gray-500 opacity-75 top-0 left-0"></div>
<div class="fixed z-101 w-full h-full top-0 left-0 overflow-y-auto">
    <div class="table w-full h-full py-6">
        <div class="table-cell text-center align-middle">
            <div class="w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                <div class="bg-white rounded-lg text-left overflow-hidden shadow-xl">
                    {{ $content }}
                </div>
            </div>
        </div>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

If we will open /app/View/Components/CustomisedModal.php file we will see code

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class CompanyItem extends Component
{
    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\Contracts\View\View|string
     */
    public function render()
    {
        return view('components.customised-modal');
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Now we can call this component by using tags (tag name x- and name of view)
<x-customised-modal>...</x-customised-modal>
Enter fullscreen mode Exit fullscreen mode
  • 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>
Enter fullscreen mode Exit fullscreen mode
  • In general our /resources/views/livewire/companies.blade.php file should look like:
<x-slot name="header">
    <h2 class="font-semibold text-xl text-gray-800 leading-tight">
        {{ __('Companies') }}
    </h2>
</x-slot>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    @if (session()->has('message'))
        <div id="alert" class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-green-500">
            <span class="inline-block align-middle mr-8">
                {{ session('message') }}
            </span>
            <button class="absolute bg-transparent text-2xl font-semibold leading-none right-0 top-0 mt-4 mr-6 outline-none focus:outline-none" onclick="document.getElementById('alert').remove();">
                <span>×</span>
            </button>
        </div>
    @endif
    <button wire:click="create()" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mt-10">Create New Company</button>
    @if (count($companies)>0)
        <div class="py-10">
            <div class="inline-block min-w-full shadow rounded-lg overflow-hidden">
                <table class="min-w-full leading-normal">
                    <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
                                class="px-5 py-3 border-b-2 border-black bg-black text-left text-xs font-semibold text-white uppercase tracking-wider">
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach($companies as $company) 
                            <tr>
                                <td class="px-5 py-5 bg-white text-sm @if (!$loop->last) border-gray-200 border-b @endif">
                                    {{ Str::limit($company->title, 25) }}
                                </td>
                                <td class="px-5 py-5 bg-white text-sm @if (!$loop->last) border-gray-200 border-b @endif text-right">
                                    <div class="inline-block whitespace-no-wrap">
                                        <button wire:click="edit({{ $company->id }})" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Edit</button>
                                        <button wire:click="$emit('triggerDelete',{{ $company->id }})" class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">Delete</button>
                                    </div>
                                </td>
                            </tr>
                        @endforeach
                    </tbody>
                </table>
                {{ $companies->links('pagination',['is_livewire' => true]) }}
            </div>
        </div>
    @endif
    @if($isOpen)
        <x-customised-modal>
            <x-slot name="content">
                <form>
                    <div class="px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
                        <div class="flex flex-wrap -mx-3 mb-6">
                            <div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
                                <label for="titleInput" class="block text-gray-700 text-sm font-bold mb-2">Title:</label>
                                <input type="text" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="titleInput" placeholder="Enter Title" wire:model="title">
                                @error('title') <span class="text-red-500">{{ $message }}</span>@enderror
                            </div>
                        </div>
                    </div>
                    <div class="px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
                        <span class="flex w-full sm:ml-3 sm:w-auto">
                            <button wire:click.prevent="store()" type="button" class="inline-flex bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Save</button>
                        </span>
                        <span class="mt-3 flex w-full sm:mt-0 sm:w-auto">
                            <button wire:click="closeModal()" type="button" class="inline-flex bg-white hover:bg-gray-200 border border-gray-300 text-gray-500 font-bold py-2 px-4 rounded">Cancel</button>
                        </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 () {

        @this.on('triggerDelete', companyId => {
            Swal.fire({
                title: 'Are You Sure?',
                text: 'Company record will be deleted!',
                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
Enter fullscreen mode Exit fullscreen mode

Top comments (14)

Collapse
 
schrijvers123 profile image
Arjen Schrijvers

Nice tutorial, two issues:

  1. Delete is not working. When clicking nothing is happening.
  2. Adding a new company shows the model, woth two fields: #No and #company. Filling in the #No field results in an error: Property [$no] not found on component: [companies]. What is the meaning of this field?
Collapse
 
dariusdauskurdis profile image
Darius Dauskurdis

And about deleting problem.
Your javascript and style code has to be between tags:
@push('scripts') and @endpush
@push('styles') ... @endpush
Please check my previous tutorial:
dev.to/dariusdauskurdis/laravel-8-...

Collapse
 
dariusdauskurdis profile image
Darius Dauskurdis

Thank you for your comment. I wanted to make this CRUD smaller as possible, with less fields. This field "NO" is not necessary, I forgot to remove from my example.

Collapse
 
schrijvers123 profile image
Arjen Schrijvers • Edited

github.com/Schrijvers123/crud can de code be found as far a I have it (with the error described above).

Collapse
 
patake profile image
patake

About the delete function that was not working, on app.blade.php file, we have to put @stack('scripts') tag after the @livewireScripts tag.
Check the source code of the page for the changes and the code for delete have to be after the Livewire javascript code.

Collapse
 
alamriku profile image
alamriku

This will reset all public props.

$this->reset();
Enter fullscreen mode Exit fullscreen mode

initializing-properties

Collapse
 
hominini profile image
Byron Pérez • Edited

Thanks for the tutorial, I have followed the two parts, Delete button not working, I don't know if something is wrong with the javascript code, but I see in the console, can you think about what is causing the issue?
Thanks anyway.

Error message:
index.js:31 Uncaught TypeError: Cannot read property '$wire' of undefined
at Livewire.value (index.js:31)
at HTMLDocument. (companies:438)
value @ index.js:31
(anonymous) @ companies:438

Collapse
 
smallkan profile image
Jhol H Winchester

@if (count($companies)>0) ?

@if ($companies)

Collapse
 
dariusdauskurdis profile image
Darius Dauskurdis

In my case will not work, because "@if ($companies)" means if variable $companies is not null, but my is not null, it is empty.

Collapse
 
sammymwangangi profile image
Sammy Mwangangi

I am looking for one with 1-M relationships. It seems there are no tuts for such. Anyone who cares to share such tutorial, e.g. one that inlcudes selection field in the form.

Collapse
 
szabeh profile image
Mohammad sadegh Zabeh Jamshidi

Thanks, Can you share source code?

Collapse
 
dariusdauskurdis profile image
Darius Dauskurdis

Mr. Arjen Schrijvers has good example for you github.com/Schrijvers123/crud
But in general you need to follow Laravel documentation how to install Laravel and then follow my steps how to create CRUD, just copy and paste code in few files.

Collapse
 
charlink1 profile image
Charlink

Someday I try to upload several images and dont work like the oficial documentación say

Collapse
 
dariusdauskurdis profile image
Darius Dauskurdis

Do you mean upload image in CRUD?