Try our conversational search powered by Generative AI!

How to get value from Dojo Dialog back to Custom Widjit

Vote:
 

We are trying to create a property where the user can search for things in a dojo dialog popup and select one item from a list and after that we need to save the selected value to our EPiServer property.

The problem now is that we can´t figure out on how to get the value from the dialog back to the main widjit. The code we have is fist the main js-file

define([
    "dojo/_base/declare",
    "dijit/_WidgetBase",
    "dijit/_TemplatedMixin",
    "dojo/store/JsonRest",
    "epi/routes"
], function (
    declare,
    _WidgetBase,
    _TemplatedMixin
) {
    return declare("site.editors.FilmSearchEditor", [_WidgetBase, _TemplatedMixin], {
            templateString:
            '<div class=\"dijitInline\">' +
                '<div id="selectedFilm" style="margin-left:175px"></div>' +
                '<input type="button" value="Search" id="searchButton" data-dojo-attach-event="onclick:showDialog" />' +
                '<div data-dojo-id="myExternalDialog" data-dojo-type="dijit/Dialog" title="My external dialog" href=""></div>' +
            '</div>',
            postCreate: function () {
                // call base implementation
                this.inherited(arguments);
            },
             onCancel:function() {
                 console.log("Event Cancelled");
             },
            showDialog: function (title, action, evt) {
                var dialog = dijit.byId('myExternalDialog');
                if (dialog) { dialog.destroyRecursive(); }

                dialog = new dijit.Dialog({
                    href: "/filmsearch",
                    refreshOnShow: true,
                    id: 'myExternalDialog',
                    title: title,
                    onDownloadEnd: dojo.hitch(this, this.initializeDialog, action, evt)
                });

                dialog.show();
            },
            intermediateChanges: false,
            value: null,
            filmSelected: function () {
                //get the selected film and update the property
            }
        });
});

The dialog will show content from this view:

@model FilmSearchViewModel

<form data-dojo-type="dijit/form/Form" id="searchForm" data-dojo-id="searchForm" action="" method="">
    <input data-dojo-type="dijit.form.TextBox" type="text" id="searchText" name="searchText" value="" trim="true" />
    <input data-dojo-type="dijit.form.TextBox" type="hidden" id="selectedFilmId" name="selectedFilmId" value="" />
    <div data-dojo-type="dijit/form/Button">
        Sök
        <script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
            dojo.xhrGet({
                url: "@Url.Action("Search")",

                form: "searchForm",
                handleAs: "text",
                timeout: 5000,

                load: function(response, ioArgs){
                    dojo.byId("results").innerHTML = response;

                    // return the response for succeeding callbacks
                    return response;
                },

                error: function(response, ioArgs){
                    dojo.byId("results").innerHTML = "Form submission failed.";
                    return response;
                }
            });
        </script>
    </div>
<br>
<strong>Sökresultat :</strong>
<br>
<div id="results"></div>
<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="submitButton" type="submit" value="OK" />
<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="cancelButton">
</form>

We need to get the value of selectedFilmId and return it to the widjit (We have code that shows the search result like this:

@model FilmSearchViewModel

@if (Model.FileSearchResults != null && Model.FileSearchResults.Count > 0)
{
    
    <ul>
        @foreach (var film in Model.FileSearchResults)
        {
            <li>
                @Html.RadioButton("SelectFilm",film.ExternalId.ToString(),new {data_dojo_type="dijit/form/RadioButton"})
                @film.Title @(film.SwedishTitle != film.Title ? string.Format("({0})", film.SwedishTitle) : "")
            </li>    
        }
    </ul>
    <input type="button" id="selectFilmButton" value="Välj film"/>
    
}

We know that the code for population the hidden value is not there and we will implement it but our propblem is how to connect the hidden value back to the main widjit.

Anyone who is a Dojo expert and can help a Dojo newbe ;-)

#85903
May 08, 2014 11:20
Vote:
 

In theory, it should be as easy as suppling an execute method to the dialog arguments:

execute: function(value) {
    alert(value);
}

You may have to change your movie selection button to a dijit button.

#85923
May 08, 2014 16:15
Vote:
 

Thanks stefan. Will try I out on Monday.

#85986
May 09, 2014 15:42
Vote:
 

Stefan, that will not work, I found this:

"In order to run Dialog's execute-method the submit button has to be a dijit.form.Button, normal submit button doesn't trigger this function. In addition, the form has to be local, the dialog doesn't find the form values if it's included via href attribute."

We cant have our form local since it will do a lot of logic and is now a MVC action.

I found that text here: 

http://livedocs.dojotoolkit.org/dijit/Dialog

 

#86015
Edited, May 12, 2014 10:15
Vote:
 

