首页 > 解决方案 > 没有搜索按钮的 Laravel 下拉过滤器

问题描述

我有一个列出医生的页面。所有医生都属于特定类别:妇科、外科、泌尿科等。

如何在不使用提交按钮的情况下使用选择下拉菜单过滤它们?我知道这可以通过 Ajax 实现,但我需要帮助。

这是我的代码:

医生控制器

public function doctorsList() {
    $doctors = Doctor::orderBy('id', 'desc')->paginate(20);
    $categories = Category::all();
    return view('doctors-list', compact('doctors', 'categories'));
}

医生-list.blade.php

  <div class="filter text-center">
    <select name="category_id">
      <option value="all">All</option>
      @foreach($categories as $category)
        <option value="{{ $category->id }}">{{ $category->title }}</option>
      @endforeach
    </select>
  </div>
  @foreach($doctors as $doctor)
    <div class="article">
      <div class="row">
        <div class="col-sm-3">
          <div class="image"><a href="{{ route('doctor', $doctor->slug) }}"><img width="260" src="{{ Storage::url($doctor->image) }}" /></a></div>
        </div>
        <div class="col-sm-9 right">
          <div class="title"><h3>{{ $doctor->title }}</h3></div>
          <div class="body">{!! strip_tags(str_limit($doctor->body, 300)) !!}</div>
          <div class="more"><a href="{{ route('doctor', $doctor->slug) }}">More></a></div>
        </div>
      </div>
    </div>
  @endforeach

路线:

Route::get('/doctors', 'DoctorsController@doctorsList')->name('doctorsList');

迁移(两个单独的文件):

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateDoctorsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('doctors', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('doctors');
    }
}


<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateDoctorTranslationsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('doctor_translations', function (Blueprint $table) {
          $table->increments('id');
          $table->integer('doctor_id')->unsigned();
          $table->string('locale')->index();

          // The actual fields to store the content of your entity. You can add whatever you need.
          $table->string('title');
          $table->string('slug')->unique();
          $table->string('image');
          $table->text('body');
          $table->integer('category_id');
          $table->string('status');
          $table->integer('user_id');

          $table->unique(['doctor_id', 'locale']);
          $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('doctor_translations');
    }
}

型号:Doctor.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Dimsav\Translatable\Translatable;

class Doctor extends Model
{
  use Translatable;

  public $translatedAttributes = ['title', 'slug', 'image', 'body', 'category_id','status', 'user_id'];

  public function category() {
    return $this->belongsTo('App\Category');
  }
}

DoctorTranslation.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;

class DoctorTranslation extends Model
{
  use Sluggable;

  public $timestamps = false;

  /**
   * Return the sluggable configuration array for this model.
   *
   * @return array
   */
  public function sluggable()
  {
      return [
          'slug' => [
              'source' => 'title',
              'onUpdate' => true
          ]
      ];
  }
}

现在,我正在使用此代码显示所有医生,并创建了从数据库中获取类别的选择框。

当我从下拉列表中选择不同的类别时,如何过滤它们?

我正在使用 Laravel 5.5

标签: phplaraveleloquent

解决方案


您可以使用查询参数按类别过滤医生。这将是更新的控制器方法:

public function doctorsList(Request $request)
{
    $query = (new Doctor)->newQuery();
    $selectedCategory = $request->get('category_id', 'all');

    if (is_numeric($selectedCategory )) {
        $query->whereTranslation('category_id', $selectedCategory);
    }

    $doctors = $query->orderBy('id', 'desc')->paginate(20);
    $categories = Category::all();

    return view('doctors-list', compact('doctors', 'categories', 'selectedCategory'));
}

刀片模板将类似于:

<form action="{{route('doctorsList')}}" method="get">
  <div class="filter text-center">
    <select name="category_id" onchange="this.form.submit()">
      <option value="all">All</option>
      @foreach($categories as $category)
        <option value="{{ $category->id }}" {{$category->id == $selectedCategory ? 'selected' : ''}}>{{ $category->title }}</option>
      @endforeach
    </select>
  </div>
</form>
  @foreach($doctors as $doctor)
    <div class="article">
      <div class="row">
        <div class="col-sm-3">
          <div class="image"><a href="{{ route('doctor', $doctor->slug) }}"><img width="260" src="{{ Storage::url($doctor->image) }}" /></a></div>
        </div>
        <div class="col-sm-9 right">
          <div class="title"><h3>{{ $doctor->title }}</h3></div>
          <div class="body">{!! strip_tags(str_limit($doctor->body, 300)) !!}</div>
          <div class="more"><a href="{{ route('doctor', $doctor->slug) }}">More></a></div>
        </div>
      </div>
    </div>
  @endforeach

当然,您可以将 onchange 处理程序放在 js 文件中的某个位置,而不是内联。

我认为您将医生列出的路线命名为doctors.list

此外,如果您使用此解决方案,您应该注意也将类别查询参数添加到分页链接。


推荐阅读