Giter VIP home page Giter VIP logo

laravel-simple-select's Introduction

Laravel Simple Select

Laravel Simple Select inputs component for Blade and Livewire.

Latest Version on Packagist Total Downloads GitHub Actions

DEMO PREVIEW

preview

Table of Contents


Installation

You can install the package via composer:

composer require victorybiz/laravel-simple-select

OPTIONAL: To customize the component, you should publish the configuration file using the vendor:publish Artisan command. The configuration file will be placed in your application's config directory and view file in views directory respectively:

# Publish the config file
php artisan vendor:publish --tag=simple-select:config
# Publish the view file
php artisan vendor:publish --tag=simple-select:views

Requirements

This package use the following packages.

Please make sure you include these dependencies before using this component.

JavaScript Dependencies

For any external JavaScript dependency, we recommend you install them through npm or yarn, and then require them in your project's JavaScript. To install each of the dependencies this package makes use of, run this command in the terminal:

npm install -D alpinejs @popperjs/core
import Alpine from 'alpinejs'
import { createPopper } from "@popperjs/core";

window.Alpine = Alpine;
Alpine.start()

window.createPopper = createPopper;

If you’re using the compiled JavaScript, don’t forget to include CDN versions of the JavaScript Dependencies before it.

Usage

Simple Select

@php
// Basic Arrays
$options = ['Nigeria', 'United Kingdom', 'United States'];
// Above will output Option Value e.g Nigeria 
// Above will output Option Text e.g Nigeria

// OR

// Associative Arrays
$options = [
  ['value' => 'NG', 'text' => 'Nigeria'],
  ['value' => 'GB', 'text' => 'United Kingdom'],
  ['value' => 'US', 'text' => 'United States']
];
// Above will output Option Value e.g NG 
// Above will output Option Text e.g Nigeria

// OR

// Using Associative Arrays data from a Model/Database,
// ensure to customize the field names with value-field="code" and text-field="name" properties of the component.
$options = [
  ['code' => 'NG', 'name' => 'Nigeria'],
  ['code' => 'GB', 'name' => 'United Kingdom'],
  ['code' => 'US', 'name' => 'United States']
];
// OR
$options = [
  ['code' => 'NG', 'name' => 'Nigeria', 'flag' => 'https://www.countryflags.io/ng/shiny/32.png'],
  ['code' => 'GB', 'name' => 'United Kingdom', 'flag' => 'https://www.countryflags.io/gb/shiny/32.png'],
  ['code' => 'US', 'name' => 'United States', 'flag' => 'https://www.countryflags.io/us/shiny/32.png']
];
// Above will output Option Value e.g NG 
// Above will output Option Text e.g Nigeria

@endphp
<x-simple-select       
    name="country"
    id="country"
    :options="$options"
    value-field='code'
    text-field='name'
    placeholder="Select Country"
    search-input-placeholder="Search Country"
    :searchable="true"                                               
    class="form-select"     
/>

Custom Option Slot

<x-simple-select       
    name="country"
    id="country"
    :options="$options"
    value-field='code'
    text-field='name'
    placeholder="Select Country"
    search-input-placeholder="Search Country"
    :searchable="true"                                               
    class="form-select"     
>
  <x-slot name="customOption">
    <img class="float-left mr-2 -mt-1" :src="option.flag">
    <span x-text="option.name"></span>
  </x-slot>
</x-simple-select>

<x-simple-select       
    name="country"
    id="country"
    :options="$options"
    value-field='code'
    text-field='name'
    placeholder="Select Country"
    search-input-placeholder="Search Country"
    :searchable="true"                                               
    class="form-select"     
>
  <x-slot name="customOption">
    <img class="float-left mr-2 -mt-1" :src="`https://www.countryflags.io/${option.code?.toLowerCase()}/shiny/32.png`">
    <span x-text="option.name"></span>
  </x-slot>
</x-simple-select>

Custom Selected Slot

