Search for Item Attributes when creating multiple variations

It would be great if we’d have a search field just like we have a search option in the Item Attribute screen or other child tables.

1 Like

did you find the solution
can anyone tell is it possible somehow from the code, to add a search box
any help please

use below solution
i updated the code in item.js file of erpnext

show_multiple_variants_dialog: function(frm) {
    var me = this;

    let promises = [];
    let attr_val_fields = {};

    function make_fields_from_attribute_values(attr_dict) {
        let fields = [];
        Object.keys(attr_dict).forEach((name, i) => {
            if (i % 3 === 0) {
                fields.push({ fieldtype: 'Section Break' });
            }

            fields.push({ fieldtype: 'Column Break', label: name });

            // Add a search field
            fields.push({
                fieldtype: 'Data',
                label: __('Search {0}', [name]),
                fieldname: `${name}_search`,
                onchange: function () {
                    let search_value = this.get_value().toLowerCase();
                    // Filter checkboxes dynamically
                    let checkboxes = $(this.wrapper).parent().find('.checkbox');
                    checkboxes.each(function () {
                        let label = $(this).find('label').text().toLowerCase();
                        if (label.includes(search_value)) {
                            $(this).show();
                        } else {
                            $(this).hide();
                        }
                    });
                }
            });

            attr_dict[name].forEach(value => {
                fields.push({
                    fieldtype: 'Check',
                    label: value,
                    fieldname: value,
                    default: 0,
                    onchange: function () {
                        let selected_attributes = get_selected_attributes();
                        let lengths = [];
                        Object.keys(selected_attributes).map(key => {
                            lengths.push(selected_attributes[key].length);
                        });
                        if (lengths.includes(0)) {
                            me.multiple_variant_dialog.get_primary_btn().html(__('Create Variants'));
                            me.multiple_variant_dialog.disable_primary_action();
                        } else {
                            let no_of_combinations = lengths.reduce((a, b) => a * b, 1);
                            let msg;
                            if (no_of_combinations === 1) {
                                msg = __("Make {0} Variant", [no_of_combinations]);
                            } else {
                                msg = __("Make {0} Variants", [no_of_combinations]);
                            }
                            me.multiple_variant_dialog.get_primary_btn().html(msg);
                            me.multiple_variant_dialog.enable_primary_action();
                        }
                    }
                });
            });
        });
        return fields;
    }

    function make_and_show_dialog(fields) {
        me.multiple_variant_dialog = new frappe.ui.Dialog({
            title: __("Select Attribute Values"),
            fields: [
                {
                    fieldtype: "HTML",
                    fieldname: "help",
                    options: `<label class="control-label">
                        ${__("Select at least one value from each of the attributes.")}
                    </label>`,
                }
            ].concat(fields)
        });

        me.multiple_variant_dialog.set_primary_action(__('Create Variants'), () => {
            let selected_attributes = get_selected_attributes();

            me.multiple_variant_dialog.hide();
            frappe.call({
                method: "erpnext.controllers.item_variant.enqueue_multiple_variant_creation",
                args: {
                    "item": frm.doc.name,
                    "args": selected_attributes
                },
                callback: function(r) {
                    if (r.message === 'queued') {
                        frappe.show_alert({
                            message: __("Variant creation has been queued."),
                            indicator: 'orange'
                        });
                    } else {
                        frappe.show_alert({
                            message: __("{0} variants created.", [r.message]),
                            indicator: 'green'
                        });
                    }
                }
            });
        });

        $($(me.multiple_variant_dialog.$wrapper.find('.form-column'))
            .find('.frappe-control')).css('margin-bottom', '0px');

        me.multiple_variant_dialog.disable_primary_action();
        me.multiple_variant_dialog.clear();
        me.multiple_variant_dialog.show();
    }

    function get_selected_attributes() {
        let selected_attributes = {};
        me.multiple_variant_dialog.$wrapper.find('.form-column').each((i, col) => {
            if (i === 0) return;
            let attribute_name = $(col).find('label').html().trim();
            selected_attributes[attribute_name] = [];
            let checked_opts = $(col).find('.checkbox input');
            checked_opts.each((i, opt) => {
                if ($(opt).is(':checked')) {
                    selected_attributes[attribute_name].push($(opt).attr('data-fieldname'));
                }
            });
        });

        return selected_attributes;
    }

    frm.doc.attributes.forEach(function(d) {
        let p = new Promise(resolve => {
            if (!d.numeric_values) {
                frappe.call({
                    method: "frappe.client.get_list",
                    args: {
                        doctype: "Item Attribute Value",
                        filters: [
                            ["parent", "=", d.attribute]
                        ],
                        fields: ["attribute_value"],
                        limit_page_length: 0,
                        parent: "Item Attribute",
                        order_by: "idx"
                    }
                }).then((r) => {
                    if (r.message) {
                        attr_val_fields[d.attribute] = r.message.map(function(d) { return d.attribute_value; });
                        resolve();
                    }
                });
            } else {
                frappe.call({
                    method: "frappe.client.get",
                    args: {
                        doctype: "Item Attribute",
                        name: d.attribute
                    }
                }).then((r) => {
                    if (r.message) {
                        const from = r.message.from_range;
                        const to = r.message.to_range;
                        const increment = r.message.increment;

                        let values = [];
                        for (var i = from; i <= to; i = flt(i + increment, 6)) {
                            values.push(i);
                        }
                        attr_val_fields[d.attribute] = values;
                        resolve();
                    }
                });
            }
        });

        promises.push(p);

    }, this);

    Promise.all(promises).then(() => {
        let fields = make_fields_from_attribute_values(attr_val_fields);
        make_and_show_dialog(fields);
    });
},

3 Likes