Multi-level actions of laravel-admin

Keywords: Laravel

The framework of laravel-admin has been defined for multi-level actions that can be viewed on the official website. It will not be repeated here. However, when using it, it is found that the function is slightly different from what you want. It is not useful when you first enter the default, so you change it and add a default method.

Take the secondary actions of cities and regions as an example, when I select Shenyang, the regional list becomes Peace Zone, Shenhe Zone, Tiexi Zone, etc. When I select Dalian, it shows Wafangdian, Ganjingzi, etc.

First, follow laravel-admin's documentation and add it to Model

    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);

        $this->setParentColumn('pid');
        $this->setOrderColumn('sort');
        $this->setTitleColumn('name');
    }

Then add a select control for the city and region on the form

    protected function form()
    {
        return Admin::form(AreaModel::class, function (Form $form) {

            $form->text('name', 'Name')->rules("required");
            $form->select('city_id','City')->options(

                DealCityModel::selectOptionsNoRoot()

            )->load('pid', 'district')->loadOne('pid', 'district');//The load method comes with the framework, defined in the vendor=>encore=>laravel-admin=>src=>Form=>Field=>Select file, the loadone is written by itself, and the code district is given to define the method for itself, and the pid is the name of the drop-down list box that changes depending on the city, which is this one below.

            $form->select('pid','region')->options(array(0 =>'Please select a region'));

        });
    }

Create a new district method after the from method

    public function district(Request $request)
    {
        $cityId = $request->get('q');

        $list = AreaModel::where(['city_id' => $cityId, 'pid' => 0])->get(['id', DB::raw('name as text')]);

        foreach ($list as $key => $value) {

            $arr[] = array("id" => $value->id, "text" => $value->text);

        }

        return $arr;//Returns the option of the array to the region

    }

After the load method in the vendor=>encore=>laravel-admin=>src=>Form=>Field=>Select file, create a new method named loadone with the following code:

    public function loadOne($field, $sourceUrl, $idField = 'id', $textField = 'text')
    {
        if (Str::contains($field, '.')) {
            $field = $this->formatName($field);
            $class = str_replace(['[', ']'], '_', $field);
        } else {
            $class = $field;
        }

        $script = <<<EOT
$(function(){
    var target = $(".$class");
    $.get("$sourceUrl?q="+$("{$this->getElementClassSelector()}").val(), function (data) {
        target.find("option").remove();
        $(target).select2({
            data: $.map(data, function (d) {
                d.id = d.$idField;
                d.text = d.$textField;
                return d;
            })
        });
    });
});
EOT;

        Admin::script($script);

        return $this;
    }

This is equivalent to adding a default data fill to the load method.

Finally, don't forget to add the district method to the route. Write the route that defines the district above

Posted by gabaod on Sun, 19 Jul 2020 07:24:26 -0700