yajra / laravel-datatables-editor

Laravel DataTables Editor Integration.
https://yajrabox.com/docs/laravel-datatables/editor-installation
MIT License
115 stars 14 forks source link

Editor and join select box #44

Closed der-ada closed 5 months ago

der-ada commented 4 years ago

Hi!

I have a laravel 5.8 application which uses the datatables editor with this package, i.e. laravel-datatables.

I have a model App\x which has a belongsTo('App\y') relation.

In the datatable I display the field y.name which works well and shows the joined data from the y-table based on join-field x.y_id.

Now, the editor should use (both inline and in the dialogue) a select-box which gets its options list from all rows in the y table and set the selected attribute based on x.y_id. If an option in this select-box is chosen, the field x.y_id should be updated accordingly. When I set the field type to "select", it still shows the current y.name correctly, but there are no options to select from.

How can I populate the options list? And how can I tell the editor to update the field x.y_id according to the selected option?

Thank you very much, ada

der-ada commented 4 years ago

Anyone?

yajra commented 4 years ago

Several ways to achieve this. Assuming Post belongsTo User.

use Yajra\DataTables\Html\Editor\Fields\BelongsTo;
use Yajra\DataTables\Html\Editor\Fields\Select;

Select::make('user_id')->modelOptions(User::class, 'name'),
Select::make('user_id')->tableOptions('users', 'name'),
BelongsTo::model(User::class, 'name'),

You can also use select2 to fetch the data using ajax request but the setup needs more work to implement.

sahakavatar commented 4 years ago

Hi i have same problem im using this https://yajrabox.com/docs/laravel-datatables/master/editor-tutorial same structure and dont understand where needs use code below

Several ways to achieve this. Assuming Post belongsTo User.

use Yajra\DataTables\Html\Editor\Fields\BelongsTo; use Yajra\DataTables\Html\Editor\Fields\Select;

Select::make('user_id')->modelOptions(User::class, 'name'), Select::make('user_id')->tableOptions('users', 'name'), BelongsTo::model(User::class, 'name'), You can also use select2 to fetch the data using ajax request but the setup needs more work to implement.

sahakavatar commented 4 years ago

in DataTable class i override following methods and problem solved

public function render($view, $data = [], $mergeData = []) { if ($this->request()->ajax() && $this->request()->wantsJson()) { return app()->call([$this, 'ajax']); }

    if ($action = $this->request()->get('action') and in_array($action, $this->actions)) {
        if ($action == 'print') {
            return app()->call([$this, 'printPreview']);
        }

        return app()->call([$this, $action]);
    }

    return view($view, $data, $mergeData)->with($this->dataTableVariable, $this->getHtmlBuilder());
}

public function ajax()
{
    $source = null;
    if (method_exists($this, 'query')) {
        $source = app()->call([$this, 'query']);
        $source = $this->applyScopes($source);
    }

    /** @var \Yajra\DataTables\DataTableAbstract $dataTable */
    $options=[];
    $dataTable = app()->call([$this, 'dataTable'], compact('source','options'));
    $result=$dataTable->toArray();
    $result['options']=method_exists($this, 'getOptions')?app()->call([$this, 'getOptions']):[];
    $dataTable=new Collection($result);
    if ($callback = $this->beforeCallback) {
        $callback($dataTable);
    }

    if ($callback = $this->responseCallback) {
        $data = new Collection($dataTable->toArray());
        return new JsonResponse($callback($data));
    }

    return $dataTable->toJson();
}

public function getOptions()
{
    return [
        'barcodes.code'=>Barcodes::select('code as label','id as value')->get()
    ];

}

improved-software commented 4 years ago

I pass the options from the DataTable class

public function dataTable($query)
{

    $options = [
        "block_id" => FarmBlock::pluck('id', 'name')->sortBy('name'),
        "variety_id" => FarmVariety::pluck('id', 'name')->sortBy('name'),
    ];

    return datatables()
        ->eloquent($query)
        ->with('options', $options);
}

In the query I get both the id and the name

public function query(FarmBlockVariety $model)
{
    return $model->newQuery()
        ->select(
            'farm_block_varieties.id', 
            'block_id',
            'farm_blocks.name AS block_name',
            'variety_id',  
            'farm_varieties.name AS variety_name',
            'ha', 
            'trees', 
            'year_planted', 
            'num_rows', 
            'farm_block_varieties.season_id',
            'setting_seasons.short_name AS season_name'
        )
        ->join('setting_seasons', 'farm_block_varieties.season_id', '=', 'setting_seasons.id')
        ->join('farm_blocks', 'farm_block_varieties.block_id', '=', 'farm_blocks.id')
        ->join('farm_varieties', 'farm_block_varieties.variety_id', '=', 'farm_varieties.id')
        ->where('setting_seasons.current', '=', true);
}

When you set up the DataTable table, the data is the name and the editField is the id

{
    data: 'block_name',
    editField: 'block_id',
    name: 'farm_blocks.name',
    title: 'Block',
    orderable: true,
    searchable: true,
    className: 'editable'
},
{
    data: 'variety_name',
    editField: 'variety_id',
    name: 'farm_varieties.name',
    title: 'Variety',
    orderable: true,
    searchable: true,
    className: 'editable'
},

Note that when you do update the select field, only the id will be passed back. (The name will stay the same, but if you refresh it is actually updated) So you need to specify the new name to be returned in the updated method. See #43

github-actions[bot] commented 5 months ago

This issue is stale because it has been open for 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] commented 5 months ago

This issue was closed because it has been inactive for 7 days since being marked as stale.