This is similar to a question already on here but I'm using Dojo 1.7. So, I can't get BorderContainer and ContentPanes working inside of a custom widget template. It's driving me mad. I tried adding the mixins suggested in the other post and it didn't work.
So I have two examples. The first is a single page using dojo declaratively and it works fine. The second example is exactly the same page but I use a widget to embed the template. It renders the widgets but they are all stuck together in the top right corner. Same page, same styles. BUT, when i resize the browser window the page takes shape. There are still bits missing but it's better
screenshot here for first example using dojo declaratively
screenshot here for second example using a widget
screenshot here for second example after resizing the browser window. Still not the same as the first example but better.
Many thanks
This is the first example, which works
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Application Controller</title>
<link rel="stylesheet" href="/js/tag/widgets/BorderWidget/css/demo.css" media="screen">
<link rel="stylesheet" href="/js/tag/widgets/BorderWidget/css/style.css" media="screen">
<link rel="stylesheet" href="/js/dijit/themes/claro/claro.css" media="screen">
<!-- Configure Dojo -->
<script type="text/javascript">
var djConfig = {
isDebug : true,
parseOnLoad : true
};
</script>
<script type="text/javascript" src="/js/dojo/dojo.js"></script>
<script>
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.layout.ContentPane");
</script>
</head>
<body class="claro">
<div style="height:100%">
<div id="appLayout" class="demoLayout" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design: 'headline'">
<div class="centerPanel" id="tabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props="region: 'center', tabPosition: 'bottom'">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title: 'About'">
<h2>Flickr keyword photo search</h2>
<p>
Each search creates a new tab with the results as thumbnails
</p>
<p>
Click on any thumbnail to view the larger image
</p>
</div>
</div>
<div class="edgePanel" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
<div class="searchInputColumn">
<div class="searchInputColumnInner">
<input id="searchTerms" placeholder="search terms">
</div>
</div>
<div class="searchButtonColumn">
<button id="searchBtn">
Search
</button>
</div>
</div>
</div>
</div>
</body>
</html>
And this is second example using a widget
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Application Controller</title>
<link rel="stylesheet" href="/js/tag/widgets/BorderWidget/css/demo.css" media="screen">
<link rel="stylesheet" href="/js/tag/widgets/BorderWidget/css/style.css" media="screen">
<link rel="stylesheet" href="/js/dijit/themes/claro/claro.css" media="screen">
<!-- Configure Dojo -->
<script type="text/javascript">
var djConfig = {
isDebug : true,
parseOnLoad : true,
paths : {
'tag' : '../tag/widgets/BorderWidget'
}
};
</script>
<script type="text/javascript" src="/js/dojo/dojo.js"></script>
<script>
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require('tag.Widget');
dojo.ready(function() {
new tag.Widget().startup();
});
</script>
</head>
<body class="claro">
</body>
</html>
This is the widget code
define('tag/Widget',
[
'dojo',
'dijit/_Widget',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
'dijit/layout/BorderContainer',
'dijit/layout/TabContainer',
'dijit/layout/ContentPane'
],
function(d) {
//The widget contructor will be returned
return d.declare('tag.Widget',
[
dijit._Widget,
dijit._TemplatedMixin,
dijit._WidgetsInTemplateMixin
],
{
templateString : d.cache("tag", "templates/template.html"),
postCreate : function() {
this.inherited(arguments);
var domNode = this.domNode;
},
startup : function(args) {
this.inherited(arguments);
this.placeAt(dojo.doc.body);
}
});
});
This is the template for the widget
<div style="height:100%">
<div id="appLayout" class="demoLayout" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design: 'headline'">
<div class="centerPanel" id="tabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props="region: 'center', tabPosition: 'bottom'">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title: 'About'">
<h2>Flickr keyword photo search</h2>
<p>
Each search creates a new tab with the results as thumbnails
</p>
<p>
Click on any thumbnail to view the larger image
</p>
</div>
</div>
<div class="edgePanel" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
<div class="searchInputColumn">
<div class="searchInputColumnInner">
<input id="searchTerms" placeholder="search terms">
</div>
</div>
<div class="searchButtonColumn">
<button id="searchBtn">
Search
</button>
</div>
</div>
</div>
</div>
You might need to explicitly call startup on the BorderContainer and ContentPane layout widgets in your own startup()
method. Also you probably want to always have this.inherited(arguments)
in any of the widget lifecycle methods if you are overriding and inheriting method.
startup : function(args) {
this.inherited(arguments);
//console.log('asdasd')
dojo.empty("body");
this.placeAt('body');
this.subContainerWidget.startup();
//I think the border container will automatically call startup on its children
//(the content panes), but you may also need to call startup on them.
}
Also, as @missingno mentioned, you probably don't want to be emptying the <body>
and replacing it during widget startup, as a general reusability thing.
I had a very similar problem with a custom Widget and BorderContainers within and it finally worked after I inherited BorderContainer instead BaseWidget or _Widget. Hope that also helps in your case!
I'm creating my templated custom widgets which contain BorderContainers with a surrounding div
(because I couldn't get a top-level BorderContainer to work), like so:
<div style="height: 100%;">
<div style="height: 100%;" data-dojo-type="dijit/layout/BorderContainer"
data-dojo-attach-point="bc"
data-dojo-props="design: 'headline', gutters: false">
<div data-dojo-type="dijit/layout/ContentPane"
data-dojo-props="region: 'top'">
</div>
<div data-dojo-type="dijit/layout/ContentPane"
data-dojo-props="region: 'center'">
</div>
</div>
I had the exact same layout problems (BorderContainer would only layout correctly after page resize), until I realized (thanks to the answer by John Brinnand above) that I need to forward any resize
calls from dijit to the "inner" BorderContainer. So what I did was to implement a resize
method in my widget ("bc"
is the BorderContainer widget, brought in via data-dojo-attach-point
as seen in the above code):
resize: function () {
this.bc.resize(arguments);
this.inherited(arguments);
}
and lo and behold: everything works fine.
(I'm using dojo 1.9, but this should work for dojo >= 1.7)
BorderContainer is a layout widget that needs to be dinamically sized. You have overwritten the startup method and I'd bet this is at least one of the problems.
Since your startup method contents aren't really startupy, I'd suggest you just try removing or renaming it (to expose the original startup).
d.declare(...)|{
...
toFullScreen: function(){
dojo.empty("body");
this.placeAt('body');
}
}
var w = new FlickApiView({...});
w.toFullScreen();
w.startup();
Edit (for the new problem):
I find
startup : function(args) {
this.inherited(arguments);
this.placeAt(dojo.doc.body);
}
to be suspicious, since all the resizing is done in the this.inherited part before the widget is actually placed (so the resizing doesn't work initially)
You could try switching the order here but I think it is better to just remove the startup method entirely and change the main to
var w = new tags.Widget();
w.placeAt(dojo.body());
s.startup();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With