Crud: [Field Type] addClause on select, select2, select_multiple, select2_multiple, checklist, checklist_dependency

Created on 23 Jun 2016  路  5Comments  路  Source: Laravel-Backpack/CRUD

@AurelDragut made an interesting suggestion: at some point, we'll definitely need to filter the results in these 1-n and n-n fields.

Say:

  • only show moderators, not all users
  • only show trashed items
  • only show products that are under 50$
    etc.

I see one way to do this right now:

  • creating a new model that extends the old one and overwrites the "all" method to restrict the query;

But... it's not pretty... Should we do something about this? What better ways do you see to solve this?

Thanks, cheers!

help wanted question

Most helpful comment

Following @MarcosBL example, I had to do like this (probably because of a newer laravel version?) :

In a separate file:

<?php
namespace App\Models;
class CursosActivos extends Cursos
{
    public static function boot()
    {
        parent::boot();
        static::addGlobalScope(function ($query) {
            $query->where('activo', 1);
        });
    }
}

All 5 comments

There are a few solutions to this, available right now. Let's round them up:
1) use the select_from_array field type and give it a filtered array of results;
2) create a new field type, where you copy-paste the select2 field type and just load the options you want;
3) create a new model that extends the old one and overwrites the "all" method to restrict the query (as mentioned above);

Since there are 3 existing solutions to this possible problem, with option 1 being a very good one ( in my opinion) I'll go ahead and close this issue.

hi , i have this situation
a table : containing iphone brand ( apple samsung ...)
Schema::create('marque_tel', function (Blueprint $table) {

        $table->increments('id');
        $table->string('nom_marque');
        //
    });

a model table containing phones models ( 5S , 6 , 7 for appel , S1 , S2 ... for samsung )
Schema::create('model_tel', function (Blueprint $table) {
$table->increments('id_model');
$table->string('nom_model');
$table->date('annee_model');
$table->timestamps();
$table->integer('marque_id')->unsigned();
$table->foreign('marque_id')->references('id')->on('marque_tel');
});

a reference table contaiing the id

Schema::create('model_ref', function (Blueprint $table) {
$table->increments('id');
$table->string('nom_ref');
$table->integer('model_id')->unsigned();
$table->foreign('model_id')->references('id')->on('model_tel');
$table->timestamps();
});
i managed to create admin menu item using crud for marque ( brand ) table so i list , add modify phone brands , and also i managed to create a model menu item to manage phones models ( model_tel table ) using this crud controller
`

namespace App\Http\Controllers\Admin;

use Backpack\CRUD\app\Http\Controllers\CrudController;

// VALIDATION: change the requests to match your own file names if you need form validation
use App\Http\Requests\Admin\marquecrudrequest as StoreRequest;
use App\Http\Requests\Admin\marquecrudrequest as UpdateRequest;

class ModelTelController extends CrudController {

    /**
     *
     */
    public function setup() {
        $this->crud->setModel("App\Larapen\Models\model_tel");
        $this->crud->setRoute("admin/model");
        $this->crud->setEntityNameStrings('model', 'model_tel');


 $this->crud->addColumn([
    'name' =>'id',
    'label' =>'id',
    ]);
  $this->crud->addColumn([
            'label' => "marque tel", // Table column heading
    'type' => 'select',
    'name' => 'marque_id', // the column that contains the ID of that connected entity;
    'entity' => 'marque_tel', // the method that defines the relationship in your Model
    'attribute' => "nom_marque",
// foreign key attribute that is shown to user
    'model' => 'App\Larapen\Models\marque_tel', // foreign key model'
        ]);
    $this->crud->addColumn([
            'name' => 'nom_model',
            'label' => "nom model",
        ]);
        $this->crud->addColumn([
            'name' => 'annee_model',
            'label' => "annee model",
        ]);




        $this->crud->addField([
            'name' => 'nom_model',
            'label' => "nom model",
        ]);
        $this->crud->addField([
            'name' => 'annee_model',
            'label' => "annee model",
            'type' => 'datetime'
        ]);
        $this->crud->addField([
        'label' => "id Marque",
        'type' => 'select',
        'name' => 'marque_id', // the db column for the foreign key
        'entity' => 'marque_tel', // the method that defines the relationship in your Model
        'attribute' => 'nom_marque', // foreign key attribute that is shown to user
        'model' => 'App\Larapen\Models\marque_tel' // foreign key model

        ]);
    }

    public function store(StoreRequest $request)
    {
        return parent::storeCrud();
    }

    public function update(UpdateRequest $request)
    {
        return parent::updateCrud();
    }
}`

my probleme now is tha i want to be able to select brand ( marque_tel ) then only model of this brend is shown when adding reference for model

many searches lead me to hasmanythrought by i dont know how to uses it with crud . and

Just used the method @tabacitu proposes. I had a select2 with a model Cursos that I wanted filled only with activo=1 (active, boolean field) records in related models.

So in the same Models\Cursos.php file (to keep things together) I added a second mini-class:

````php
class CursosActivos extends Cursos
{
public static function boot()
{
parent::boot();
static::addGlobalScope('activo', function (Builder $builder) {
$builder->where('activo', 1);
});
}

}
````

And in my CrudController I set the select2 instead of the regular

php 'model' => "App\Models\Cursos"

to the new filtered one

php 'model' => "App\Models\CursosActivos"

Et voil谩, my select2 combos only show active courses :smiley:

I make extension for select2 field to support filter results

  1. Add filter on filed crud
$this->crud->addField([
            'label' => ' Members',
            'type' => 'select2',
            'name' => 'user_id',
            'entity' => 'user',
            'attribute' => 'name_email_points',
            'model' => "App\Models\Member",
            'attributes' => ['required' => 'required', ],
            'filter' => ['key'=>'points', 'operator'=>'>', 'value'=>5],
        ]);
  1. update select2 field file
        @if (isset($field['model']))
            <?php
                    if(isset($field['filter']) && is_array($field['filter'])){
                        $filter = $field['filter'];
                        $key = $filter['key'];
                        $val = $filter['value'];
                        $op = (isset($filter['operator']))? $filter['operator']: '==';

                        $fields = $field['model']::where($key,$op ,$val)->get() ;
                    }else{
                        $fields = $field['model']::all() ;
                    }

                ?>
            @foreach ($fields as $connected_entity_entry)

Following @MarcosBL example, I had to do like this (probably because of a newer laravel version?) :

In a separate file:

<?php
namespace App\Models;
class CursosActivos extends Cursos
{
    public static function boot()
    {
        parent::boot();
        static::addGlobalScope(function ($query) {
            $query->where('activo', 1);
        });
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

sseggio picture sseggio  路  3Comments

alexgmin picture alexgmin  路  3Comments

sokvebolkol picture sokvebolkol  路  3Comments

genesiscz picture genesiscz  路  3Comments

jorgepires picture jorgepires  路  3Comments