gsferro / select2easy
Uso global e generico do plugin select2 ajax utilizando o laravel
README
Pacotes Dependências:
Instalação
-
Instalar o pacote via Composer:
composer require gsferro/select2easy -W
-
Publicar o pacote:
php artisan vendor:publish --provider="Gsferro\Select2Easy\Providers\Select2EasyServiceProvider" --force
Configuração
-
Diretrivas blade, Coloque as no seu arquivo de layout
- No final do header:
@select2easyCss()
- No final do body:
@select2easyCss()
- No final do header:
-
Caso utilize framework
bootstrap 5
, adicione no header abaixo do@select2easyCss()
:@select2easyThemeBootstrap5()
-
Mude ou na instancia do plugin ou diretamente no
public/vendor/select2easy/js/select2easy.js
:$('#exemple').select2easy({ theme: 'bootstrap-5', });
- Ou vc pode utilizar o
@select2easyOptionsJs()
para configurar o plugin para usar otheme
e também já deixara utilizando viamodal
ou outroparent
, basta adicionar antesselect2easyJs()
- Ou vc pode utilizar o
-
É necesário fazer um ajuste no css para quando o select2 estiver
disabled
e no tamanho doinput
@select2easyThemeBootstrap5Disabled()
-
Caso queira implementar um css avançado no
theme
, adicione:@select2easyThemeBootstrap5Advance()
-
É necessário ajustar o css para funcionar com as cores do
validate
:/* ajustando select2 validado: is-invalid */ .is-invalid+.select2-container--bootstrap-5 .select2-selection, .was-validated select:invalid+.select2-container--bootstrap-5 .select2-selection { border-color: var(--falcon-form-invalid-border-color) !important; } /* ajustando select2 validado: is-valid */ .is-valid+.select2-container--bootstrap-5 .select2-selection, .was-validated select:valid+.select2-container--bootstrap-5 .select2-selection { border-color: var(--falcon-form-valid-border-color) !important; }
-
-
Caso você queira aplicar a instância do plugin
select2
em todas as tagsselect
, adicione apósselect2easyJs()
:@select2easyApplyAnyJs()
Implementação
-
Você pode implementar quantos metodos quiser, para chamar a modelo em varias ocaciões dentro do projeto
- Ex: Model User
sl2Nome
: usando o nome como buscasl2Email
: usando o nome como buscasl2Login
: usando o nome como login
-
Implemente na model a trait Select2Easy
-
Crie uma stact function
Sl2<NomeMetodo>
que sera chamado na implementação emdata-sl2_method
ou{ sl2_method : ""}
-
Na View:
- no select coloque a class select2Easy (required)
- coloque o attributo data-sl2_method = "nomeDoMetodoEstaticoDaModel"
- coloque o attributo data-sl2_model = 'caminho\para\Model'
- ou coloque o attributo data-sl2_hash = "{{ Crypt::encryptString('caminho\para\Model') }}"
- Exemplo:
<label for="select2easy">Select2 Easy:</label> <select id="select2easy" name="select2easy" class="form-control select2easy" data-sl2_method="sl2" data-sl2_hash="{{ Crypt::encryptString('App\Models\Teams') }}" <!-- recommend --> <!-- ou --> data-sl2_model="App\Models\Teams" data-minimumInputLength=2 data-delay=1000 > </select>
-
Instancie o plugin no select2easy
<script type="text/javascript"> $( function() { $( '#select2easy' ).select2easy( { // select2 // minimumInputLength : 2 , // ajax // delay : 1000 , // select2eay server side // sl2_method : 'string Method' , // sl2_hash : 'Crypt::encryptString('App\Models\Teams')' , // recommend // ou // sl2_model : 'App\Models\Teams' , } ); } ) </script>
-
Model
- Import usando:
use Gsferro\Select2Easy\Http\Traits\Select2Easy
- Coloque a trait
Select2Easy
- crie o
nomeDoMetodoEstaticoDaModel
passando o term e page
- Exemplo:
<?php use Gsferro\Select2Easy\Http\Traits\Select2Easy class Teams extends Model { use Select2Easy; public static function sl2Name(string $term, int $page, string $parentId = null ) // nome usado na view { /* |--------------------------------------------------- | Required |--------------------------------------------------- | | $select2Search - colum from search | $select2Text - colum from write selectbox | */ $select2Search = [ "name", // with relation 'relation.title' ]; // required $select2Text = "name"; /* |--------------------------------------------------- | Optional exemple |--------------------------------------------------- | | $limitPage - limit view selectbox, default 6 | $extraScopes - array with scopes | $prefix - prefix for after $select2Text | $scopeParentAndId - array with scope parent and id | */ $limitPage = 10; // default 6 $extraScopes = ["active"] // scope previously declared $prefix = 'otherRelation.description'; // or other column $scopeParentAndId = [ 'scope' => $parentId, ]; $suffix = 'otherRelation.description'; // or other column return self::select2easy( $term, $page, $select2Search, $select2Text, $limitPage = 6, $extraScopes = [], $prefix = null, $scopeParentAndId, $suffix = null, ); } }
- Import usando:
Cascade (select2 parents/dependent)
Tem momentos que é necessário que um select seja dependente de outro para poder exibir os dados pré filtrados, por
exemplo Estado > Cidades
. Para tal, basta colocar o atributo data-sl2_child
no select2 pai
(parent) o
id
do select2 dofilho
(child):
-
Exemplo:
<select id="parent" ... data-sl2_child="#children" > </select>
-
Na model: É necessário ter o scope do
pai
e ser inicializado o array$scopeParentAndId
contendo como chave o scope e o value o paramentro$parentId
, e passar para oself::select2easy
, exemplo:public static function sl2Name(string $term, int $page, string $parentId) { $select2Search = [ "name", ]; $select2Text = "name"; $scopeParentAndId = [ 'parent' => $parentId, ]; return self::select2easy( $term, $page, $select2Search, $select2Text, $limitPage = 6, $extraScopes = [], $prefix = null, $scopeParentAndId, $suffix = null, ); }
-
Caso vc esteja usando as versões do
php
>8, pode utilizar oNamed Arguments
:public static function sl2Name(string $term, int $page, string $parentId) { $select2Search = [ "name", ]; $select2Text = "name"; $scopeParentAndId = [ 'parent' => $parentId, ]; return self::select2easy( term: $term, page: $page, select2Search: $select2Search, select2Text: $select2Text, scopeParentAndId: $scopeParentAndId ); }
-
Inspirado neste javascript select2-cascade.js
-
Prefixos e Sufixos (pode ser um relacionamento ou coluna)
- Prefixo: adicionado antes do texto do select2
- Sufixo: adicionado depois do texto do select2
Use Templating (Markups)
-
O pacote
select2easy
esta preparado para utilizar o recurso deTemplating
, que permite formatar o título (text
) e o html exibido no pluginselect2
. -
Para isso, basta criar na model os metodos tanto para o
text
quanto para ohtml
, e o plugin fará o resto. -
O
text
é o que sera exibido no select apos a escolha e ohtml
é o que sera exibido quando abre a busca de seleção ao retorno noajax
. -
Você também pode utilizar separadamente tanto o
text
quantohtml
, basta passar para o array$markups
o item desejado. -
Cada método receberá 2 parametros no momento de ser invocado pelo pacote:
string $text
eModel $model
, sendo a instancia da a propria model ($this
) utilizada, e estes metodos devem retornar ohtml
que sera rendereziado.-
Exemplo de uso:
public static function sl2Name(string $term, int $page, string $parentId) { $select2Search = [ "name", ]; $select2Text = "name"; $markups = [ 'text' => 'sl2MarkupText', 'html' => 'sl2MarkupHtml', ]; return self::select2easy( term: $term, page: $page, select2Search: $select2Search, select2Text: $select2Text, markups: $markups ); }
-
Exemplo de metodo para o
html
:# Pode ser usando assim: return string private function sl2MarkupHtml(string $text, Country $model): string { return '<span class="select2-selection__rendered" id="select2_country-container" role="textbox" aria-readonly="true" title="'.$text.'"> <span> <img src="'.$model->image.'" class="rounded-circle" alt="image"> '.$model->name.' </span> </span>'; }
-
Exemplo de metodo para o
text
:# Ou, pode ser usando assim: return view renderizada private function sl2MarkupText(string $text, Country $model): string { return view('country', [ 'text' => $text, 'model' => $model ])->render(); }
-
Como você pode ter multiplos metodos para usar o
select2easy
na model, você pode utilizar varios tipos de formatação, conforme a necessidade ou fazer reusos de metodos e views.
-
Selected
-
Links do plugin
-
melhor opção:
<select id="select2easy" name="select2easy" class="form-control select2easy" data-sl2_method="sl2" data-sl2_hash="{{ Crypt::encryptString('App\Models\Teams') }}" <!-- recommend --> > <option value="{{ $model->teams_id }}" selected>{{ \App\Models\Teams::find($model->teams_id)->name }}</option> <!-- ou usar via relacionamento (se não for 1xN ou NxN --> <option value="{{ $model->teams->id }}" selected>{{ $model->teams->name }}</option> <!-- prefix --> <option value="{{ $model->teams->id }}" selected>{{ $model->teams->id }} - {{ $model->teams->name }}</option> </select>
Para Laravel > 7
Como a ideia, pelo menos nas versões v1.*
do pacote, é manter a compatiblidade com todas as versões do Laravel
,
desde a L5
até a atual L11
, não esta disponivel um component, mas fica aqui uma sugestão e possivel
disponibilzação para as proximas versões de um component completamente funcional (baseado no bootstrap 5
):
-
Crie, caso não exista:
resources/views/components/forms/label.blade.php
@props([ 'label', 'isRequired' => false, ]) <label {{ $attributes->merge([ 'class' => 'form-label' ])->whereDoesntStartWith('label') }}> {{ $label }} {{ $isRequired ? '*' : '' }} </label>
-
Crie:
resources/views/components/select2/easy.blade.php
@props([ 'name', 'groupClass', 'appModel', 'col' => 12, 'colMd' => 4, 'id' => null, 'sl2' => 'sl2Name', 'label' => null, ]) @section('vendor-styles') @once @select2easyCss() <link href="{{ asset('vendor/select2easy/select2/css/select2-bootstrap.css') }}" rel='stylesheet' type='text/css'> @endonce @endsection @php $id = $id ?? $name; @endphp <div class="col-{{ $col }} col-md-{{ $colMd }} {{ $groupClass ?? '' }}"> @if($label) <x-forms.label for="{{ $id }}" class="{{ $labelClass ?? '' }}" :label="$label" :isRequired="$attributes->offsetExists('required')" /> @endif <select name="{{ $name }}" id="{{ $id }}" data-sl2_method="{{ $sl2 }}" data-sl2_hash="{{ Crypt::encryptString($appModel) }}" {{ $attributes ->merge(['class' => 'form-control select2easy']) ->whereDoesntStartWith('col') }} > {{ $slot }} </select> </div> @push('js') <script type="text/javascript"> $(() => { $('#{{$id}}').select2easy({ theme: 'bootstrap-5', }); }); </script> @endpush
- Ou publique o component
-
Recomendo criar novos components encapsulando-o, Exemplo de uso:
resources/views/components/select2/category.blade.php
@props([ 'col', 'sl2' => null, 'value' => null, 'name' => null, 'useRequest' => null, ]) @php $name = $name ?? 'category_id'; $value = isset($useRequest) ? app('request')->input($name) : $value; $appModel = '\App\Models\Category'; @endphp <x-select2.easy :col="$col ?? '12'" :col-md="$colMd ?? '4'" label="Categoria" :name="$name" :sl2="$sl2" :app-model="$appModel" {{ $attributes }} > @if (!empty($value)) <option value="{{ $value }}"> {{ $appModel::find($value)->name }} </option> @endif </x-select2.easy>
- No formulário:
# usando request para pegar o value (filtro e etc) <x-select2.category useRequest data-sl2_child="#subcategory_id"/> # no form de create/edit <x-select2.category :value="old('category_id', $model->category_id)" data-sl2_child="#subcategory_id" required />
Troubleshooting
-
Erro: "Select2easy não está funcionando":
- Verifique se o pacote está instalado corretamente
- Verifique se o arquivo de layout está configurado corretamente
-
Erro: "Select2easy não está aparecendo"
- Verifique se o select2easy está sendo chamado corretamente
- Verifique se o tema está configurado corretamente
- Verifique se a model esta configurado corretamente
- Verifique se o html esta corretamente implementado
License
Laravel Localization is an open-sourced laravel package licensed under the MIT license.