Laravel-背包选择取决于另一个选择 [英] Laravel - Backpack select dependent from another select

查看:72
本文介绍了Laravel-背包选择取决于另一个选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在我的Laravel项目中安装了 Laravel Backpack admin.目前,我正在研究它.但是我需要帮助.所以...

我想要的东西:

我想有两个选择,第一个是 Category ,第二个是 Article .因此, Article 选择必须取决于 Category 选择.并且 Article 属于 类别.

类别文章

 类别1 = [第1条,第2条,第3条]第2类= [第4条,第5条] 

这只是显示哪个文章属于类别.因此,例如,当我单击 category select上的 Category 1 时,在 article select上,它应该只向我显示 Article 1,Article 2和第3条.

我做什么

我按照背包文档的说明进行操作,为此

解决方案

在背包4.1中,您应该添加'include_all_form_fields'=>依赖字段上的true属性.

I recently installed Laravel Backpack admin in my Laravel project. 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. So Article select must depend on Category select. And 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.

What I did

I followed instructions on Backpack docs, for Add a select2 field that depends on another field on this link. So what I did first:

I created two tables, Category table and Article table. 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:

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.

After all this I made Archive table and these are my migrations:

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:

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. This is my 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. Then I made Api folder in App\Http\Controller and then I made ArticleController in it, like this:

<?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. And finally my 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.

But when I choose category in my Archive create no articles showing. Can someone please help me with this?

解决方案

From backpack 4.1 you should include 'include_all_form_fields' => true attribute on the dependent field.

这篇关于Laravel-背包选择取决于另一个选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