Header Ads

Create and Update Data Row to different table in Laravel Nova



Already have table User but want to insert some data row to another table, we will use fillUsing and resolveUsing functions in this tutorial. 

    The provided code is a PHP script written in the Laravel Nova framework, which is a tool for building administration panels for web applications. The script defines a resource called "User" in the Nova panel, which corresponds to the "User" model in the application.

    The "User" resource has several fields defined for displaying and managing user data. These fields include the user's ID, name, email, password, and a relationship to the "Post" model representing the user's posts. Additionally, there is a custom field called "Data" that contains multiple text fields for storing additional data about the user, such as their Facebook name, YouTube name, and Twitter name.

    The "Data" field is configured using the "Row" and "CustomText" classes from the R64\\NovaFields package. The field is prepopulated when empty, and it is displayed as a table-like structure with multiple rows and columns. The field also has some custom styling and configuration options.

The most interesting part of the code is the "fillUsing" and "resolveUsing" callbacks defined for the "Data" field. The "fillUsing" callback is executed when the form is submitted, and it handles the saving of the additional data rows to the "Datatable" table. It retrieves the data rows from the request, iterates over them, and performs the necessary operations to insert or update the rows in the "Datatable" table based on the provided data. It also handles the deletion of any existing data rows that are not included in the current request.

The "resolveUsing" callback is executed when retrieving the data for the "Data" field. It retrieves the existing data rows from the "Datatable" table and transforms them into a JSON-encoded string to be displayed in the field. It filters out any rows with a "status" of "DEL" to exclude deleted rows from being displayed.

    In addition to the field definitions, the script also includes the necessary imports and the definition of the "User" resource class, which extends the "Resource" class provided by Laravel Nova. The class defines static properties such as the model class to be used, the title field, and the fields to be searched. It also includes empty methods for defining cards, filters, lenses, and actions associated with the "User" resource.

ncludes the definition of an "ImportUsers" action, which is a custom action that can be performed on the "User" resource in the Nova panel. The action is included in the "actions" method of the resource, making it available for use.

    Overall, the provided code sets up a resource for managing user data in the Laravel Nova panel. It includes fields for basic user information and additional data rows, and it provides callbacks for handling the saving and retrieval of the additional data rows in a separate table.


<?h   
namespace App\Nova;

    use App\Datatable;
    use App\Nova\Actions\ImportUsers;
    use App\Nova\Post;
    use Illuminate\Http\Request;
    use Laravel\Nova\Fields\Gravatar;
    use Laravel\Nova\Fields\ID;
    use Laravel\Nova\Fields\Date;
    use Laravel\Nova\Fields\HasMany;
    use Laravel\Nova\Fields\Password;
    use Laravel\Nova\Fields\Text;
    use R64\NovaFields\Row;
    use R64\NovaFields\Text as CustomText;

    class User extends Resource
    {
        /**
         * The model the resource corresponds to.
         *
         * @var string
         */
        public static $model = \App\User::class;

        /**
         * The single value that should be used to represent the resource when being displayed.
         *
         * @var string
         */
        public static $title = 'name';

        /**
         * The columns that should be searched.
         *
         * @var array
         */
        public static $search = [
            'id', 'name', 'email',
        ];

        /**
         * Get the fields displayed by the resource.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return array
         */
        public function fields(Request $request)
        {
            return [
                ID::make()->sortable(),

                Gravatar::make()->maxWidth(50),

                Text::make('Name')
                    ->sortable()
                    ->rules('required', 'max:255'),

                Text::make('Email')
                    ->sortable()
                    ->rules('required', 'email', 'max:254')
                    ->creationRules('unique:users,email')
                    ->updateRules('unique:users,email,{{resourceId}}'),

                Password::make('Password')
                    ->onlyOnForms()
                    ->creationRules('required', 'string', 'min:8')
                    ->updateRules('nullable', 'string', 'min:8'),
                HasMany::make('Posts', 'posts', Post::class),
                Row::make('Data', [
                    CustomText::make('Name'),
                    CustomText::make('Facebook Name'),
                    CustomText::make('YouTube Name'),
                    CustomText::make('Twitter Name'),
                ])->prepopulateRowWhenEmpty()
                    ->fieldClasses('py-6 px-8 w-full')
                    ->panelFieldClasses('w-full py-4')
                    ->itemWrapperClasses('flex border-40 border-l-0
                                            border-r-0 table-field-item-wrapper')
                    ->childConfig([
                        'fieldClasses' => 'w-full px-1 py-2',
                        'wrapperClasses' => 'w-full flex',
                        'hideLabelInForms' => true,
                    ])
                    ->hideLabelInForms()
                    ->hideLabelInDetail()
                    ->alwaysShow()
                    ->fillUsing(function ($request, $model) {
                        $model::saved(function ($model) use ($request) {
                            $dataRows = $request->data ?: [];  //2
                            foreach ($dataRows as $data) {
                                $data = (object)$data;
                                if (!optional($data)->id) {
                                    //insert user_id to tbl_datatable
                                    $datatable = new Datatable();

                                    $datatable->user_id = $model->id;
                                } else {
                                    $datatable = Datatable::find($data->id);
                                    $datatable->updated_at = date('Y-m-d');
                                }
                                $datatable->name = $data->name;
                                $datatable->facebook_name = $data->facebook_name;
                                $datatable->twitter_name = $data->twitter_name;
                                $datatable->youtube_name = $data->youtube_name;
                                $datatable->save();
                            }
                            $dataIds = $dataRows ? collect($dataRows)->pluck('id')->toArray() : [];
                            $requestDatas = $this->dataTable;
                            if ($requestDatas) {
                                foreach ($requestDatas as $existingDatas) {
                                    if (!in_array($existingDatas->id, $dataIds)) {
                                        $existingDatas->status = 'DEL';
                                        $existingDatas->updated_at = date('Y-m-d H:i:s');
                                        $existingDatas->update_by = auth()->user()->username;
                                        $existingDatas->save();
                                    }
                                }
                            }
                        });
                    })
                    ->resolveUsing(function ($data) {
                        $rows = [];
                        $requestDatas = $this->dataTable;
                        if ($requestDatas->isNotEmpty()) {
                            foreach ($requestDatas as $data) {
                                if ($data->status !== 'DEL') {
                                    $rows[] = array(
                                        'name' => $data->name,
                                        'facebook_name' => $data->facebook_name,
                                        'youtube_name' => $data->youtube_name,
                                        'twitter_name' => $data->twitter_name,
                                        'id'    => $data->id
                                    );
                                }
                            }
                        }
                        return json_encode($rows);
                    })

            ];
        }

        /**
         * Get the cards available for the request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return array
         */
        public function cards(Request $request)
        {
            return [];
        }

        /**
         * Get the filters available for the resource.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return array
         */
        public function filters(Request $request)
        {
            return [];
        }

        /**
         * Get the lenses available for the resource.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return array
         */
        public function lenses(Request $request)
        {
            return [];
        }

        /**
         * Get the actions available for the resource.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return array
         */
        public function actions(Request $request)
        {
            return [
                new ImportUsers
            ];
        }
    }

No comments:

Powered by Blogger.