A laravel Livewire Dynamic Selects with multiple selects depending on each other values, with infinite levels and totally configurable.

Overview

Package Logo

Latest Version on Packagist StyleCI GitHub last commit

Livewire Combobox: A dynamic selects for Laravel Livewire

A Laravel Livewire multiple selects depending on each other values, with infinite levels of dependency and totally configurable.

Requirements

This package need at least:

  • PHP ^8.0
  • Laravel ^8.0
  • Laravel Livewire ^2.0
  • TailwindCSS ^2.0

Installation

You can install the package via composer:

composer require daguilarm/livewire-combobox

Add the package styles in the <head> using the helper @LivewireComboboxCss:

<html>
    <head>
        @LivewireComboboxCss
    </head>
    <body>
        ...
    </body>
</html>

Documentation

General Methods

The first thing you have to do is create a component in your folder Livewire. Below you can see an example using three selects:

<?php

declare(strict_types=1);

namespace App\Http\Livewire;

use App\Models\Car;
use App\Models\Extra;
use App\Models\Option;
use Daguilarm\LivewireCombobox\Components\ComboboxLivewireComponent;
use Daguilarm\LivewireCombobox\Components\Fields\Select;
use Daguilarm\LivewireCombobox\Contracts\Combobox;

class ComboboxCars extends ComboboxLivewireComponent implements Combobox
{
    public function elements(): array
    {
        return [
            Select::make('Cars', Car::class)
                ->uriKey('key-for-car')
                ->options(function($model) {
                    return $model
                        ->pluck('name', 'id')
                        ->toArray();
                }),
            Select::make('Options for cars', Option::class)
                ->uriKey('key-for-options')
                ->dependOn('key-for-car')
                ->foreignKey('car_id')
                ->selectRows('id', 'option'),
            Select::make('Extras for cars')
                ->model(Extra::class)
                ->firstRemoved()
                ->hideOnEmpty()
                ->uriKey('key-for-extras')
                ->dependOn('key-for-options')
                ->foreignKey('option_id')
                ->selectRows('id', 'extra')
                ->withoutResponse(),
        ];
    }
}

The package supports infinite dependent elements. The method elements() should return an array with all the elements.

Let's see how the class works Select::class and its methods:

make()

The method make(), has the following structure:

Select::make(string $label, ?string $model = null);

model()

As it can be seen, the attribute $model is optional in the make() method, and it can be added using the method model():

Select::make('My label')->model(User::class);

⚠️ Defining the model is mandatory, but it can be done in the two ways described.

uriKey()

This method is mandatory, it is used to define a unique key for the element.

hideOnEmpty()

Dependent children are removed if they are empty, instead of showing an empty field.

withoutResponse()

When we want an element does not send a response to the component and works only as a form field, that is, remove all the Laravel Livewire code from it. Very useful when it comes to the last selectable element and we don't want to send a request to the server.

Child elements

These elements have their own methods, apart from those described above. These child elements do not need the method options(), although it can be added if desired. The child specific methods are described below:

dependOn()

With this method we define the parent element on which our child element depends. We must use the uriKey from the parent element. The basic structure of the method is:

dependOn(?string $parentUriKey = null, ?string $foreignKey = null)

As can be seen, it admits a second value which is the foreing key that links the two models: Parent and Child.

foreignKey()

This second field can also be added in two ways:

// Option 1
Select::make(...)
    ->dependOn('key-for-options', 'option_id');

// Option 2
Select::make(...)
    ->dependOn('key-for-options')
    ->foreignKey('option_id');

selectRows()

It is used to select the fields from the table that we want to load in the child element.

disabledOnEmpty()

If you want to disabled the field while it is empty...

Field Types

At the moment, the package support the folowing field types:

Select field

These fields have the following methods:

options()

It is used to add the values ​​that will be shown in the element select. We can directly add an array with the values, or define a callback. The two values ​​returned by the array: key and value, are shown as follows in the Blade template:

// The array
[
    1 => 'Car',
    2 => 'Bike',
    3 => 'Plane'
]

//Will be render as 
<option value="1">Car</option>
<option value="2">Bike</option>
<option value="3">Plane</option>

Therefore, in the component example (will be reverse):

// The array
Select::make(...)
    ->options(function($model) {
        return $model
            ->pluck('name', 'id')
            ->toArray();
    })

//Will be render as 
<option value="id">name</option>

firstRemoved()

By default, each item will show a select field with an empty option element:

// Element
<select>
    <option value=""></option>
    ...
</select>

If you want to remove it, you can add the method firstRemoved().

Search field

comming soon...

Loading...

You can activate or deactivate the loading state, modifying the attribute $loading, in your component:

<?php

declare(strict_types=1);

namespace App\Http\Livewire;

use App\Models\Car;
use App\Models\Extra;
use App\Models\Option;
use Daguilarm\LivewireCombobox\Components\ComboboxLivewireComponent;
use Daguilarm\LivewireCombobox\Components\Fields\Select;
use Daguilarm\LivewireCombobox\Contracts\Combobox;

class ComboboxCars extends ComboboxLivewireComponent implements Combobox
{
    protected bool $loading = false;

    public function elements(): array
    {
        return [];
    }
}

By default it is activated (true). The template file is located at: resources/views/vendor/livewire-combobox/loading.blade.php.

