简体   繁体   English

Laravel - 背包 select 依赖于另一个 select

[英]Laravel - Backpack select dependent from another select

I recently installed Laravel Backpack admin in my Laravel project.我最近在我的 Laravel 项目中安装了Laravel Backpack admin。 Currently right now I'm working on it.目前我正在努力。 But I need help.但我需要帮助。 So...所以...

What I want:我想要的是:

I want to have two selects, first one is Category and the second one is Article .我想要两个选择,第一个是Category ,第二个是Article So Article select must depend on Category select.所以Article select 必须依赖于Category select。 And Article belongsTo Category .并且Article belongsTo Category

Category-Article分类-文章

Category 1 = [ Article 1, Article 2, Article 3 ]
Category 2 = [ Article 4, Article 5 ]

This is just a showing of which article belongs to category.这只是显示哪个文章属于类别。 So for example, when I click Category 1 on category select, on article select it should show me only Article 1, Article 2 and Article 3 .因此,例如,当我在article select 上单击category select 上的Category 1时,它应该只显示Article 1, Article 2 and Article 3

What I did我做了什么

I followed instructions on Backpack docs, for Add a select2 field that depends on another field on this link .我按照 Backpack docs 上的说明添加了一个依赖于此链接Add a select2 field that depends on another field So what I did first:所以我首先做了什么:

I created two tables, Category table and Article table.我创建了两个表, Category表和Article表。 Their models:他们的模型:

class Category extends Model
{
    use CrudTrait;

    /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $table = 'categories';
    protected $primaryKey = 'id';
    // public $timestamps = false;
    // protected $guarded = ['id'];
    protected $fillable = ['title'];
    // protected $hidden = [];
    // protected $dates = [];

    /*
    |--------------------------------------------------------------------------
    | FUNCTIONS
    |--------------------------------------------------------------------------
    */

    public function articles(){
        return $this->hasMany('App\Models\Article');
    }
}

This is a Category model, and this is Article model:这是一个Category model,这是Article model:

class Article extends Model
{
    use CrudTrait;

    /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $table = 'articles';
    protected $primaryKey = 'id';
    // public $timestamps = false;
    // protected $guarded = ['id'];
    protected $fillable = ['title', 'category_id'];
    // protected $hidden = [];
    // protected $dates = [];

    /*
    |--------------------------------------------------------------------------
    | FUNCTIONS
    |--------------------------------------------------------------------------
    */

    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */

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

I made relationships between these two models like this.我在这两个模型之间建立了这样的关系。 So when I create Article it shows me title and I have to choose category_id from category select .因此,当我创建Article时,它会显示标题,我必须从category select中选择category_id

After all this I made Archive table and these are my migrations:毕竟,我制作了Archive表,这些是我的迁移:

Schema::create('archives', function (Blueprint $table) {
   $table->increments('id');
   $table->string('title');

   $table->bigInteger('category_id')->unsigned();
   $table->foreign('category_id')->references('id')->on('categories');

   $table->bigInteger('article_id')->unsigned();
   $table->foreign('article_id')->references('id')->on('articles');

   $table->timestamps();
});

And my Archive.php model:还有我的Archive.php model:

class Archive extends Model
{
    use CrudTrait;

    /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $table = 'archives';
    protected $primaryKey = 'id';
    // public $timestamps = false;
    // protected $guarded = ['id'];
    protected $fillable = ['title', 'category', 'article'];
    // protected $hidden = [];
    // protected $dates = [];

    /*
    |--------------------------------------------------------------------------
    | FUNCTIONS
    |--------------------------------------------------------------------------
    */

    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */

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