<x-simple-select       
    name="country"
    id="country"
    :options="$options"
    value-field='code'
    text-field='name'
    placeholder="Select Country"
    search-input-placeholder="Search Country"
    :searchable="true"                                               
    class="form-select"     
>
  <x-slot name="customSelected">
    <img class="float-left mr-2" :src="`https://www.countryflags.io/${option.code?.toLowerCase()}/shiny/24.png`">
    <span x-text="option.name"></span>
  </x-slot>
  <x-slot name="customOption">
    <img class="float-left mr-2 -mt-1" :src="`https://www.countryflags.io/${option.code?.toLowerCase()}/shiny/32.png`">
    <span x-text="option.name"></span>
  </x-slot>
</x-simple-select>

Custom Icon Slots

<x-simple-select       
    name="country"
    id="country"
    :options="$options"
    value-field='code'
    text-field='name'
    placeholder="Select Country"
    search-input-placeholder="Search Country"
    :searchable="true"                                               
    class="form-select"     
>
  <x-slot name="customOption">
    <img class="float-left mr-2 -mt-1" :src="option.flag">
    <span x-text="option.name"></span>
  </x-slot>
  <x-slot name="customDeselectOptionIcon">
    <!-- Heroicon solid/x-circle -->
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class = 'h-4 fill-current'>
      <path d="M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm6 16.538l-4.592-4.548 4.546-4.587-1.416-1.403-4.545 4.589-4.588-4.543-1.405 1.405 4.593 4.552-4.547 4.592 1.405 1.405 4.555-4.596 4.591 4.55 1.403-1.416z"/>
    </svg>
  </x-slot>
</x-simple-select>

Dependent Selects

If you have a custom select whose options depend on the selection of another select, or just some kind of condition to be met, you can listen to the updated event of the livewire model of the main select to update the options in the dependent select.

// Expected data in Database
// Model Country::class 
$countries = [
  ['code' => 'NG', 'name' => 'Nigeria'],
  ['code' => 'GB', 'name' => 'United Kingdom'],
  ['code' => 'US', 'name' => 'United States']
];
// Model State::class
$states = [
  ['id' => 1, 'country_code' => 'NG', 'name' => 'Abuja'],
  ['id' => 2, 'country_code' => 'NG', 'name' => 'Edo'],
  ['id' => 3, 'country_code' => 'NG', 'name' => 'Lagos'],
  ['id' => 4, 'country_code' => 'US', 'name' => 'Alaska'],
  ['id' => 5, 'country_code' => 'US', 'name' => 'Califonia'],
  ['id' => 6, 'country_code' => 'US', 'name' => 'Florida'],
  ['id' => 7, 'country_code' => 'GB', 'name' => 'Belfast'],
  ['id' => 8, 'country_code' => 'GB', 'name' => 'London'],
  // ...
];

Create a livewire component as the form page

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class CreateUser extends Component
{
    public $countries = [];
    public $states = [];

    public $name;
    public $country;
    public $state;

    protected function rules()
    {
        // 
    }

    public function updated($propertyName)
    {
        $this->validateOnly($propertyName);
    }

    public function store()
    {
        $this->validate();
        // Store the data
    }

    public function mount()
    {
        $this->countries = \App\Models\Country::orderBy('name')->get()->toArray();             
    }

    public function updatedCountry($countryCode)
    {   
        if ($countryCode) {
            $this->states = \App\Models\State::where('country_code', $countryCode)->orderBy('name')->get()->toArray();  
        } else {
            $this->states = [];            
        }   
        $this->state = null;
    }

    public function render()
    {
        return view('livewire.create-user');
    }
}