Customize the display of elements

The package uses TailwindCSS so the styles must be based on it. The structure of the elements is as follows:

<!-- Main container -->
<div id="container">

    <!-- Element 1 -->
    <div id="element-container-1">
        <label id="label-1"></label>
        <select id="select-1"></select>
    </div>

    <!-- Element 2 -->
    <div id="element-container-2">
        <label id="label-2"></label>
        <select id="select-2"></select>
    </div>

</div>

We can modify the styles of the Main Container from the component that we created at the beginning of the documentation, using the $comboboxContainerClass:

<?php

declare(strict_types=1);

namespace App\Http\Livewire;

use App\Models\Car;
use App\Models\Extra;
use App\Models\Option;
use Daguilarm\LivewireCombobox\Components\ComboboxLivewireComponent;
use Daguilarm\LivewireCombobox\Components\Fields\Select;
use Daguilarm\LivewireCombobox\Contracts\Combobox;

class ComboboxCars extends ComboboxLivewireComponent implements Combobox
{
    protected string $containerClass = 'flex p-2 m-2 bg-gray-100';

    public function elements(): array
    {
        return [];
    }
}

To modify an element, we will have to do it directly from each of them, using the method class():

Select::make('Cars', Car::class)
    ->uriKey('key-for-car')
    ->options(function($model) {
        return $model
            ->pluck('id', 'name')
            ->toArray();
    })
    ->class('p-4', 'text-green-600', 'text-lg'),

We can use the new functionality of php 8 to modify only those parts that interest us, or we can use the method directly:

// Method 1
Select::make(...)
    ->class(
        container: 'p-4',
        field: 'text-lg',
    ),

// Method 2
Select::make(...)
    ->class('p-4', null, 'text-lg'),

The order of the parameters is:

class(?string $container = null, ?string $label = null, ?string $field = null)

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Issues
Releases(v1.3)
Owner
Damián Aguilar
Damián Aguilar
Livewire Notifier is a simple notifications system with zero dependencies above TALL-stack

Livewire Notifier is a simple notifications system with zero dependencies above TALL-stack (Tailwind CSS, Alpine.JS, Laravel and Livewire).

CodeSPB 6 Jun 8, 2021
A laravel Livewire Dynamic Selects with multiple selects depending on each other values, with infinite levels and totally configurable.

Livewire Combobox: A dynamic selects for Laravel Livewire A Laravel Livewire multiple selects depending on each other values, with infinite levels of

Damián Aguilar 15 Jun 5, 2021
Auto generate routes for Laravel Livewire components

livewire-auto-routes Auto generate routes for Laravel Livewire Components. Requirements Livewire 2 Laravel 8 php 8 Installation composer require tanth

Tina Hammar 12 Jun 1, 2021
Laravel Livewire full page component routing.

Laravel Livewire Routes Laravel Livewire full page component routing. This package allows you to specify routes directly inside your full page Livewir

null 8 Jun 7, 2021
Dynamic Laravel Livewire Bootstrap 5 modals.

Laravel Livewire Modals Dynamic Laravel Livewire Bootstrap 5 modals. Requirements Bootstrap 5 Installation Require the package: composer require basti

null 11 Jun 10, 2021
Please see the Diglactic fork.

Update: 18 October 2020 There is now an official fork of Laravel Breadcrumbs: https://github.com/diglactic/laravel-breadcrumbs Blog post: https://news

Dave James Miller 2.4k Jun 17, 2021
Laravel Livewire form component with declarative Bootstrap 5 fields and buttons.

Laravel Livewire Forms Laravel Livewire form component with declarative Bootstrap 5 fields and buttons. Requirements Bootstrap 5 Installation composer

null 24 Jun 10, 2021
Laravel blade directives and php helpers for serverside rendered content, based on browser window size WITHOUT css

Laravel Window Size and Breakpoints Laravel blade directives and php helpers for server side rendered content, based on browser window size WITHOUT cs

Tina Hammar 5 May 24, 2021
Belich Tables: a datatable package for Laravel Livewire

Belich Tables is a Laravel package base on Livewire and AlpineJS that allows you to create scaffold datatables with search, column sort, filters, pagination, etc...

Damián Aguilar 5 Jun 4, 2021
An Eloquent Way To Filter Laravel Models And Their Relationships

Eloquent Filter An Eloquent way to filter Eloquent Models and their relationships Introduction Lets say we want to return a list of users filtered by

Eric Tucker 1.2k Jun 18, 2021
A sample application with a multistep form built with Livewire.

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

David Grzyb 5 Jun 2, 2021
Laravel Livewire Excel Upload with Progressbar

Laravel Livewire Excel Upload with Progressbar This is sample project, that explains how to import Excel files with progress bar Steps to run project

Prabakaran T 3 Apr 21, 2021
Laravel Stats Tracker

Laravel Stats Tracker Tracker gathers a lot of information from your requests to identify and store: Sessions Page Views (hits on routes) Users (logge

Antonio Carlos Ribeiro 2.6k Jun 13, 2021
Inertia.js Events for Laravel Dusk

Inertia.js Events for Laravel Dusk Requirements PHP 7.4+ Vue Laravel 8.0 and higher Support We proudly support the community by developing Laravel pac

Protone Media 9 Jun 14, 2021