Grid row in child table not exiting editable mode on outside click (Unable to deselect row)

Hi everyone,

I am facing a UI/UX issue with child tables (grid) in Frappe/ERPNext and would appreciate guidance or a proper solution. I’m using v15


Issue Description

In doctypes like Sales Order, Quotation, and other forms with child tables:

  • When I click on a row (e.g., an Item row), it correctly enters editable mode
  • However, when I click anywhere outside the child table (form area, header, etc.), the row does not exit editable mode

Ideally, it should revert back to static display showing:

Item Code : Item Name


Steps to Reproduce

  1. Open Sales Order / Quotation
  2. Add or select an item in Items table
  3. Click on a row → it becomes editable
  4. Click anywhere outside the grid

Current Behavior

  • Row remains in editable mode
  • Does not revert to static display
  • Requires page refresh or selecting another row to reset

Expected Behavior

  • Clicking outside the grid should:
    • Exit editable mode
    • Return to static display
    • Show formatted values (Item Code : Item Name)

What I Tried

I created a custom script to handle deselection:

File:grid_deselection_handler.js
(function () {

"use strict";



console.log("\[GridDeselect\] Global handler active");



function force_grid_deselection() {

    if (!window.cur_frm || !cur_frm.fields_dict) return;



    if (document.activeElement && $(document.activeElement).closest('.form-grid').length) {

        document.activeElement.blur();

    }



    Object.keys(cur_frm.fields_dict).forEach(fieldname => {

        const field = cur_frm.fields_dict\[fieldname\];

        if (field && field.df && field.df.fieldtype === 'Table' && field.grid) {

            const grid = field.grid;



            if (grid.wrapper.find('.grid-row-open, .grid-row.active').length > 0) {

                try {

                    grid.row_display(null, false);

                    

                    grid.active_row = null;

                    grid.open_grid_row = null;

                    

                    grid.refresh();



                    if (typeof apply_profit_colors === 'function') {

                        apply_profit_colors(cur_frm);

                    }

                    

                    console.log(\`\[GridDeselect\] Table '${fieldname}' reset to view mode\`);

                } catch (err) {

                    console.debug("\[GridDeselect\] Error refreshing grid:", err);

                }

            }

        }

    });

}



window.addEventListener('mousedown', function(e) {

    if (!window.cur_frm) return;



    const is_inside_grid = $(e.target).closest('.form-grid').length > 0;

    const is_inside_ui_overlay = $(e.target).closest('.popover, .awesomplete, .link-field-results, .modal, .link-preview-box, .btn-open-row').length > 0;



    if (!is_inside_grid && !is_inside_ui_overlay) {

        setTimeout(force_grid_deselection, 200);

    }

}, true);

}());

Included via hooks:
app_include_js = [
“/assets/novasource/js/grid_deselection_handler.js”
]

I tried:

  • Blurring active element
  • Using frappe.ui.form.editable_row.toggle_editable_row(false)
  • DOM-based fallback handling

However, the row still remains in editable mode or sometimes re-enters edit mode due to internal grid click handling.


Technical Observation

From debugging, it seems:

  • Editable state is controlled by frappe.ui.form.editable_row
  • There is no global handler to reset this when clicking outside the grid
  • Grid column click events may be re-triggering edit mode

Questions

  1. Is this expected behavior in Frappe grid?
  2. Is there any standard way to:
    • Deselect a grid row
    • Exit editable mode on outside click
  3. Has anyone implemented a reliable solution for this?

Thanks in advance!