Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more

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.