Phix
Phix

Reputation: 9880

Adding content to dijit Dialog

I've looked at quite a few links for people trying to add content / change the template for a Dojo Dialog. This was the most promising.

However, whenever I do something like this:

Dialog declared in HTML:

<div class="djDialog" id="dgViewer" data-dojo-type="TemplatedDialog" data-dojo-props="title: 'My Dialog', draggable:false"></div>

Dialog Template:

<div class="dijitDialog" role="dialog" aria-labelledby="${id}_title">
    <div data-dojo-attach-point="titleBar" class="dijitDialogTitleBar">
        <span data-dojo-attach-point="titleNode" class="dijitDialogTitle" id="${id}_title"></span>
        <span data-dojo-attach-point="closeButtonNode" class="dijitDialogCloseIcon" data-dojo-attach-event="ondijitclick: onCancel" title="${buttonCancel}" role="button" tabIndex="-1">
            <span data-dojo-attach-point="closeText" class="closeText" title="${buttonCancel}">x</span>
        </span>
    </div>
    <!-- containerNode from original Dialog template -->
    <div data-dojo-attach-point="containerNode" class="dijitDialogPaneContent">
        <!-- All "custom" content -->
        <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'" style="height:300px">
            <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'">

            </div>
            <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'">
                <button data-dojo-type="dijit.form.Button">Edit</button>
                <button data-dojo-type="dijit.form.Button">Status</button>
            </div>
        </div>
        <!-- End "custom" content -->
    </div>
</div>

Custom Dialog class:

define([
    'dojo/_base/declare',
    'dijit/Dialog', 
    'dijit/_TemplatedMixin',
    'dojo/text!./dialog_templates/View.html'], 
    function(
        declare, 
        Dialog, 
        _Mixin,
        _template){
    return declare('TemplatedDialog', [Dialog, _Mixin], {    
        templateString : _template,
        constructor : function(){

        }
    })
})

In my console (using Chrome) I just see:

<div data-dojo-attach-point="containerNode" class="dijitDialogPaneContent" style="width: auto; height: auto; "></div>

... and empty node where content should be.

So far I haven't found anyone who seems to have successfully extended dijit.Dialog in terms of templates. Is this possible?

Edit

After trying some variations on this template:

<div class="dijitDialog" role="dialog" aria-labelledby="${id}_title">
    <div data-dojo-attach-point="titleBar" class="dijitDialogTitleBar">
        <span data-dojo-attach-point="titleNode" class="dijitDialogTitle" id="${id}_title"></span>
        <span data-dojo-attach-point="closeButtonNode" class="dijitDialogCloseIcon" data-dojo-attach-event="ondijitclick: onCancel" title="${buttonCancel}" role="button" tabIndex="-1">
            <span data-dojo-attach-point="closeText" class="closeText" title="${buttonCancel}">x</span>
        </span>
    </div>
    <!-- containerNode from original Dialog template -->
    <div class="dijitDialogPaneContent">
        <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'" style="height:100%;width:100%">
            <div data-dojo-attach-point="containerNode" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"></div>
        </div>
        <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'bottom'">
            <button data-dojo-type="dijit.form.Button">Edit</button>
        </div>
    </div>
</div>

The error Uncaught TypeError: Cannot read property '0' of undefined is being thrown. This is the stack, if it helps. I'm using the uncompressed version from the Google CDN to help in debugging.

_childElements          dojo.js.uncompressed.js:8341
getStepQueryFunc        dojo.js.uncompressed.js:8597
query                   dojo.js.uncompressed.js:9005
query                   dojo.js.uncompressed.js:5248
_2._checkIfSingleChild  _ContentPaneResizeMixin.js:2
_4._size                Dialog.js:2
_4.show                 Dialog.js:2

Removing the data-dojo-type and -props from the containerNode resolves this, but it's still not getting things closer to having a working custom templated Dialog.

Upvotes: 1

Views: 9103

Answers (1)

mschr
mschr

Reputation: 8641

Reason for troubles with doing templating on a contentpane is, that whatever template-contents you put into the domNode referenced with the attach-point 'containerNode', you will loose on startup.

If there is no 'href' nor 'content' attributes set, they will simply be set to an empty string, thus leaving the Dialog.containerNode.innerHTML == ""

You have no need for deriving from _TemplatedMixin as the Dialog itself is a templated widget. Instead change this to _WidgetsInTemplateMixin to compensate for the BorderContainer layout widgets and your dijit.form contents. Also, your markup within the custom template should be pre-required, so you could go with something like this here:

Change the template from old attachpoint for container to this

<div data-dojo-attach-point="containerNode" 
     data-dojo-type="dijit.layout.ContentPane"
     data-dojo-props="region:'center'">

Then add requirements to your markup widgets in the template plus the _WidgetsInTemplateMixin:

define(["dijit/Dialog",
    "dijit/_WidgetsInTemplateMixin",
    "dojo/text!./dialog_templates/View.html",
    // rest are for rendering example
    "dijit/layout/BorderContainer",
    "dijit/layout/ContentPane",
    "dijit/form/Button"
}. ... );

Result should ressemble this, keeping your template View.html change in mind:

define([
    'dojo/_base/declare',
    'dijit/Dialog', 
    "dijit/_WidgetsInTemplateMixin",
    "dojo/text!./dialog_templates/View.html",
        // rest are for rendering example
    "dijit/layout/BorderContainer",
    "dijit/layout/ContentPane",
    "dijit/form/Button"], 
    function(
        declare, 
        Dialog, 
        _Mixin,
        _template){
    return declare('TemplatedDialog', [Dialog, _Mixin /*careful, widgetsintemplate is tricky*/ ], {    
        templateString : _template
    })
})

You can fiddle here

EDIT:

As there is troubles with dialogs containing borderlayouts (its not unheard of anyways) here's a workaround:

    _checkIfSingleChild: function() {
        delete this._singleChild;
       domClass.toggle(this.containerNode, this.baseClass + "SingleChild", !!this._singleChild);

    },
    templateString: '....'

Im not certain of the consequences, im thinking the borderlayout of yours might start to misbehave if you try to programmatically change its contents and dimensions.. But it will render - at least it does here: updated fiddle

Upvotes: 4

Related Questions