Master detail error

Hello john. I experienced an error when i try to add data using master detail. Let’s get to the case.

  1. I have two data. Let’s call it data number one and data number two.

  2. Click master detail button on data number one

  3. Click master detail button on data number two

  4. Click add master detail data on data number one, then save

  5. The data didn’t appear on data number one / data number two

  6. When i refresh the page, data appear on data number two’s detail.

it should appear on data number one’s detail, because that’s where i inserted it right ?
Can you help me @johnny ?

Hello @heruprambadi

Perhaps the source code you are using can be displayed here

Hello @heruprambadi ,

I will need more detail of your issue since I can’t reproduce the issue that you are referring to. I believe there is a misconception here. When you are adding one item it is supposed to be added in the list that you are getting referred to right? This is the way that master/detail works on Grocery CRUD. If you would like for all the lists to get updated then you can do that with the below work-around:

window.addEventListener('gcrud.form.insert-success', () => {
    
    document.querySelectorAll('.fa-sync-alt').forEach(button => {
        button.click();
    });
});

Don’t forget though to have the configuration 'publish_events' => true in order to work.

Regards
Johnny

this is my code :

public function index()
    {
        $crud = $this->_getGroceryCrudEnterprise();
        $crud->setTable('kal_invoices');
        $crud->setUniqueId('kal_invoices');
        $crud->unsetCssTheme();
        $crud->unsetExport();
        $crud->unsetPrint();
        //$crud->where(['per_info_personal.id_payroll >= ?' => 0]);
        $crud->setSubject('Invoices', 'Daftar Invoices');
        $crud->columns(['fk_id_projects', 'nama', 'nomor', 'tanggal', 'id_invoice']);
        $crud->addFields(['fk_id_projects', 'nama', 'nomor', 'tanggal', 'status', 'id_invoice', 'inserted_by', 'inserted_time']);
        $crud->editFields(['fk_id_projects', 'nama', 'nomor', 'tanggal', 'status', 'updated_by', 'updated_time']);

        $crud->fieldType('status', 'dropdown_search', [
            'Menunggu' => 'Menunggu',
            'Lunas' => 'Lunas',
            'Dibatalkan' => 'Dibatalkan'
        ]);

        $crud->displayAs('fk_id_projects', 'Nama Project');

        $crud->fieldType('inserted_by', 'hidden');
        $crud->fieldType('inserted_time', 'hidden');
        $crud->fieldType('id_invoice', 'hidden');
        $crud->fieldType('updated_by', 'hidden');
        $crud->fieldType('updated_time', 'hidden');

        $crud->setRelation('fk_id_projects', 'kal_kegiatan', 'nama_kegiatan');
        $crud->setMasterDetail(url('invoice/details'));
        $crud->setActionButton('Kirim', 'fa fa-envelope', function ($row) {
            return url('invoice/kirim/' . $row->id.'/'.$row->id_invoice);
        }, false);
        $crud->setActionButton('Cetak', 'fa fa-print', function ($row) {
            return url('invoice/cetak/' . $row->id.'/'.$row->id_invoice);
        }, false);
        //Crypt::encryptString($row->id)
        $crud->callbackAddForm(function ($data) {
            $data['id_invoice'] = strtotime(date('Y-m-d H:i:s'));
            $data['inserted_by'] = Auth::user()->id;
            $data['inserted_time'] = date('Y-m-d H:i:s');
            return $data;
        });

        $crud->callbackEditForm(function ($data) {
            $data['updated_by'] = Auth::user()->id;
            $data['updated_time'] = date('Y-m-d H:i:s');
            return $data;
        });
        
        $crud->setCsrfTokenName('_token');
        $crud->setCsrfTokenValue(csrf_token());

        $output = $crud->render();
        $output->detail = 'N';
        return $this->_showOutput($output);
    }

    public function details()
    {
        $crud = $this->_getGroceryCrudEnterprise();
        $crud->setTable('kal_invoices_detail');
        $crud->setUniqueId('kal_invoices_detail');
        $crud->unsetDatagridTitle();
        $crud->unsetTools();
        $crud->unsetSearchColumns(['nama', 'jumlah', 'harga']);
        $crud->columns(['nama', 'jumlah', 'harga']);
        $crud->addFields(['fk_id_invoices', 'nama', 'jumlah', 'harga', 'inserted_by', 'inserted_time']);
        $crud->editFields(['fk_id_invoices', 'nama', 'jumlah', 'harga', 'updated_by', 'updated_time']);

        if (!empty($_POST['master_id'])) {
            if (is_numeric($_POST['master_id'])) {
                session(['master_id' => $_POST['master_id']]);
                $crud->where(['fk_id_invoices' => $_POST['master_id']]);
            } else {
                throw new InvalidArgumentException("Invalid argument for the field 'master_id'");
            }
        }
        $crud->fieldType('inserted_by', 'hidden');
        $crud->fieldType('inserted_time', 'hidden');
        $crud->fieldType('updated_by', 'hidden');
        $crud->fieldType('updated_time', 'hidden');
        $crud->fieldType('fk_id_invoices', 'hidden');

        $crud->callbackAddField('harga', function ($fieldType, $fieldName) {
            return '<input type="text" name ="harga" class = "form-control decimal">';
        });
        $crud->callbackAddField('harga', function ($fieldType, $fieldName) {
            return '<input type="text" name ="harga" class = "form-control decimal">';
        });

        $crud->callbackAddForm(function ($data) {
            $data['fk_id_invoices'] = session('master_id');
            $data['inserted_by'] = Auth::user()->id;
            $data['inserted_time'] = date('Y-m-d H:i:s');
            return $data;
        });

        $crud->callbackEditForm(function ($data) {
            $data['fk_id_invoices'] = session('master_id');
            $data['updated_by'] = Auth::user()->id;
            $data['updated_time'] = date('Y-m-d H:i:s');
            return $data;
        });
        
        $crud->setCsrfTokenName('_token');
        $crud->setCsrfTokenValue(csrf_token());

        $output = $crud->render();

        return $this->_showOutput_detail($output);
    }

