Dojo, how to make an widget notify EPiServer that another widgets value has been updated?

Vote:
 

I have a custom property that's works great except for one thing. It's a basic image editor, first the editor selects an image using a standard episerver image chooser, then the editor pushes a button that opens up a dialog window where it''s possible to crop the image.

The custom property looks like this,

public class ImageEditorBlock : SiteBlockData, IHtmlImage
{
    [Display(
        Name = "Image Url")]
    [UIHint(UIHint.Image)]
    [CultureSpecific]
    public virtual Url ImageUrl { get; set; }

    [Display(
        Name = "",
        Description = "")]
    [UIHint(Constants.SiteUIHints.ImageEditor)]
    [CultureSpecific]
    public virtual string Editor { get; set; }
}

    

The editor is simly a button to trigger a dialog window,

<div>
    <div data-dojo-type="dijit/form/Button" data-dojo-attach-point="btnImageEdit" data-dojo-props="label:'Crop image'" data-dojo-attach-event='onclick: onClick'></div>
</div>

    

When the the cropping is done the editor selects "Save" that closes the dialog and updates the value in the ImageUrl textbox. My problem is that EPiServer doesn't seem to detect that the value has been changed and therefore the autosave doesn't trigger. If I manually selects the textbox and then deselect it the autosave triggers.

So my question is how can I from a dojo widget (the dialog) trigger the autosave after I've updated the value in another widget (the url textbox)?

#76726
Oct 31, 2013 16:37
Vote:
 

The editor that has got a changed value need to call the event onChange with the new value. So when the dialog is closed you need to call:

this.onChange(newValue);

#76750
Nov 01, 2013 8:41
Vote:
 

Thanks for your answer Linus, unfortunately I'm still struggling with this.  I've tried to call onChange on almost every dojo object I can find. If I look at the source for the EPi url chooser it looks like this,

<div class="epi-formsWidgetWrapper" data-dojo-attach-point="containerNode"><div class="dijitReset dijitInputField dijitInputContainer dijitInline epi-resourceInputContainer dojoDndTarget dojoDndContainer" id="uniqName_108_0" data-dojo-attach-point="dropAreaNode" widgetid="uniqName_108_0">
    <div class="dijit dijitReset dijitInline dijitLeft dijitTextBox" id="widget_dijit_form_TextBox_0" role="presentation" widgetid="dijit_form_TextBox_0"><div class="dijitReset dijitInputField dijitInputContainer"><input class="dijitReset dijitInputInner" data-dojo-attach-point="textbox,focusNode" autocomplete="off" type="text" tabindex="0" id="dijit_form_TextBox_0" value="" aria-disabled="false"></div></div>
    <span class="dijit dijitReset dijitInline dijitButton" role="presentation" widgetid="dijit_form_Button_6"><span class="dijitReset dijitInline dijitButtonNode" data-dojo-attach-event="ondijitclick:_onClick" role="presentation"><span class="dijitReset dijitStretch dijitButtonContents" data-dojo-attach-point="titleNode,focusNode" role="button" aria-labelledby="dijit_form_Button_6_label" tabindex="0" id="dijit_form_Button_6" aria-disabled="false" style="-webkit-user-select: none;"><span class="dijitReset dijitInline dijitIcon dijitNoIcon" data-dojo-attach-point="iconNode"></span><span class="dijitReset dijitToggleButtonIconChar">●</span><span class="dijitReset dijitInline dijitButtonText" id="dijit_form_Button_6_label" data-dojo-attach-point="containerNode">...</span></span></span><input type="button" value="" class="dijitOffScreen" tabindex="-1" role="presentation" data-dojo-attach-point="valueNode"></span>
</div></div>

    

So on what object should I call onChange?

My code when I close the dialog looks like this,

_onHide: function (evt) {
            this.dialogImageEditor.destroy();
            this.isShowingChildDialog = false;
            
            var dojoObject = dijit.byId(imageChooser.id);
            //dojoObject.set("value", urlParts.path + cropQueryString);
            dojoObject.onChange(imageChooser.value);

            var inputField = dijit.byId(dojoObject.domNode.children[0].children[0].id);
            inputField.onChange(imageChooser.value);

            this.onChange(imageChooser.value);
        }

    

Any ideas? Or maybe an example of how to call onChange on another editor / widget?

#76762
Nov 01, 2013 10:37
Vote:
 

Also try the below options

inputField.setValue(imageChooser.value);
this._set("value", imageChooser.value);
this.onChange(value);

    

#76763
Nov 01, 2013 10:55
Vote:
 

Also, you can make the onBlur call into the Textbox

 

postCreate: function () {
 var inputField = dijit.byId(dojoObject.domNode.children[0].children[0].id);
this.connect(inputField, "onBlur", this._onChange);

}