In your component view

 <form wire:submit.prevent="store">

  <label for="name">Name</label>
  <div class="mt-1">
    <input       
        wire:model="name"
        name="name"
        id="name"
        placeholder="Enter name"                                            
        class="form-input"     
    />
  </div>

  <label for="country">Country</label>
  <div class="mt-1">
    <x-simple-select       
        wire:model="country"
        name="country"
        id="country"
        :options="$options"
        value-field='code'
        text-field='name'
        placeholder="Select Country"
        search-input-placeholder="Search Country"
        :searchable="true"                                               
        class="form-select"     
    />
  </div>

  <label for="state">State</label>
  <div class="mt-1">
    <x-simple-select       
        wire:model="state"
        name="state"
        id="state"
        :options="$states"
        value-field='id'
        text-field='name'
        placeholder="Select State"
        search-input-placeholder="Search State"
        :searchable="true"                       
        class="form-select"
    />
  </div>
</form>

Event Listener

window.addEventListener('select', function(option) {
    console.log(option.detail.value); // Select option value(s)
    console.log(option.detail.name); // The select element name
    console.log(option.detail.id); // The select element ID
});

Positioning

The simple-select component makes use of Popper.js for positioning the select menu. This should remove the need for fixed positioning the select menu now. In addition to positioning the menu when opened, Popper.js will also re-position the menu as needed when the page is scrolled.

Props / Attributes

Name Type Default Required Description
id Integer||String Yes Used to identify the component in events.
name Integer||String Yes Specifies a name for component.
options Array Yes Array of available options: Objects, Strings or Integers. If array of objects, visible text/label will default to option.text and value default to option.value.
value-field String 'value' No Array key for option value if options is an associative array.
text-field String 'text' No Array key for option text if options is an associative array.
value Array||String||Integer null No Presets the selected options.
placeholder String 'Select Option' No Equivalent to the placeholder attribute on a <select> input.
searchable Boolean true No Show / hide options search input.
search-input-placeholder String 'Search...' No Equivalent to the placeholder attribute on a <input>.
clearable Boolean false No Enable support for clearable selection. Use only for a non multiple select.
class String No Equivalent to the class attribute on a <select> input.
multiple Boolean false No Equivalent to the multiple attribute on a <select> input. This also enable multiple options tagging if set.
max-selection Integer No Limit number of allowed selected options.
required Boolean false No Equivalent to the required attribute on a <select> input.
disabled Boolean false No Equivalent to the disabled attribute on a <select> input.
no-options String 'No option data.' No Message to show when options list is empty.
no-result String 'No results match your search.' No Message to show when no option.
on-select String 'select' No Customize event name of an event emitted after selecting an option.

Slots / Custom Display

Name Description
customOption Slot for custom option text template. See example above.
customSelected Slot for custom selected template. See example above.
customDeselectOptionIcon Slot for custom deselect option icon markup. See example above.
customCaretDownIcon Slot for custom caret down icon markup. See example above.
customCaretUpIcon Slot for custom caret up icon markup. See example above.

Events

Name Listen to Description
Select select Emitted after selecting an option. See example above.

Testing

composer test

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.

Laravel Package Boilerplate

This package was generated using the Laravel Package Boilerplate.

laravel-simple-select's People

Contributors

dcblogdev avatar laravel-shift avatar victorybiz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

laravel-simple-select's Issues

How do I use the attribute "value"?

I'm trying to use the select on my edit page, so far I manage to use multiple by passing an array of id to value.

controller.php

public function getSelected($role)
{
    $permissions = $role->permissions()->pluck('id');
    $array = [];

    foreach ($permissions as $value) {
        $array[] = $value;
    }

    return $array;
}

edit.blade.php

<x-simple-select
    name="permissions[]"
    id="permissions"
    multiple="multiple"
    :options="$permissions"
    value-field='id'
    text-field='name'
    :value="$selected"
    placeholder="Permissions"
    search-input-placeholder="Select Permissions..."
    :searchable="true"
/>

But the above code won't work in normal select, I try passing the id or the name directly but nothing would show.

