bryntum / support

An issues-only repository for the Bryntum project management component suite which includes powerful Grid, Scheduler, Calendar, Kanban Task Board and Gantt chart components all built in pure JS / CSS / TypeScript
https://www.bryntum.com
54 stars 6 forks source link

`Container` should be able to track presence of changes to its fields #9772

Closed ExtAnimal closed 2 months ago

ExtAnimal commented 3 months ago

Forum post

Container.js needs:

    /**
     * A function called by descendant widgets after they trigger their 'change' event, in reaction to field changes.
     * By default, implements the functionality for the `autoUpdateRecord` config.
     *
     * @param {Object} params Normally the event params used when triggering the 'change' event
     * @internal
     */
    onFieldChange({ source, userAction }) {
        if (userAction) {
            const { initialValues } = this;

            // When configured with `autoUpdateRecord`, changes from descendant fields/widgets are applied to the loaded
            // record using the fields `name`. Only changes from valid fields will be applied
            if (this.autoUpdateRecord) {
                const
                    { record, strictRecordMapping } = this,
                    { name, ref, isValid = true, defaultBindProperty } = source,
                    value                           = source[defaultBindProperty || 'value'],
                    key                             = strictRecordMapping ? name : name || ref;

                if (record && key && isValid) {
                    if (record.isModel) {
                        record.setValue(key, value);
                    }
                    else {
                        record[key] = value;
                    }
                }
            }
            if (initialValues) {
                (this.changeSet || (this.changeSet = {}))[source.name] = !ObjectHelper.isEqual(source.value, initialValues[source.getValueName(initialValues.__options)]);
            }
        }
    }

    get hasChanges() {
        return Boolean(this.changeSet && Object.values(this.changeSet).some(v => v));
    }

    setValues(values, options = this.assignValueDefaults) {
        // Flag checked by Field to determine if it should highlight change or not
        this.assigningValues = options;

        // inital value set for calculating the hasChanges property
        this.initialValues = {
            __options : options
        };

        this.eachWidget(widget => {
            const key = widget.getValueName(options);

            if (key && (!values || key in values)) {
                this.initialValues[key] = values?.[key] || null;
            }
            widget.assignValue(values, options);
        }, false);

        this.assigningValues = false;
    }