Another DOJO day, another failure :(

I am soooooo close to a working solution, but it is failing me.
I got all the steps working, but not the complete picure. Here is my code now:

define([
    "dojo/_base/array",
    "dojo/_base/connect",
    "dojo/_base/declare",
    "dojo/_base/lang",

    "dijit/_CssStateMixin",
    "dijit/_Widget",
    "dijit/_TemplatedMixin",
    "dijit/_WidgetsInTemplateMixin",

    "dijit/layout/ContentPane",

    "epi/epi",
    "epi/shell/widget/_ValueRequiredMixin"
],
function (
    array,
    connect,
    declare,
    lang,

    _CssStateMixin,
    _Widget,
    _TemplatedMixin,
    _WidgetsInTemplateMixin,

    ContentPane,
    epi,
    _ValueRequiredMixin
) {

    return declare("customer.editors.FilmSearchEditor", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin, _ValueRequiredMixin], {

        templateString: '<div class="dijitInline">' +    
                            '<div>' +    
                        '       <div data-dojo-attach-point="selectedFilm" data-dojo-type="dijit/layout/ContentPane"></div>' +
                        '       <input type="button" value="Search" data-dojo-attach-point="searchButton" />' +
                        '       <div data-dojo-id="myExternalDialog" data-dojo-type="dijit/Dialog" title="Filmsearch">' +
                        '       <div class="dijitDialogPaneContentArea">' +
                        '       <form data-dojo-type="dijit/form/Form" id="searchForm" data-dojo-id="searchForm" action="" method="">' +    
                        '            <input data-dojo-type="dijit.form.TextBox" type="text" id="searchText" name="searchText" value="" trim="true" />' +
                        '           <input data-dojo-type="dijit.form.TextBox" type="hidden" id="selectedFilmId" name="selectedFilmId" value="HIDDEN" />' +
                        '            <div data-dojo-type="dijit/form/Button">' +
                        '             Sök' +
                        '             <script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">' +
                        '                 dojo.xhrGet({' +
                        '                        url: "/filmeditor/SearchResults",' +
                        '                      form: "searchForm",' +
                        '                     handleAs: "text",' +
                        '                     timeout: 5000,' +
                        '                    load: function(response, ioArgs){' +
                        '                         dojo.byId("results").innerHTML = response;' +
                        '                         return response;' +
                        '                     },' +
                        '                     error: function(response, ioArgs){' +
                        '                         dojo.byId("results").innerHTML = "Form submission failed.";' +
                        '                         return response;' +
                        '                     }' +
                        '                 });' +
                        '             </script>' +
                        '         </form>' +
                        '         </div>' +
                        '       <br>' +
                        '       </div>' + 
                        '       <strong>Sökresultat</strong>' +
                        '           <div id="results"></div>' +
                        '         <button data-dojo-type="dijit/form/Button" type="submit" data-dojo-attach-point="selectButton">' +
                        '             Välj film' +
                        '         </button>' +
                        '       </div>' +
                        '    </div>' +
                        '</div>',

        
        intermediateChanges: false,

        value: null,

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

            _onSearchButtonClicked: function () {
	        myExternalDialog.title = "Sök film";
            myExternalDialog.show();

	    },

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

            // Init textbox and bind event
            this.selectedFilm.set("href", "/filmeditor/?id=" + this.value);

            this.connect(this.searchButton, "onclick", this._onSearchButtonClicked);

            this.connect(myExternalDialog, "hide", function (e) {
                var selected = $('input:radio[name=SelectFilm]:checked').val();
                if (selected != null) {
                    this._setValueAttr(selected);
                }
            });
        },

        isValid: function () {
            return !this.required || this.value.length > 0;
        },

        // Setter for value property
        _setValueAttr: function (value) {
            this._setValue(value, true);
        },

        _setReadOnlyAttr: function (value) {
            this._set("readOnly", value);
        },

        _setValue: function (value) {

            if (this._started && epi.areEqual(this.value, value)) {
                return;
            }

            // set value to this widget (and notify observers)
            this._set("value", value);

            
            if (this._started) {
                // Trigger change event
                this.onChange(value);
            }
        }
    });
});

I get it to open the dialog, do the search, get the value when they press select movie and get it to trigger this.OnChange with the new value. The thing that is not working is that EPiServer is not acting as something has changed and the value does not get saved to the database. There are no javascript errors reported.
If I try to see if the connection to the update event works with putting this changing the _onSearchButtonClicked event to like this

_onSearchButtonClicked: function () {
	        myExternalDialog.title = "Sök film";
                myExternalDialog.show();

                 this._setValue("Klicked " + Math.floor((Math.random() * 1000000) + 1));
	    },

    EPiServer are seeing that there are a new value and triggers the publish-button.

I also have problem with that after I have made a publish, I get this error:

"Tried to register widget with id==searchForm but that id is already registered"
 
Please someone help me with this, I am going DOJO-insane!
#86030
Edited, May 12, 2014 16:28
Vote:
 

When specifying id attributes in templates they will be used and you will run into conflicts if the widget is used multiple times ("Tried to register widget with id==... ").
Use data-dojo-attach-point instead if you want to reference nodes in the template, then the id will be auto-generated.

When it comes to your missing change events; is myExternalDialog defined in postCreate? Looks like you shold use data-dojo-attach-point and reference it with this.myExternalDialog

#86047
May 13, 2014 8:58
* 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.