Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model popup using AJAX to show current contents and icon change #5701

Open
technilogics opened this issue Dec 20, 2022 · 3 comments
Open

Model popup using AJAX to show current contents and icon change #5701

technilogics opened this issue Dec 20, 2022 · 3 comments

Comments

@technilogics
Copy link

  • Laravel Version: 9
  • PHP Version: 8.0.9
  • Laravel-admin: 1.8.17

Description:

I am using Grid Column Model to load Related Notes, but unfortunately it has 2 issues

  1. Icon for Column is always Clone icon, there is no way to change it
    Screenshot 2022-12-20 at 19-42-27 Admin Orders
  2. All popup data is loaded with page load, how to load it using AJAX on Icon click, so latest records can be shown.

Steps To Reproduce:

`$grid->column('notes', __('Notes'))->display(function ($title, $column) {
$notes = $this->notes()->with('admin:id,name')->take(10)->orderBy('id','desc')->get()->map(function ($note) {
//return $note->only(['id','description','admin_user_id' , 'created_at']);
return [$note->id,nl2br($note->description ."\n\r\n\rBy ".$note->admin->name ." @ ".date("d/m/Y h:i A",strtotime($note->created_at)))];
});
// dd($notes->flatten()->toArray());
// Otherwise it is displayed as editable
if(count($notes)>0){ //Show Icon, and show Notes in model popup if count greater than 0
return $column->modal('Latest Notes', function ($column) use($notes) {
return new Table(['ID', 'Description'], $notes->toArray(),['table-striped']);
//return new Box('No Information', 'There is no note to show');
});

}else{
  return "-";//Donot show Icon
}

});`

@alexoleynik0
Copy link

alexoleynik0 commented Mar 10, 2023

Was curious about this too and here's what I've found. $grid->column('files')->model($title, $callback = null); accepts two arguments, and the $callback one can be an actual \Closure that returns a string/Renderable (as in the docs' example), or a name of the class that implements \Illuminate\Contracts\Support\Renderable.

In the last case, no render will be called during the Grid render, but ajax load using admin.handle-renderable will be made on the icon click.

It will pass to your Renderable the "key" (primaryKey / id) of the current row, and everything else is just similar to what you do in the callback with tiny adjustments.

For example:

class PostFilesRenderable implements \Illuminate\Contracts\Support\Renderable {
    public function render() {
        $files = File::query()->select(['id', 'path'])->where('post_id', request('key'))->get()->map(function($item) {
            $item->size = file_size(\Illuminate\Support\Facades\Storage::disk('admin')->size($item->path));
            return $item;
        });
        $table = new \Encore\Admin\Widgets\Table(['ID', 'Path', 'Size'], $files->toArray());
        return $table->render() . "<h4>Total files: " . $files->count() . "</h4>";
    }
}

Your controller's grid:

$grid->column('files')->model('Files', PostFilesRenderable);

@alexoleynik0
Copy link

As to "fa-clone" icon change - it's hardcoded into resources/views/components/column-modal.blade.php. But you can override this view if you really need it, as described here.

In your app/Admin/bootstrap.php:

app('view')->prependNamespace('admin', resource_path('views/vendor/laravel-admin'));

You need to follow the same dir structure, so for admin::components.column-modal (from Encore\Admin\Grid\Displayers\Modal@display) you need to create file in views/vendor/laravel-admin/components.column-modal with the same content as in original + your modifications.
Example of the first 3 lines edited:

@if ($value == 0)
    <span data-toggle="modal" data-target="#grid-modal-{{ $name }}" data-key="{{ $key }}">
        <a href="javascript:void(0)"><i class="fa fa-eye"></i>&nbsp;&nbsp;{{ $value }}</a>
    </span>
@else
    <span> --- </span>
@endif

OR you can just simply don't display anything for the column if you don't want to, depending on the original value:

$grid->column('files')->model('Files', PostFilesRenderable)
    ->display(function (string $c, Grid\Column $column) {
        return $column->getOriginal() ? $c : '---';
    });

@technilogics
Copy link
Author

Hi @alexoleynik0 thanks for these directions, it help me in achieving goal. I was busy, when you suggest. Today i spare time to implement it.

but there are a couple of things that i face, so i wants to share, it may help others.

1. $grid->column('files')->model('Files', PostFilesRenderable);
 here model should be modal

2. modal accept class i.e. instead of PostFilesRenderable we have to write PostFilesRenderable:class

regarding icon instead of copying view i use the struct you provided to control display

$grid->column('files')->model('Files', PostFilesRenderable)
    ->display(function (string $c, Grid\Column $column) {
        return $column->getOriginal() ? $c : '---';
    });

in my case for notes i also count notes available as notes_count, as follow

$grid->column('notes_count',  __('Notes'))->modal(__('Notes'),ShowNote::class)
  ->display(function (string $c, Grid\Column $column) {
  if($column->getOriginal()==0){ //if notes_count is 0
    return '-';
  }
        return str_replace('fa-clone','fa-eye',$c); //replace icon with your icon of choice
    });

Thank you for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants