2

I have developed a dijit widget for EPiServer. Within the widget there is a FilteringSElect which gets it's data from a REST store. The values that populate the FilteringSelect are a numerical Id and a text value.

When EPiServer saves the value, it is the numerical value (Id) that is saved.

My entire widget looks like so:

{

return declare("communityuser.editors.CommunityUserSelector", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin, _ValueRequiredMixin], {

    templateString: "<div class=\"dijitInline\">\
                        <div data-dojo-attach-point=\"stateNode, tooltipNode\">\
                            <div data-dojo-attach-point=\"inputWidget\" data-dojo-type=\"dijit.form.FilteringSelect\" style=\"width: 300px\"></div><span style=\"padding-left:10px;\"><a href=\"#\" data-dojo-attach-point=\"resetLink\">Reset</a></span>\
                        </div>\
                    </div>",

    intermediateChanges: false,

    value: null,

    store: null,

    onChange: function (value) {
        // Event
    },

    postCreate: function () {
        // call base implementation
        this.inherited(arguments);

        // Init textarea and bind event
        this.inputWidget.set("intermediateChanges", this.intermediateChanges);

        //set whether the internal required property is true
        this.inputWidget.set('required', false);

        //get a reference to the CommunityUserStore
        var registry = dependency.resolve("epi.storeregistry");
        this.store = this.store || registry.get("customquery");

        //set the store for the FilteringSelect
        this.inputWidget.set("store", this.store);

        //connect the onChange event for the FilteringSelect
        this.connect(this.inputWidget, "onChange", this._onInputWidgetChanged);

        //connect the onclick event for the Reset Link
        this.connect(this.resetLink, "onclick", this._onResetClicked);
    },

    isValid: function () {
        // summary:
        //    Check if widget's value is valid.
        // tags:
        //    protected, override

        return true;
    },

    // Setter for value property
    _setValueAttr: function (value) {

        if (!value) {
            return;
        }

        //set the value of the FilteringSelect and the value of the parent control
        this.inputWidget.set("value", value.userId);
        this._set("value", this._serializeUser(value));
    },

    // Event handler for the changed event of the input widget
    _onInputWidgetChanged: function (value) {

        this._updateValue(value);
    },

    //Event handler when the Selection in the FilteringSelect is changed
    _updateValue: function (value) {

        //check whether the initial value matches the new value i.e. the value after the selection has changed
        if (this._started && epi.areEqual(this.value, this._serializeUser(value))) {
            return;
        }

        //create an object representation of the value
        var formattedValue = (!value) ? {} : this._serializeUser(value);

        this._set("value", formattedValue);
        this.onChange(formattedValue);
    },

    _onResetClicked: function (event) {

        event.preventDefault();
        this.inputWidget.reset();

    },

    _serializeUser: function(userId) {

        return ({userId: userId });

    },

});

This may not be the correct way to write a dojo/dijit widget - it's my first.

In my Rest Store I have two methods, Get(string name) and GetUserById(int userId).

The values of the Get method are returned, I presume because Get is the default method dojo is looking for. Therefore after loading when the user types a value into the FilteringSelect or selects the pulldown from the FilteringSelect, it is populated with all the values returned from the Get method.

However, if when the widget loads it already has a value (because it was saved in EPiServer) I want to call a different method from my store and return just 1 record - in this instance the record to be returned would be a user account that has the same Id.

Id | Value 1 | "User 1" 2 | "User 2" 3 | "User 3"

What I am struggling with is how to call the method from the store, and then show the value returned in the FilteringSelect.

This is the first time I have used either dojo or dijit so i might be doing soemthing fundamentally wrong.

Can anyone give me a pointer please?

Many thanks Al

higgsy
  • 1,991
  • 8
  • 30
  • 47

1 Answers1

3

For FilteringSelect, there are three attributes you can set: "searchAttr", "labelAttr" and "value". You can set "searchAttr" to the property name in your data which can do a filtering search, set "labelAttr" to the property name of your data which will show in the UI, and set "value" as you current selected id. like

var selector = new FilteringSelect({
    searchAttr:"label",  //label is property name in your data
    labelAttr:"label", 
    required:false,
    value:"selectedId",
    store: dojo.store.Observable(new dojo.store.Memory({
        idProperty:"name",   //if your store key property is not "id", instead of it is "name", you can set like this
        data: []    
    }))
    }, dojo.create("span", null, yourDiv)
);

You can use

selector.get('value);
selector.set('value', yourValue); 

_setValueAttr and _set is not recommanded to use in your code directly.

Wish this help.

Sean Zhao
  • 1,506
  • 12
  • 12