_onChange: function ()
{
var inputField = dijit.byId(dojoObject.domNode.children[0].children[0].id);
inputField.setValue(imageChooser.value);
this._set("value", imageChooser.value);
this.onChange(value);

}

    

#76764
Nov 01, 2013 11:00
Vote:
 

Palani, thanks but still no luck. :-/

#76765
Nov 01, 2013 11:06
Vote:
 

Ok, If the textbox is a readonly property, then the change events are not fired. If thast's your case, please use the below code

var inputField = dijit.byId(dojoObject.domNode.children[0].children[0].id);

$(inputField).val(imageChooser.value).trigger('change');

    

#76766
Edited, Nov 01, 2013 11:18
Vote:
 

Palani, I really appreciate your help. But still no luck.

I've tried all your suggestions now. Nothings seems to make EPiServer understand that's the value's been changed. The only thing is if I manually clicks the textbox and then deselects it again. 

EDIT:

Here is my code if it helps, it's a bit of a mess at the moment though. http://chopapp.com/#eplutsr9

#76768
Edited, Nov 01, 2013 11:36
Vote:
 

If possible can you please share your Html template. In the meantime, please define the event in textbox itself and add the method into your JS file like below

 

<input type="text" data-dojo-attach-point="inputField" data-dojo-attach-event="onchange:_onChange" /> 


_onChange: function (event) {
    // summary:
    //    Handles the textbox change event and populates this to the onChange method.
    // tags:
    //    private

    this._set('value', event.target.value);
  this.inputField.set("value", value);
    this.onChange(this.value);
}

    

 

 

#76772
Nov 01, 2013 12:49
Vote:
 
<div>
    <div data-dojo-type="dijit/form/Button" data-dojo-attach-point="btnImageEdit" data-dojo-props="label:'Crop image'" data-dojo-attach-event='onclick: onClick'></div>
</div>

    

Sure, but as you see my html simply is a single button. The input field I'm using is simply a EPiServer Url chooser as you see in my first post.

#76787
Nov 01, 2013 13:28
Vote:
 

did anyone get anywhere with this. I've the exact same problem. I can prod a button to cause the episerver form to need a republish.

Have tried manually triggerring the onChange event and setting the value. No luck.

Changing a textbox kworks fine - just like Daniel

 

#82869
Mar 20, 2014 16:31
Vote:
 

My collegue Duong an Nguyen has written a blog post that might be of interest for you following this thread:

http://world.episerver.com/Blogs/Duong-Nguyen/Dates/2014/1/Country-Region-drop-down-lists-in-All-properties-mode/

#83207
Mar 27, 2014 14:35
Vote:
 

Hi, Daniel and Tim, have you had any luck triggering an event?

I am trying to trigger an onChange event when input type="hidden" changes.

    var pageWidget = getPageWidget(hyperLinkSelector.wrappers);
    if (pageWidget && pageWidget.length > 0) {
        var input = pageWidget[0].inputWidget.input;
        // input is the hidden field
        input.setAttribute("data-dojo-attach-event", "onChange:nodeOnChange");
        input.setAttribute("data-dojo-type", "dijit/form/TextBox");

        on(input, "change", function () {
            var test = xx"; // never gets hit
        });

        // another try with PageChangedEventDijit
        var mydijit = new PageChangedEventDijit({}, input);
        mydijit.startup();
    }

    

PageChangedEventDijit:

define([
    "dojo/_base/declare",

    "dijit/_WidgetBase",
    "dijit/_AttachMixin"
],
function (
    declare,

    _WidgetBase,
    _AttachMixin
) {

    return declare("PageChangedEventDijit",
        [_WidgetBase, _AttachMixin], {
            nodeOnChange: function (e) {
                var test = "test";
            }
    });
});

 No breakpoints are hit when the hidden field is hit, however, the markup is changed to:

<input type="hidden" data-dojo-attach-point="input" data-dojo-attach-event="onChange:nodeOnChange" data-dojo-type="dijit/form/TextBox" id="PageChangedEventDijit_0" widgetid="PageChangedEventDijit_0" value="15_774">

I've also tried calling parser.parse after adding the attributes to the hidden field.

#84457
Apr 02, 2014 12:44
Vote:
 

Hi,

I struggled with this and setting this.isShowingChildDialog = true; when opening the dialog and setting this.isShowingChildDialog = false; when closing the dialog solved it for me.

#112268
Oct 27, 2014 11:55
Vote:
 

Hi,

I had the same issue: when you update the value of the widget then publishing event is not triggered and new value is not stored to the server.

And this doesn't work when you use a Dialog or when you close it.

To fix it you should to redirect focus to this:

//take focus to main control
this.onFocus();
//update a value
this.value = result;
//trigger change event
this.onChange(this.value);



#143876
Feb 02, 2016 17:17
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.