Populating child table in custom Dialog?

I’ve created a Dialog instance containing a child table and I want to populate it dynamically. It seems easy enough in a form but I’m having trouble understanding how to do the same thing in a Dialog.

The use case is that the dialog appears if an error is found while trying to create a shipping label. I want the user to be able to add any missing information in the dialog (for example missing country of origin or customs tariff code) before trying again to create the label.

The code I have so far is below. It displays an empty table and I can manually add a row and edit it. The links in the fields work correctly. However, I cannot populate the table programmatically.

Initially, I intuitively tried using err_dlg.add_child('customs_errors'); but received an error message that err_dlg did not have “add_child” so I tried using cur_frm instead. However, this gives the error “Cannot read properties of undefined (reading ‘options’)” instead and I don’t know why this is. Perhaps cur_frm isn’t the correct object to call add_child().

Can anyone shed any light on the correct way to add a child to a table in a custom dialog?

// Shipment error dialog
function error_dialog( errors ) {

    console.log( errors );

    const table_fields = [
        {
            fieldname: 'item_code',
            fieldtype: 'Link',
            in_list_view: 1,
            label: 'Item Code',
            options: 'Item',
            read_only: 1
        },
        {
            fieldname: 'country_of_origin',
            fieldtype: 'Link',
            in_list_view: 1,
            label: 'Country of Origin',
            options: 'Country',
            reqd: 1
        },
        {
            fieldname: 'customs_tariff_number',
            fieldtype: 'Link',
            in_list_view: 1,
            label: 'Tariff Number',
            options: 'Customs Tariff Number',
            reqd: 1
        },
    ]

    let err_dlg = new frappe.ui.Dialog({
        title: 'Shipment creation failed - action required',
        fields: [
            {
                fieldname: "filler",
                fieldtype: "HTML",
                label: "Test",
                options: '<h1>Test</H1>',
                reqd: 0
            },
            {
                label: 'Missing Customs Information',
                "allow_bulk_edit": 1,
                fieldname: 'customs_errors',
                fieldtype: 'Table',
                fields: table_fields,
                options: 'Item',
            },
        ],
        primary_action_label: 'Save',
        primary_action(values) {
            // TODO: Save amended values
            err_dlg.hide();
         }
    })

    err_dlg.show();  

    // Add any errors to the list
    $.each( errors, function(index, error) {
        if( error['type'] == 'customs' ) {
            var new_child = cur_frm.add_child('customs_errors');
            new_child.item_code = error['sku'];
            new_child.country_of_origin = error['coo'];
            new_child.customs_tariff_number = error['hs_code'];
            cur_frm.refresh_field('customs_errors');
            console.log( 'Added ' + error['sku'] );
        }
    })
}

image

OK, I’ve taken a slightly different approach to populating the table and am now specifying it as the “data” parameter in the table field. While I get no errors and the rows appear in the table, all the fields are blank. All the field values are valid links to documents. What do I need to do to make the data appear in the table rows?

// Shipment error dialog
function error_dialog( errors ) {

    console.log( errors );

    const table_fields = [
        {
            fieldname: 'item_code',
            fieldtype: 'Link',
            in_list_view: 1,
            label: 'Item Code',
            options: 'Item',
            read_only: 1
        },
        {
            fieldname: 'country_of_origin',
            fieldtype: 'Link',
            in_list_view: 1,
            label: 'Country of Origin',
            options: 'Country',
            reqd: 1
        },
        {
            fieldname: 'customs_tariff_number',
            fieldtype: 'Link',
            in_list_view: 1,
            label: 'Tariff Number',
            options: 'Customs Tariff Number',
            reqd: 1
        },
    ]

    let err_dlg = new frappe.ui.Dialog({
        title: 'Shipment creation failed - action required',
        fields: [
            {
                fieldname: "filler",
                fieldtype: "HTML",
                label: "Test",
                options: '<h1>Test</H1>',
                reqd: 0
            },
            {
                label: 'Missing Customs Information',
                fieldname: 'customs_errors',
                fieldtype: 'Table',
                fields: table_fields,
                options: 'Item',
                cannot_add_rows: 1,
                cannot_delete_rows : 1,
                data: [['SPW005', 'United Kingdom', '69120090'],['SPW005', 'United Kingdom', '69120090']]
            },
        ],
        primary_action_label: 'Save',
        primary_action(values) {
            // TODO: Save amended values
            err_dlg.hide();
         }
    })

    err_dlg.show();  
}

image

It’s working now. The table data rows need to be presented as dictionaries, not arrays.

function error_dialog( errors ) {

    console.log( errors );

    const table_fields = [
        {
            fieldname: 'item_code',
            fieldtype: 'Link',
            in_list_view: 1,
            label: 'Item Code',
            options: 'Item',
            read_only: 1
        },
        {
            fieldname: 'country_of_origin',
            fieldtype: 'Link',
            in_list_view: 1,
            label: 'Country of Origin',
            options: 'Country',
            reqd: 1
        },
        {
            fieldname: 'customs_tariff_number',
            fieldtype: 'Link',
            in_list_view: 1,
            label: 'Tariff Number',
            options: 'Customs Tariff Number',
            reqd: 1
        },
    ]

    let err_dlg = new frappe.ui.Dialog({
        title: 'Shipment creation failed - action required',
        fields: [
            {
                fieldname: "filler",
                fieldtype: "HTML",
                label: "Test",
                options: '<h1>Test</H1>',
                reqd: 0
            },
            {
                label: 'Missing Customs Information',
                fieldname: 'customs_errors',
                fieldtype: 'Table',
                fields: table_fields,
                options: 'Item',
                cannot_add_rows: 1,
                cannot_delete_rows : 1,
                data: [
                    {item_code:'SPW005', country_of_origin: 'United Kingdom', customs_tariff_number: '69120090'},
                    {item_code:'SPW005', country_of_origin: 'United Kingdom', customs_tariff_number: '69120090'},
                ]
            },
        ],
        primary_action_label: 'Save',
        primary_action(values) {
            // TODO: Save amended values
            err_dlg.hide();
         }
    })

    err_dlg.show();  
}

1 Like