November Happy Hour will be moved to Thursday December 5th.

onChange in dojo does not trigger page save if widget is not focused

Vote:
 

I have a custom dojo plugin that uses a jquery dropdown plugin where the user selects one or more items, those items are added to the dojo textbox.

But whenever I fire onChange, the page save doesn't trigger. It only triggers if the original textbox is focused by the user.

In order to condense the problem I've written a short example of the problem

(To test just run saveNewValue() from console to trigger pagesave)

If I manually change the value of the textbox, the page save and publish options functions as it should.

var myDojo = undefined;

function saveNewValue() {
    console.log('Trying to save new value');
    myDojo._saveNewValue('123');
}

define([
    "dojo/on", // To connect events
    "dojo/_base/declare", // Used to declare the actual widget

    "dojo/aspect", // Used to attach to events in an aspect-oriented way to inject behaviors

    "dijit/registry", // Used to get access to other dijits in the app
    "dijit/WidgetSet", // To be able to use 'byClass' when querying the dijit registry

    "dijit/_Widget", // Base class for all widgets
    "dijit/_TemplatedMixin",

    "epi/epi", // For example to use areEqual to compare property values
    "epi/shell/widget/_ValueRequiredMixin", // In order to check if the property is in a readonly state
    "epi-cms/widget/_HasChildDialogMixin",

    "dijit/form/TextBox",
    "dojo/_base/lang"
],
function (
    on,
    declare,

    aspect,

    registry,
    WidgetSet,

    _Widget,
    _TemplatedMixin,

    epi,
    _ValueRequiredMixin,
    _HasChildDialogMixin,

    TextBox,
    lang
    ) {

    return declare([_Widget, _TemplatedMixin, _ValueRequiredMixin, _HasChildDialogMixin, TextBox], {
        intermediateChanges: true,
        onChange: function (value) {
        },
        isValid: function () {
            return true;
        },
        postCreate: function () {
            this.inherited(arguments);

            myDojo = this;
        },
        _setValueAttr: function (value) {
            if (value === this.value) {
                return;
            }

            this._set("value", value);
            this.textbox.value = value;
        },
        _saveNewValue: function (value) {
            if (!this._started) {
                return;
            }

            console.log('saving');

            $(this.textbox).focus();
            this.textbox.value = value;
            this._set("value", value);

            this.onChange(value);
        }  
    });
});

Any tips?

#144890
Feb 22, 2016 11:55
Vote:
 

Hi bar10dr,

Appreciate the simplified example.

I'd start by removing your _setValueAttr you're overriding the base functionality and not calling the original function, which is done via:

this.inherited(arguments);

Anyway, more on that here: https://g00glen00b.be/dojo-inheritance-overriding-extending/

Then you don't need to set both the value and textbox value with:

this.textbox.value = value;
this._set("value", value);

You can just call:

this._setValueAttr(value);

which is preferred.

The key thing is then that you need to set the focus with:

this.onFocus();

Long story short, the following should work:

return declare([_Widget, _TemplatedMixin, _ValueRequiredMixin, _HasChildDialogMixin, TextBox], {
    intermediateChanges: true,
    isValid: function () {
        return true;
    },
    postCreate: function () {
        this.inherited(arguments);

        myDojo = this;
    },
    _saveNewValue: function (value) {
        if (!this._started) {
            return;
        }

        console.log('saving');

        this.onFocus();
        this._setValueAttr(value);
    }
});
#201940
Mar 07, 2019 17:24
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.