<x-simple-select
    name="province"
    id="province"
    :options="$provinces"
    value-field='id'
    text-field='name'
    :value="$municipality->province_id"
    placeholder="Province"
    search-input-placeholder="Select Province..."
    :searchable="true"
/>

I'm still new to TALL so I don't understand anything when I read your code, wish you could help.

show selected element

How do you show a standard selected value?

I have this usage:

<label>Supplier {{ $supplierId }}</label><br>
<x-simple-select name="supplierId" id="supplierId" wire:model="supplierId" :options="$suppliers" value-field='id' text-field='name' class="form-select" />

In my class I have mounted supplierId to an id I can see this if I render {{ $supplierId }} to the blade but the select does not pre-select the entry on load. The select menu remains blank until I manually select an item in the menu.

Screenshot 2021-09-27 at 10 10 01

Double dropdown arrow: how to fix?

In a fresh Laravel 10 project, using TALL (including Tailwind), all Laravel-simple-select show a double dropdown arrow on the right.
Does anybody know how to fix this? Thanks.

Simple-Select

Uncaught (in promise) TypeError: this.$dispatch is not a function

Hello! Trying to use simple select:

<div class="mt-1">
                    <x-simple-select wire:model="selectedCar" name="country" id="country" :options="$cars" value-field='id' text-field='vin' placeholder="Select Country" search-input-placeholder="Search Country" :searchable="true" class="form-select" />
                </div>

When selecting value it throws error:

Alpine Error: "TypeError: this.$dispatch is not a function"

Expression: "selectOption(getOptionValue(option, index))"

Strange thing is that selectedCar value gets updated in livewire and after that it throws error.

Limit result displayed

Is there a way to limit the result shown instead of all the records loaded to the component but when searched the record is shown in the container?

Is there a way to keep the select open?

I would like to keep the selectable options open (on multiple) to select many in a row without it closing itself after selecting one.
Is there an option I missed?

HTML in option text-field?

Is there a possibility to use HTML tags in the option text-field to highlight certain options?

Thanks.

Selection Issue

When Already selected Item is showing is [object Object]

This Only Occurs in Dependent Dropdowns Please Help

Please Check the Images
In This Have 2 Depended on One Each and 2 Completed Independent

image

@dcblogdev
@victorybiz

Simple Select: requires Popper

fresh install from laravel 10

then install livewire 3
and [laravel-simple-select] with JavaScript Dependencies

the console.log shows

Uncaught TypeError: Laravel Simple Select: requires Popper (https://popper.js.org)
    at Proxy.popper ((index):1174:25)
    at (index):1052:32

my app.js code

import "./bootstrap";
import Alpine from 'alpinejs'
import { createPopper } from "@popperjs/core";

window.Alpine = Alpine;
Alpine.start()

window.**_createPopper_** = createPopper;

vscode shows
Property 'createPopper' does not exist on type 'Window & typeof globalThis'

excuse me
how to solve it
thanks.

strange behavior duplicate items

I am using laravel-simple-select on a Laravel9 with Jetstream and I don't know why the select show me duplicates items:

image

When i do a search:

image

My code:

  public function render()
    {


        $options = [
            ['id' => '1', 'name' => 'Item1'],
            ['id' => '2', 'name' => 'Item2'],
            ['id' => '3', 'name' => 'Item3']
          ];
        return view('livewire.producto-form',[
            'subcategorias' => $options,
            //'subcategorias' => Subcategoria::pluck('nombre','id')->ToArray(),
        ]);
    }

view:

                    <div class="col-span-6">
                        <x-jet-label for="producto.items" value="Item Name" />
                        <x-simple-select
                        name="Items"
                        id="item"
                        :options="$subcategorias"
                        value-field='id'
                        text-field='name'
                        placeholder="Select Item"
                        search-input-placeholder="Select Item"
                        :searchable="true"
                        class="form-select"
                    />
                        <x-jet-input-error for="producto.item" />
                    </div>

event is not firirng

hi I am trying to update a text field based on select option but the event is not firing

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.