[Tutorial] How to Order/Sort child items in a Form View

After a code research, a found a way to order items in a child doctype in a Form View.

The Problem

I have a supplier that order all their items by Purchase Order and Item Code, and could be hundreds, so it was difficult to find them to check when numbers did not match.

  1. Create a Custom Button to Apply sorting on Refresh Event
  2. Apply the Order
  3. Reset Idx
  4. Refresh the Table

The Solution

frappe.ui.form.on('Purchase Invoice', {
    refresh(frm) {

        // Adding Custom Button
        frm.add_custom_button('[Action Name]', function() {
            let sorted = frm.doc["items"].sort(function(a, b) {

                // Sort by purchase_order
                // Convert to upper to avoid case mismatch
                const purchase_order_a = a.purchase_order.toUpperCase();
                const purchase_order_b = b.purchase_order.toUpperCase();

                // Then by item_code
                const item_code_a = a.item_code.toUpperCase();
                const item_code_b = b.item_code.toUpperCase();

                if (purchase_order_a < purchase_order_b) return -1;
                if (purchase_order_a > purchase_order_b) return 1;

                if (item_code_a < item_code_b) return -1;
                if (item_code_a > item_code_b) return 1;

                return 0;
            });

            for (let i = 0, j = sorted.length; i < j; i++) {
                let d = sorted[i];

                // Assign new Idx for each item in the table
                d.idx = i + 1;
            }

            // Refreshing field
            frm.refresh_field('items');

        }, '[Category]');
    },
})

If you have any doubt, let me know.

2 Likes