sample skeleton application with dojo toolkit & arcgis js api v 4.30
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

617 lines
22 KiB

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title>WidgetsInTemplateMixin.js</title>
<style type="text/css">
/* Make our tests stand out as easily identifiable content */
.testcontainer {
border: 10px yellow;
border-style: dashed;
padding: 1em;
margin: 1em;
}
.testcontainer > p {
padding: 0 1em;
font-weight: bold;
}
</style>
<script type="text/javascript" src="boilerplate.js"></script>
<script type="text/javascript">
require([
"doh", "dojo/_base/array", "dojo/_base/declare", "dojo/_base/window", "dojo/dom", "dojo/dom-geometry",
"dojo/html", "dojo/on", "dojo/query", "dojo/parser",
"dijit/registry", "dijit/_WidgetBase", "dijit/_Widget",
"dijit/_AttachMixin", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin",
"dijit/form/Button", "dijit/form/CheckBox", "dijit/form/TextBox",
"dijit/ProgressBar", "dijit/_Container", "dijit/_Contained",
"dijit/layout/ContentPane", "dijit/layout/_LayoutWidget", "dijit/layout/LayoutContainer",
"dijit/tests/resources/TestContextRequireWidget",
"dojo/domReady!"
], function(doh, array, declare, win, dom, domGeom, html, on, query, parser,
registry, _WidgetBase, _Widget, _AttachMixin, _TemplatedMixin, _WidgetsInTemplateMixin,
Button, CheckBox, TextBox, ProgressBar, _Container, _Contained, _LayoutWidget, LayoutContainer){
declare('Test1Widget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: dom.byId('Test1Template').value,
onClick: function(e){
if(e.target){
alert('onClick widgetId='+e.target.id);
}else{
if(e._counter == undefined){
e._counter = 1;
}else{
e._counter++;
}
}
}
});
declare('Test3Widget', [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: dom.byId('Test3Template').value
});
declare('TestLayoutWidget', _LayoutWidget, {
startup: function(){
if(this._started){
this._doubleStarted = true;
}
this.inherited(arguments);
},
destroy: function(){
if(this._destroyed){
this._doubleDestroyed = true;
}
this.inherited(arguments);
this._destroyed = true;
}
});
declare('TestCtnrWidget', [_WidgetBase, _Container], {
startup: function(){
if(this._started){
this._doubleStarted = true;
}
this.inherited(arguments);
},
destroy: function(){
if(this._destroyed){
this._doubleDestroyed = true;
}
this.inherited(arguments);
this._destroyed = true;
}
});
declare('TestCtndWidget', [_WidgetBase, _Contained], {
startup: function(){
if(this._started){
this._doubleStarted = true;
}
this.inherited(arguments);
},
destroy: function(){
if(this._destroyed){
this._doubleDestroyed = true;
}
this.inherited(arguments);
this._destroyed = true;
}
});
declare('TestNonCtnrWidget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: "<div data-dojo-attach-point=containerNode></div>",
startup: function(){
if(this._started){
this._doubleStarted = true;
}
this.inherited(arguments);
},
destroy: function(){
if(this._destroyed){
this._doubleDestroyed = true;
}
this.inherited(arguments);
this._destroyed = true;
}
});
declare('TestStubWidget', _WidgetBase, {
startup: function(){
if(this._started){
this._doubleStarted = true;
}
this.inherited(arguments);
},
destroy: function(){
if(this._destroyed){
this._doubleDestroyed = true;
}
this.inherited(arguments);
this._destroyed = true;
}
});
declare('Test5Widget',
[_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin],
{
templateString: dom.byId('Test5Template').value,
startup: function(){
if(this._started){
this._doubleStarted = true;
}
this.inherited(arguments);
},
destroy: function(){
if(this._destroyed){
this._doubleDestroyed = true;
}
this.inherited(arguments);
this._destroyed = true;
}
});
declare('Test6Widget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: dom.byId('Test6Template').value,
clickCount: 0,
handleClick: function(){
this.clickCount++;
}
});
declare("Missing", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: '<div>' +
'<div data-dojo-type="dijit/layout/ContentPane">' +
'<div data-dojo-type="dijit/form/Button" data-dojo-props="id: \'missingButtonId\'" ' +
'data-dojo-attach-point="missingButton">Missing...</div>' +
'</div>' +
'</div>'
});
function getTest5WidgetsInTemplate(testW){
// summary:
// Returns all the widgets in the template for a Test5Widget
return [
testW,
testW.layout,
testW.layChild1,
testW.layChild2,
testW.container,
testW.contained1,
testW.contained2,
testW.nonContainer,
testW.nonContained1,
testW.nonContained2,
testW.threeLevel,
testW.secondLevel,
testW.bottomLevel,
testW.anotherThree,
testW.anotherSecond,
testW.anotherBottom,
testW.stub1
];
}
function validateTest5Widget(/*Test5Widget*/ testW, /*Boolean*/ started){
// Check that testW widget, and all the widgets in it's template, got started, but not double-started
array.forEach(getTest5WidgetsInTemplate(testW), function(w){
if(started){
doh.t(w._started, w + " should be started");
}else{
doh.f(w._started, w + " should not be started");
}
doh.is(undefined, w._doubleStarted, "w._doubleStarted: " + w);
});
}
function validateTest5WidgetDestroy(t, testW){
var savedWidgets = getTest5WidgetsInTemplate(testW);
testW.destroy();
array.forEach(savedWidgets, function(w, idx){
doh.t(w._destroyed, "w._destroyed: " + w);
doh.is(undefined, w._doubleDestroyed, "w._doubleDestroyed: " + w);
});
}
doh.register("_AttachMixin-widgetInTemplate", [
function createAttachWidgetsCombo() {
/*** TEST _AttachMixin combined with _WidgetsInTemplateMixin ***/
var AttachWidgetsCombo = declare([ _WidgetBase, _AttachMixin, _WidgetsInTemplateMixin ], {
postCreate: function() {
html.set(this.heading, "Amazing things will happen if you click this button!!!");
},
_buttonClicked: function(e) {
html.set(this.heading, "Well that was boring. " +
"My attach point button thinks it is a " + (this.mybutton.isInstanceOf(Button) ? 'dijit/form/Button':'Gruffalo'));
}
});
var myawc = new AttachWidgetsCombo({}, dom.byId('attachMeThree'));
doh.t(myawc.heading, "heading");
doh.t(myawc.mybutton, "mybutton");
doh.is("Amazing things will happen if you click this button!!!", myawc.heading.innerHTML, "Initial value");
// Simulate clicking the button. Don't use click() because it's not supported on a <span>
// in Android < 4.4.
on.emit(myawc.mybutton.focusNode, "click", {
bubbles: true,
cancelable: true
});
doh.is("Well that was boring. My attach point button thinks it is a dijit/form/Button", myawc.heading.innerHTML, "Post-op value");
},
function containerNode(){
// Test that widgets inside of containerNode aren't parsed by _WidgetsInTemplateMixin
declare("OuterWidget", [ _WidgetBase, _AttachMixin, _WidgetsInTemplateMixin ], {
// Prevent the main parser call from hitting my supporting widgets.
// But this also stops the parser from hitting anything inside my containerNode, so I need
// to do a recursive parse() like ContentPane does (or just extend ContentPane)
stopParser: true,
postCreate: function(){
doh.is(0, this.getChildren().length, "contained widget not created yet");
parser.parse(this.containerNode);
}
});
declare("SupportingWidget", _WidgetBase);
declare("ContainedWidget", _WidgetBase);
parser.parse(dom.byId("containerNode"));
doh.t("outerWidget" in window, "outer widget created");
doh.t(outerWidget.supportingWidget, "supporting widget instantiated");
doh.f(outerWidget.containedWidget, "contained widget not instantiated by _WidgetsInTemplateMixin parse call");
doh.is(1, outerWidget.getChildren().length, "contained widget created too");
}
]);
doh.register("_Templated-widgetsInTemplate", [
function parse(){
parser.parse("templateTests");
},
{
name: "data-dojo-attach-point",
runTest: function(t){
var testW = registry.byId("test1Widget");
doh.t(testW, "test1Widget was instantiated");
doh.t(testW.normalNode, "normalNode");
doh.f(isNaN(testW.normalNode.nodeType), "normalNode.nodeType");
doh.t(testW.buttonWidget instanceof Button, "buttonWidget is Button");
doh.t(testW.checkboxWidget instanceof CheckBox, "checkboxWidget is CheckBox");
doh.t(testW.progressBarWidget instanceof ProgressBar, "progressBarWidget is ProgressBar");
}
},
{
name: "data-dojo-attach-event",
runTest: function(t){
var testW = registry.byId("test1Widget");
testW.buttonWidget._counter=0;
testW.buttonWidget.onClick(testW.buttonWidget);
testW.checkboxWidget._counter=0;
testW.checkboxWidget.onClick(testW.checkboxWidget);
testW.progressBarWidget._counter=0;
testW.progressBarWidget.onChange(testW.progressBarWidget);
doh.is(1,testW.buttonWidget._counter, "buttonWidget._counter");
doh.is(1,testW.checkboxWidget._counter, "checkboxWidget._counter");
doh.is(1,testW.progressBarWidget._counter, "progressBarWidget._counter");
}
},
{
name: "data-dojo-attach-event strange name",
runTest: function(t){
// This is for testing data-dojo-attach-event to attach to a method in the widget,
// rather than using _WidgetBase.on(...). Remove for 2.0.
var SubWidget = declare("SubWidget", _WidgetBase, {
f: function(){
// just for attaching to
}
});
var MainWidget = declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString:
'<div>' +
'<div data-dojo-type="SubWidget" data-dojo-attach-point="sw" ' +
' data-dojo-attach-event="f: g">' +
'</div>',
g: function(){
this.gWasCalled = true;
}
});
var mw = new MainWidget();
doh.t(mw.sw, "attach-point exists");
mw.sw.f();
doh.t(mw.gWasCalled, "attach-event worked");
}
},
{
// Test that getDescendants ()
// finds direct descendants but skips widgetsInTemplates
// and also nested widgets (if direct==true)
name: "getChildren",
runTest: function(t){
var testW = registry.byId("test3Widget");
/*** performance tests
var start = new Date();
for(var i=0; i<1000; i++)
testW.getChildren();
console.log("*** time for getChildren(): " + (new Date()-start));
var start = new Date();
for(var i=0; i<1000; i++)
testW.getDescendants();
console.log("*** time for getDescendants(false): " + (new Date()-start));
***/
var chil = testW.getChildren();
doh.is(5, chil.length, "number of direct descendants");
doh.is(chil[0].id, "3.1");
doh.is(chil[1].id, "3.2");
doh.is(chil[2].id, "3.3");
doh.is(chil[3].id, "3.4");
doh.is(chil[4].id, "3.5");
// remove this test for 2.0
var desc = testW.getDescendants();
doh.is(7, desc.length, "number of descendants (including nested ones)");
doh.is(desc[0].id, "3.1");
doh.is(desc[1].id, "3.2");
doh.is(desc[2].id, "3.3");
doh.is(desc[3].id, "3.nested");
doh.is(desc[4].id, "3.nested2");
doh.is(desc[5].id, "3.4");
doh.is(desc[6].id, "3.5");
}
},
{
// Check that declarative widget with other widgets in template is correctly started
name: "declarative widget with many child widgets",
runTest: function(t){
validateTest5Widget(registry.byId("test5Widget"), true);
}
},
{
// Check that programmatic widget with other widgets in template is correctly started
name: "programmatic widget with many child widgets",
runTest: function(t){
// Create widget. Widgets in template should not be started yet.
test5WidgetProgrammatic = new Test5Widget();
validateTest5Widget(test5WidgetProgrammatic, false);
// Place widget in DOM and startup. Widgets in template should now be started.
test5WidgetProgrammatic.placeAt("test5Widget", "after");
test5WidgetProgrammatic.startup();
validateTest5Widget(test5WidgetProgrammatic, true);
}
},
{
// Check that destroying our declarative widget works correctly
name: "declarative widget destruction",
runTest: function(t){
validateTest5WidgetDestroy(t, registry.byId("test5Widget"));
}
},
{
// Check that destroying our programmatic widget works correctly
name: "programmatic widget destruction",
runTest: function(t){
validateTest5WidgetDestroy(t, test5WidgetProgrammatic);
}
},
{
// Test that data-dojo-attach-point inside of a ContentPane (inside of a template) works
name: "ContentPane",
runTest: function(){
var testW = registry.byId("missing");
doh.t(testW, "widget was created");
doh.t(testW.missingButton, "data-dojo-attach-point created");
doh.is("dijit.form.Button", testW.missingButton.declaredClass, "and it's to a widget");
doh.t(registry.byId("missingButtonId"), "nested widget also registered by id");
}
},
{
// Test that data-dojo-attach-event bindings work with widgets in template, when
// binding to dijit/_Widget methods
name: "_Widget Deferred Connect methods",
runTest: function(){
var test6Widget = registry.byId("test6Widget");
doh.t(test6Widget.clickCount === 0, "click count was initially zero");
// Issue a 'click' event directly on the interior input of the TextBox
test6Widget.textbox.textbox.click();
doh.t(test6Widget.clickCount === 1, "click count incremented properly");
}
},
function widgetsInTemplateLifecycle(t){
var result = [], expected = [1, 1, 0, 2, 2, 3];
// widgetsInTemplateLifecycle
declare("SubThing", _WidgetBase, {
postCreate: function(){
this.inherited(arguments);
result.push(1);
},
startup: function(){
this.inherited(arguments);
result.push(2);
}
});
declare("ParentThing", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: "<div>" +
"<span data-dojo-type='SubThing'>a</span>" +
"<div data-dojo-type='dijit/layout/LayoutContainer'>" +
"<span data-dojo-type='SubThing' data-dojo-props='region: \"center\"'>b</span>" +
"</div>" +
"</div>",
postCreate: function(){
// children postcreate (x2) called before this postCreate
this.inherited(arguments);
result.push(0);
},
startup: function(){
// then children startup (x2) then our startup
// (we can call inherited after push(), and change the order)
this.inherited(arguments);
result.push(3);
}
});
new ParentThing().startup();
t.is(expected.length, result.length);
array.forEach(expected, function(r){
t.is(r, result.shift());
});
}
]);
// Test that "this" referenced from data-dojo-props can refer to the hosting widget
doh.register("data-dojo-props this", function(){
var host = declare([dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
obj: {hello: "world"},
templateString:
"<div>" +
"<div data-dojo-type='dijit/_WidgetBase' data-dojo-props='hostObj: this.obj'" +
" data-dojo-attach-point='subWidget'></div>" +
"</div>"
});
var hostWidget = new host(),
subWidget = hostWidget && hostWidget.subWidget;
doh.isNot(undefined, hostWidget, "created host widget");
doh.isNot(undefined, subWidget, "created sub widget");
doh.isNot(undefined, subWidget.hostObj, "sub widget got hostObj defined");
doh.is("world", subWidget.hostObj.hello, "object is correct")
});
// Test that a context require can be passed to the parser
doh.register("context require", function(){
var cw = registry.byId("testContextWidget");
doh.is(typeof cw.fooNode, "object", "button created");
doh.is(cw.fooNode.fooNode.innerHTML, "TestWidget", "sub widget contains right properties");
});
doh.run();
});
</script>
</head>
<body>
<h1>WidgetsInTemplateMixin</h1>
<!-- Tests for _WidgetsInTemplateMixin combined with _AttachMixin -->
<div class="testcontainer">
<p>This test shows that a _AttachMixin dijit with _WidgetsInTemplate properly attaches widgets from the template.<br>
<div id="attachMeThree">
<h2 data-dojo-attach-point='heading'></h2>
<button data-dojo-type='dijit/form/Button'
data-dojo-attach-point='mybutton'
data-dojo-attach-event='click: _buttonClicked'>A button</button>
</div>
</div>
<!-- Test that widgets inside containerNode aren't parsed by _WidgetsInTemplateMixin-->
<div id="containerNode" class="testcontainer">
<p>This tests that nodes inside of data-dojo-attach-point="containerNode" are ignored<br>
<div data-dojo-id="outerWidget" data-dojo-type="OuterWidget">
<h2 data-dojo-attach-point="heading">heading</h2>
<div data-dojo-type="SupportingWidget" data-dojo-attach-point="supportingWidget">supporting widget</div>
<div data-dojo-attach-point="containerNode">
<span data-dojo-type="ContainedWidget" data-dojo-attach-point="containedWidget">contained widget</span>
</div>
</div>
</div>
<!-- Tests for _WidgetsInTemplateMixin combined with _TemplatedMixin -->
<div id="templateTests">
<textarea id="Test1Template" style="display:none;">
<div>
<div data-dojo-attach-point="normalNode">normal node</div>
<button data-dojo-attach-point="buttonWidget" data-dojo-attach-event="click:onClick" data-dojo-type="dijit/form/Button">button #1</button>
<div data-dojo-attach-point="checkboxWidget" data-dojo-attach-event="click:onClick" data-dojo-type="dijit/form/CheckBox"></div> checkbox #1
<div data-dojo-attach-point="progressBarWidget" data-dojo-attach-event="change:onClick"
data-dojo-type="dijit/ProgressBar" data-dojo-props='value: 20, maximum: 200, style: "width:400px;"'></div>
</div>
</textarea>
<div data-dojo-type="Test1Widget" data-dojo-props="id: 'test1Widget'"></div>
<textarea id="Test3Template" style="display:none;">
<div>
<div data-dojo-attach-point="checkboxWidget" data-dojo-type="dijit/form/CheckBox"></div> checkbox #3
<div data-dojo-attach-point="containerNode"></div>
</div>
</textarea>
<div data-dojo-type="Test3Widget" data-dojo-props="id: 'test3Widget'">
<span>hello world</span>
<b style="border: 1px solid blue;">this is my
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.1'">first button</button>
</b>
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.2'">another button</button>
<i>and some more</i>
<div style="border: 1px solid red;">
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="style: {border: '1px solid gray'}, id: '3.3'">
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.nested'">a nested button</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.nested2'">another nested button</button>
</div>
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.4'">yet another button</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.5'">yet yet another button</button>
</div>
</div>
<!-- Test templated widget containing container and nested widgets in template -->
<textarea id="Test5Template" style="display:none;">
<div>
<div data-dojo-type="TestLayoutWidget" data-dojo-attach-point="layout">
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild1"></div>
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild2"></div>
</div>
<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="container">
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained1"></div>
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained2"></div>
</div>
<div data-dojo-type="TestStubWidget" data-dojo-attach-point="stub1"></div>
<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="nonContainer">
<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained1"></div>
<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained2"></div>
</div>
<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="threeLevel">
<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="secondLevel">
<div data-dojo-type="TestStubWidget" data-dojo-attach-point="bottomLevel"></div>
</div>
</div>
<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="anotherThree">
<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="anotherSecond">
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="anotherBottom"></div>
</div>
</div>
</div>
</textarea>
<div data-dojo-type="Test5Widget" data-dojo-props="id: 'test5Widget'"></div>
<div data-dojo-type="Missing" data-dojo-props="id: 'missing'"></div>
<!-- Test templated widget containing relative MIDs for data-dojo-type -->
<div data-dojo-type="dijit/tests/resources/TestContextRequireWidget" data-dojo-props="id: 'testContextWidget'"></div>
<!-- Test templated widget for back-compat with inherited onClick etc events when using widgets in template -->
<textarea id="Test6Template" style="display:none;">
<div>
<div data-dojo-type="dijit/form/TextBox" data-dojo-attach-point="textbox" data-dojo-attach-event="onClick: handleClick"></div>
</div>
</textarea>
<div data-dojo-type="Test6Widget" data-dojo-props="id: 'test6Widget'"></div>
</div>
</body>
</html>