[Solved] Removing a row in Child Table based on Table idx

I am trying to remove a row of Child Table in client side when a condition is valid.

In my code for the Child Table ‘Unbooked’ , I am getting the object I need to remove with:

frm.doc.unbooked[unbooked_idx]

What I have I tried:

frm.doc.unbooked.slice(unbooked_idx, -1)
frm.refresh_field('unbooked')
frm.get_field("unbooked").grid.grid_rows[unbooked_idx].remove()
frm.get_field("unbooked").grid.refresh()

Neither of those worked, any idea’s ?
Is it problem that nothing in my Child Table is a record in the database? I mean that the user manipulates the data and after that I update DocType records when user click save btn.

UPDATED WITH THE SOLUTION based on @rmehta comment :

frm.doc.unbooked.splice(frm.doc.unbooked[unbooked_idx], 1)
frm.refresh_field('unbooked')
3 Likes

updating frm.doc.unbooked and then doing frm.refresh_field should work

I don’t think slice works they way you want. You might want to use splice

@rmehta splice was my issue :slight_smile:

@kickapoo Hi would you mind sharing the complete script. I tried to replicate your code since I need it for the Payment Entry Reference. I need to remove the rows that I don’t want to create a payment Entry for. this is the code
frappe.ui.form.on("Payment Entry", "del_iv", function(frm, cdt, cdn) { frm.doc.references.splice(frm.doc.references[del_all], 0) frm.refresh_field('references') });

But I get this error in console
ReferenceError: del_all is not defined

Where del_iv is the button in the parent that triggers and del_all is the check which I want to tick and the ones that are ticked, must remain the rest of the rows must be removed. Appreciate your help.

Hey @mrmo,

I dont think sharing my code will do any help.

Your error message state that ‘del_all’ variable, where I assume is your index variable, is not defined. You have to define which ‘index’ you want to delete. Also, you have to think that `frm.doc.references[del_all]’ is a single DocType Instance of Referenses, and del_all is a integer index.

1 Like

@kickapoo Thanks for your explanation, I have found another way to remove the rows.
below the reference to the thread in case you want to remove multiple rows based on some criteria inside the child table.

for the Payment Entry doctype it is a bit more complicated because the server side scripts running on refresh for the references so I had to add some script on the server side.

On top of that I added a validate SUM on the client side for the field paid_amount so the user does not need to calculate the paid amount.

Python Server

    def clear_invoices(self):
        self.set("references", self.get("references", {"del_all": ["not in", [0, None, ""]]}))

        frappe.db.sql("""delete from `tabPayment Entry Reference` 
            where parent = %s and del_all = 0""", self.name)    

JS Server

    
    del_iv: function(frm) {
        return frappe.call({
            method: "clear_invoices",
            doc: frm.doc,
            callback: function(r, rt) {
                frm.refresh_fields();
            }
        });
    },
```

JS Client

```
frappe.ui.form.on("Payment Entry", "validate", function(frm, cdt, cdn) {
    // code for calculate total and set on parent field.
    rf = 0;
    $.each(frm.doc.references || [], function(i, d) {
        rf += flt(d.allocated_amount);
    });
    frm.set_value("paid_amount", rf);
});
```

@mrmo,

another alternative to remove the child table row would be to use the self.remove() method.

Please check the item.py.

Thanks, Makarand

2 Likes

Hello;

I have question about this code:
what the d means here?
And why we used with the or? What does it means?

Thanks in advance for the help.
Regards
Bilal

if not frm.doc.references use an empty array [] . This is javascript “hack” for the code not give a errors in empty case.

function(i, d) : index, whatever object in the loop of frm.doc.references. In this case is named d from doctype and is the same as frm.doc.references[i]

3 Likes

Hello;

Thanks a lot for your kindly reply and help.

So we can overcome this problem by having if statement to check if frm.doc.references if null or not. I have a question here: if there is no any document, what the returned value of frm.doc.references? Is it 0 or or false or null?

So each d is a document of the doctype, right?
Regards
Bilal