    public function article(){
        return $this->belongsTo('App\Models\Article');
    }
}

And then I followed instructions from the backpack docs .然后我按照backpack docs的说明进行操作。 This is my ArchiveCrudController :这是我的ArchiveCrudController

public function setup()
    {
        /*
        |--------------------------------------------------------------------------
        | CrudPanel Basic Information
        |--------------------------------------------------------------------------
        */
        $this->crud->setModel('App\Models\Archive');
        $this->crud->setRoute(config('backpack.base.route_prefix') . '/archive');
        $this->crud->setEntityNameStrings('archive', 'archives');

        $this->crud->setColumns(['title', 'category', 'article']);
        $this->crud->addField([
            'name' => 'title',
            'type' => 'text',
            'label' => "Archive title"
        ]);

        $this->crud->addField([    // SELECT2
            'label'         => 'Category',
            'type'          => 'select',
            'name'          => 'category_id',
            'entity'        => 'category',
            'attribute'     => 'title',
        ]);
        $this->crud->addField([ // select2_from_ajax: 1-n relationship
            'label'                => "Article", // Table column heading
            'type'                 => 'select2_from_ajax',
            'name'                 => 'article_id', // the column that contains the ID of that connected entity;
            'entity'               => 'article', // the method that defines the relationship in your Model
            'attribute'            => 'title', // foreign key attribute that is shown to user
            'data_source'          => url('api/article'), // url to controller search function (with /{id} should return model)
            'placeholder'          => 'Select an article', // placeholder for the select
            'minimum_input_length' => 0, // minimum characters to type before querying results
            'dependencies'         => ['category'], // when a dependency changes, this select2 is reset to null
            //'method'                    => ‘GET’, // optional - HTTP method to use for the AJAX call (GET, POST)
        ]);


        /*
        |--------------------------------------------------------------------------
        | CrudPanel Configuration
        |--------------------------------------------------------------------------
        */

        // TODO: remove setFromDb() and manually define Fields and Columns
        //$this->crud->setFromDb();

        // add asterisk for fields that are required in ArchiveRequest
        $this->crud->setRequiredFields(StoreRequest::class, 'create');
        $this->crud->setRequiredFields(UpdateRequest::class, 'edit');
    }

Like from backpack docs .就像来自backpack docs一样。 Then I made Api folder in App\Http\Controller and then I made ArticleController in it, like this:然后我在App\Http\Controller中创建了Api文件夹,然后在其中创建了ArticleController ,如下所示:

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Article;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function index(Request $request)
    {
        $search_term = $request->input('q');
        $form = collect($request->input('form'))->pluck('value', 'name');

        $options = Article::query();

        // if no category has been selected, show no options
        if (! $form['category']) {
            return [];
        }

        // if a category has been selected, only show articles in that category
        if ($form['category']) {
            $options = $options->where('category_id', $form['category']);
        }

        if ($search_term) {
            $results = $options->where('title', 'LIKE', '%'.$search_term.'%')->paginate(10);
        } else {
            $results = $options->paginate(10);
        }

        return $options->paginate(10);
    }

    public function show($id)
    {
        return Article::find($id);
    }
}

I just copy-paste code from docs but of course I changed model for my need.我只是从docs中复制粘贴代码,但当然我根据需要更改了 model。 And finally my routes :最后是我的routes

Route::get('api/article', 'App\Http\Controllers\Api\ArticleController@index');
Route::get('api/article/{id}', 'App\Http\Controllers\Api\ArticleController@show');

I copy-paste these routes in my web.php in routes folder and in custom.php in routes/backpack folder.我将这些路线复制粘贴到我的web.phproutes文件夹和custom.phproutes/backpack文件夹中。

But when I choose category in my Archive create no articles showing.但是当我在我的Archive create任何articles显示。 Can someone please help me with this?有人可以帮我吗?

在此处输入图像描述

From backpack 4.1 you should include 'include_all_form_fields' => true attribute on the dependent field.从背包 4.1 开始,您应该在依赖字段上包含 'include_all_form_fields' => true 属性。

you have some issue in your code i hope this would solve them:您的代码中有一些问题,我希望这可以解决它们:

1- in ArchiveCrudController: be sure that the dependencies with category_id not category... 1- 在 ArchiveCrudController 中:确保具有 category_id 的依赖项不是类别...

'dependencies'         => ['category_id'], 

 $this->crud->addField([ // select2_from_ajax: 1-n relationship
            'label'                => "Article", 
            'type'                 => 'select2_from_ajax',
            'name'                 => 'article_id',
            'entity'               => 'article',
            'attribute'            => 'title', 
            'data_source'          => url('api/article'), 
            'placeholder'          => 'Select an article',
            'minimum_input_length' => 0, querying results
            'dependencies'         => ['category_id'], 
            //'method'                    => ‘GET’,
        ]);

2- in Archive Model $fillable should take db column names not relations... 2-在存档 Model $fillable 应该采用 db 列名而不是关系...

 protected $fillable = ['title', 'category_id', 'article_id'];

3- also when you get $form request parameter, it comes with name category_id like you name it in Crud not (category) 3- 当你得到 $form 请求参数时,它带有名称 category_id 就像你在 Crud 中命名它不是(类别)

public function index(Request $request)
    {
        $search_term = $request->input('q');
        $form = collect($request->input('form'))->pluck('value', 'name');

        $options = Article::query();

        // if no category has been selected, show no options
        if (! $form['category_id']) {
            return [];
        }

        // if a category has been selected, only show articles in that category
        if ($form['category_id']) {
            $options = $options->where('category_id', $form['category_id']);
        }

        if ($search_term) {
            $results = $options->where('title', 'LIKE', '%'.$search_term.'%')->paginate(10);
        } else {
            $results = $options->paginate(10);
        }

        return $options->paginate(10);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM