Reputation: 3555
I have the following widget HTML.
<div class="expandableSearch">
<div data-dojo-type="dijit/TitlePane" data-dojo-props="title:'${prefixTitle}', open:false" id="${containedWidgetId}titleNodePane">
<div id="container"
class="${baseClass}Container"
data-dojo-attach-point="containerNode"></div>
</div>
</div>
with the following Javascript behind it:
/**
* Javascript for ExpandableSearchComponent
*/
define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
"dojo/text!./templates/ExpandableSearchComponent.html",
"dijit/TitlePane", "dijit/_WidgetsInTemplateMixin", "dijit/registry",
"dojo/on", "dojo/aspect", "dojo/_base/lang", "dojo/dom",
"dojo/dom-attr", "js/utils/CommonUtils", "dijit/focus" ], function(declare,
_WidgetBase, _TemplatedMixin, template, TitlePane,
_WidgetsInTemplateMixin, registry, on, aspect, lang, dom, domAttr,
CommonUtils, focusUtil) {
return declare([ _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], {
templateString : template,
prefixTitle : "",
containedWidgetId : "",
defaultValue : "",
startup : function() {
this.inherited(arguments);
var containedWidgetId = this.containedWidgetId;
var containedWidget = registry.byId(this.containedWidgetId);
if (typeof containedWidget === "undefined") {
containedWidget = dom.byId(this.containedWidgetId);
}
var titlePane = registry.byId(this.containedWidgetId
+ "titleNodePane");
this.own(on(titlePane, "Show", function() {
if (typeof containedWidget.loadAndOpenDropDown === "function") {
containedWidget._aroundNode = containedWidget.focusNode;
containedWidget.loadAndOpenDropDown();
}
focusUtil.focus(dom.byId(containedWidgetId));
}));
this.own(on(titlePane, "Hide", function() {
if (typeof containedWidget.closeDropDown === "function") {
containedWidget.closeDropDown();
}
}));
this.own(on(containedWidget, "change", function(event) {
var newVal = "";
if (typeof containedWidget.attr == "function"
&& containedWidget.attr("displayedValue") !== null) {
newVal = containedWidget.attr("displayedValue");
}
if (typeof event === "object") {
newVal = containedWidget.value;
}
var newTitle = this.prefixTitle + newVal;
if (newTitle.length > 35) {
newTitle = newTitle.substring(0, 32) + "...";
}
titlePane.set("title", newTitle);
if (titlePane.open) {
titlePane.toggle();
}
}.bind(this)));
},
reset : function() {
var containedWidget = registry.byId(this.containedWidgetId);
if (typeof containedWidget === "undefined") {
containedWidget = dom.byId(this.containedWidgetId);
}
if (typeof containedWidget.set === "function"
&& containedWidget.attr("displayedValue") !== null) {
containedWidget.set("value", this.defaultValue);
}
if (typeof containedWidget.set === "function"
&& containedWidget.attr("displayedValue") === null) {
containedWidget.set("value", this.defaultValue);
}
if (typeof containedWidget.onChange !== "function") {
domAttr.set(containedWidget, "value", this.defaultValue);
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
containedWidget.dispatchEvent(evt);
} else {
containedWidget.fireEvent("onchange");
}
}
}
});
});
Essentially, this combination of HTML and Javascript is just a dijit/TitlePane
with some extra javascript to
Used like this:
<div data-dojo-type="js/widgets/ExpandableSearchComponent" id="machineSearchView.operatingSystemExpandableSearch"
data-dojo-props="prefixTitle: '<s:property value="%{getText('label.machine.operatingSystem')}"/>: ', containedWidgetId: 'machineSearchView.operatingSystem', defaultValue: '-1'">
<div data-dojo-type="dojo/store/Memory"
data-dojo-id="operatingSystemStore"
data-dojo-props="<s:property value='%{getOperatingSystemTypeCodeJsonString()}'/>"></div>
<s:set name="operatingSystem" value="machineSearchView.operatingSystem"
scope="request"></s:set>
<div data-dojo-type="dijit/form/Select" class="readOnlySelect"
data-dojo-props="store:operatingSystemStore, labelAttr: 'label', sortByLabel: false, value:'${operatingSystem}'"
name="machineSearchView.operatingSystem" id="machineSearchView.operatingSystem"></div>
</div>
When I open it, it looks like this:
As you can see, the dijit/form/Select
opens the SelectMenu
on the TitlePane
component instead of on the Select div itself. you can JUST about see the Select peek out to the side of the SelectMenu
.
As an example of how I'd like it to look:
The containedWidget._aroundNode = containedWidget.focusNode;
was an attempt to make it work based on https://davidwalsh.name/dijit-dropdowns, but it didn't help. I'm not sure what else I can try. I've already tried to go on debugging binges deep inside the Dojo components, but to no avail?
How do I fix this?
Upvotes: 0
Views: 226
Reputation: 725
TitlePane plays an animation when it opens. Opening the select drop down on the "Show" event is too early, the TitlePane container is not ready yet. You need to wait for the animation to finish. The internal opening animation object in TitlePane is _wipeIn and you can add an aspect after its onEnd() function.
require([
"dijit/TitlePane",
"dijit/form/Select",
"dojo/data/ObjectStore",
"dojo/store/Memory",
"dojo/on",
"dojo/aspect",
"dojo/domReady!"
], function(TitlePane, Select, ObjectStore, Memory, on, aspect) {
var store = new Memory({
data: [
{ id: "foo", label: "Foo" },
{ id: "bar", label: "Bar" }
]
});
var os = new ObjectStore({ objectStore: store });
var s = new Select({store: os});
s.startup();
var tp = new TitlePane({title:"I'm a TitlePane", content: s, open: false});
tp.placeAt("content");
tp.startup();
/*
// This does not work:
on(tp, "Show", function() {
s.loadAndOpenDropDown();
});
*/
// This works:
aspect.after(tp._wipeIn, "onEnd", function() {
s.loadAndOpenDropDown();
});
on(tp, "Hide", function() {
s.closeDropDown();
});
});
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css">
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css">
<div class="claro">
<div id="content"></div>
</div>
Upvotes: 1