Have you try reproduce this error @nasrul ?

yes john, it should be like this. But that didn’t work for me. Look at this video.

hello @heruprambadi

maybe you can check is fk_id_invoices inserted properly to database
if is not then maybe you can use callbackBeforeInsert instead of use callbackAddForm to insert fk_id_invoices

so your code became like this same as @johnny example given

$crud->callbackBeforeInsert(function ($stateParameters) {
if (!empty($_POST[‘master_id’])) {
if (is_numeric($_POST[‘master_id’])) {
$stateParameters->data[‘fk_id_invoices’] = $_POST[‘master_id’];
} else {
throw new InvalidArgumentException(“Invalid argument for the field ‘master_id’”);
}
}
return $stateParameters;
});

yes @nasrul , fk_id_invoices inserted to database.

fk_id_invoices should be 1.

also, please see this video.

hello @heruprambadi

Perhaps you can check first whether the inputted ‘fk_id_invoices’ variable corresponds to the selected row. For example, if you input a row with ‘id’ 1, the fk_id_invoices stored should also be 1.

If I use the ‘callbackBeforeInsert’ and the result is as I desired.

Hello @heruprambadi ,

The problem is that you use the session id and not the one passed from Grocery CRUD. More specifically from this code:

$crud->callbackAddForm(function ($data) {
            $data['fk_id_invoices'] = session('master_id');
            $data['inserted_by'] = Auth::user()->id;
            $data['inserted_time'] = date('Y-m-d H:i:s');
            return $data;
        });

So for you to work at the details function, you will need to do it like this:

$crud->callbackAddForm(function ($data) {
             // We removed the line $data['fk_id_invoices'] = session('master_id');
            $data['inserted_by'] = Auth::user()->id;
            $data['inserted_time'] = date('Y-m-d H:i:s');
            return $data;
        });

and then:

$crud->callbackBeforeInsert(function ($stateParameters) {

    if (!empty($_POST['master_id'])) {
        if (is_numeric($_POST['master_id'])) {
            $stateParameters->data['fk_id_invoices'] = $_POST['master_id'];
        } else {
            throw new InvalidArgumentException("Invalid argument for the field 'master_id'");
        }
    }

    return $stateParameters;
});

Let me know if that worked for you.

Regards
Johnny

Thank’s @johnny @nasrul , after i remove this line :

// We removed the line $data['fk_id_invoices'] = session('master_id');

and using callbackBeforeInsert that you suggested, it works !

But why this example not using callbackBeforeInsert ?

Which example are you referring to ? this one ?

Hello @heruprambadi Glad that it worked :smiley: ,

The example doesn’t use the add in the orders that’s why it is not needed. I may update the example in the future to also consider this as well.

@nasrul was referring to this example

1 Like