gsferro/select2easy

使用 Laravel 的插件 select2 ajax 的全局和通用用法

v1.6.2 2024-09-02 23:07 UTC

This package is auto-updated.

Last update: 2024-09-03 15:59:25 UTC


README

select2easy

Latest Version Total Downloads License

依赖包

安装

  1. 通过 Composer 安装包

    composer require gsferro/select2easy -W
  2. 发布包

    php artisan vendor:publish --provider="Gsferro\Select2Easy\Providers\Select2EasyServiceProvider" --force
    

配置

  • Blade 指令,将其放在布局文件中

    • 在头部末尾
      @select2easyCss()
    • 在 body 末尾
      @select2easyCss()
  • 如果使用 bootstrap 5 框架,请将其添加到 @select2easyCss() 下的 header 中

    @select2easyThemeBootstrap5()
    • 更改插件实例或直接在 public/vendor/select2easy/js/select2easy.js 中修改

         $('#exemple').select2easy({
          theme: 'bootstrap-5',
        });
      • 或者,您可以使用 @select2easyOptionsJs() 来配置插件使用 theme,并且已经通过 modal 或其他 parent 使用,只需在 select2easyJs() 之前添加即可
    • 需要调整 css 以适应 select2 的 disabled 状态和 input 的大小

      @select2easyThemeBootstrap5Disabled()
    • 如果您想在 theme 中实现高级的 css,请添加

      @select2easyThemeBootstrap5Advance()
    • 需要调整 css 以配合 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;
        }
  • 如果您想将插件实例 select2 应用于所有 select 标签,请在 select2easyJs() 之后添加

    @select2easyApplyAnyJs()

实现

  • 您可以实现任意数量的方法,以在项目中的多个地方调用模型

    • 例如:用户模型
    • sl2Nome:使用名称作为搜索
    • sl2Email:使用名称作为搜索
    • sl2Login:使用名称作为登录
  • 在模型中实现 Select2Easy 特性

  • 创建一个静态函数 Sl2<NomeMetodo>,该函数将在 data-sl2_method{ sl2_method : ""} 中的实现中调用

  • 在视图中

    • 在 select 中放置 class select2Easy(必需)
    • 放置属性 data-sl2_method = "nomeDoMetodoEstaticoDaModel"
    • 放置属性 data-sl2_model = 'caminho\para\Model'
    • 或放置属性 data-sl2_hash = "{{ Crypt::encryptString('caminho\para\Model') }}"
    • 示例
      <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>
  • 在 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>
  • 模型

    • 使用 use Gsferro\Select2Easy\Http\Traits\Select2Easy 导入
    • 放置特性 Select2Easy
    • 创建 nomeDoMetodoEstaticoDaModel,传递术语和页面
    • 示例
      <?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,
            );
          }
      }

级联(select2 父/依赖项)

有时需要将一个 select 设置为另一个 select 的依赖项,以便显示预先筛选的数据,例如 State > Cities。为此,只需在 select2 的 parent)中放置属性 data-sl2_child,并指定 child)的 select2 的 id 即可

  • 示例

    <select id="parent"
        ...
        data-sl2_child="#children" 
    >
    </select>
  • 在模型中:需要有一个 的作用域,并初始化包含作用域作为键和参数 $parentId 作为值的数组 $scopeParentAndId,并将其传递给 self::select2easy,例如

    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,
       );
    }
    • 如果您正在使用 php >8 的版本,可以使用 命名参数

      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
         );
      }
    • 灵感来自此 JavaScript select2-cascade.js

前缀和后缀(可以是关系或列)

  • 前缀:添加到 select2 文本之前
  • 后缀:添加到 select2 文本之后

使用模板(标记)

  • select2easy 包已准备好使用 Templating 功能,该功能允许格式化插件中显示的标题(text)和 HTML。

  • 为此,只需在模型中创建用于 texthtml 的方法,然后插件会完成剩下的工作。

  • 文本 text 是选择后在 select 中显示的内容,而 html 是在返回时通过 ajax 显示的内容。

  • 您也可以单独使用 texthtml,只需将所需项目传递给数组 $markups 即可。

  • 当包被调用时,每个方法将接收两个参数:string $textModel $model,其中 $model 是当前模型实例($this),这些方法必须返回将被渲染的 html

    • 使用示例

      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
            );
        }
    • 用于 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>';
        }
      • 方法渲染

        html
    • 用于 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();
        }
      • 方法渲染

        html
    • 由于您可以在模型中使用多个方法来使用 select2easy,因此您可以根据需要或重用方法和视图来使用多种格式。

已选中

  • 插件链接

  • 最佳选项

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

对于 Laravel > 7

由于至少在包的 v1.* 版本中,目标是与所有版本的 Laravel 保持兼容性,从 L5 到当前的 L11,目前没有提供 component,但这里提供了一些建议和可能在未来版本中提供完全功能性的 component(基于 bootstrap 5)。

  • 如果不存在,创建:resources/views/components/forms/label.blade.php

    @props([
        'label',
        'isRequired' => false,
    ])
    <label  {{ $attributes->merge([ 'class' => 'form-label' ])->whereDoesntStartWith('label') }}>
        {{ $label }} {{ $isRequired ? '*' : '' }}
    </label>
  • 创建: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
    • 或发布组件
  • 我建议创建新的组件,将其封装起来,使用示例

    • 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>
    • 在表单中
      # 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 />

故障排除

  • 错误:"Select2easy 不工作"

    1. 请检查包是否已正确安装
    2. 请检查布局文件是否正确配置
  • 错误:"Select2easy 没有出现"

    1. 请检查是否正确调用 select2easy
    2. 请检查主题是否正确配置
    3. 请检查模型是否正确配置
    4. 请检查 html 是否正确实现

许可

Laravel Localization 是一个开源的 laravel 包,许可协议为 MIT 许可协议