dojo.dialog.change size after content has been set - dojo

require(["dojo","dojo/dom-attr"], function(dojo, domAttr){
var dlg =dijit.byId("my_dialog");
domAttr.set(dlg, "content", "this is a text");
//dlg.set("dimensions", [400, 200]);
//dojo.style("my_dialog", "width", "300px");
//dlg.resize({h: 500, w: 500});
});
I have a dijit.dialog. I set its text dynamically but the dialog's size is way too big. i've tried the three things commented above to no avail.

Just set property style with the right dimension for your dijit/dialog.
In the following example we set dimension width to 500px setting inline CSS for dialog dom element.
Live example:
https://jsfiddle.net/358rjoch/
require(["dijit/Dialog", "dojo/domReady!"], function(Dialog){
myDialog = new Dialog({
title: "My Dialog",
content: "Test content.",
style: "width: 500px"
});
});
<button onclick="myDialog.show();">show</button>
Alternatively you can use only CSS (no inline), for example you can give an ID to your dialog widget and use a CSS selector for its style.
Live example:
https://jsfiddle.net/o15mbodm/
require(["dijit/Dialog", "dojo/domReady!"], function(Dialog){
myDialog = new Dialog({
id:"myDialog", // your id here
title: "My Dialog",
content: "Test content."
});
});
#myDialog{
width: 500px;
height:400px;
}
You can find a detailed list of methods and properties for dijit/dialog widgets at the following link:
http://dojotoolkit.org/api/?qs=1.10/dijit/Dialog

Related

Custom attribute not working on dynamic content

I'm using w2ui grid, and the template column generated like so:
{ field: 'TableCards', caption: 'Table cards', size: '10%', sortable: true ,
render:function(record, index, column_index) {
let html = '';
if (record.TableCards) {
record.TableCards.forEach(function(card) {
html += `<div class="card-holder" style="width: 12%; display: inline-block; padding: 0.5%;">
<div class="poker-card blah" poker-card data-value="${card.value}"
data-color="${card.color}"
data-suit="&${card.suit};"
style="width: 30px;height: 30px">
</div>
</div>`;
});
}
return html;
}
},
poker-card as u can see is a custom attribute. and it's not get rendered in the grid.
any other way?
You can use the TemplatingEngine.enhance() on your dynamic HTML.
See this article for a complete example: http://ilikekillnerds.com/2016/01/enhancing-at-will-using-aurelias-templating-engine-enhance-api/
Important note: based on how your custom attribute is implemented, you may need to call the View's lifecycle hooks such as .attached()
This happened to me, when using library aurelia-material, with their attribute mdl.
See this source where the MDLCustomAttribute is implemented, and now see the following snippet, which shows what I needed to do in order for the mdl attribute to work properly with dynamic HTML:
private _enhanceElements = (elems) => {
for (let elem of elems) {
let elemView = this._templEngine.enhance({ element: elem, bindingContext: this});
//we will now call the View's lifecycle hooks to ensure proper behaviors...
elemView.bind(this);
elemView.attached();
//if we wouldn't do this, for example MDL attribute wouldn't work, because it listens to .attached()
//see https://github.com/redpelicans/aurelia-material/blob/5d3129344e50c0fb6c71ea671973dcceea14c685/src/mdl.js#L107
}
}

canvasOverlay show in jqplot

How do I trigger on the overlays in jqplot only after I click a checkbox (not when the html loads). When I first set overlay option show to false the overlays are not displayed on plot at 1st and when I used my trigger function the overlays do not appear.
Here is the code I use for the plot :
<div id="fastest" style="margin-top:20px; margin-left:20px; margin-right:200px; width:800px; height:400px;">
<script class="code" type="text/javascript">
$(document).ready(function(){
var dataset="too long to be displayed here"
plot1 = $.jqplot('fastest', dataset, {
title: 'Test_figs',
legend: {show:false},
series: [{
showMarker: false,
color: '#ED0E0E',
label: 'R spectrum',
neighborThreshold: -1
}],
axes:{
xaxis:{
label:'Restframe Wavelength'
},
yaxis:{
label:'Flux',
tickOptions:{formatString:'%.3e'}
}
},
cursor:{
show:true,
zoom:true,
tooltipLocation:'sw'
},
Canvasoverlay: {
show: false,
objects: [
{verticalLine: {
name: 'Na-ID',
x: 5893.000000,
lineWidth: 2,
color: '#F0630C',
lineCap:'butt',
yOffset:0,
shadow: true
}}
]
}
});
});
function NaID_trigger() {
var co = plot1.plugins.canvasOverlay;
var line = co.get('Na-ID');
if (line.options.show==false) line.options.show = true;
else line.options.show = false;
co.draw(plot1);
}
</script>
I then use :
<button onclick="NaID_trigger()">Na-ID</button>
to trigger the overlay on or off for instance.
PS: I tried replacing draw by replot as advised didn't work when show=false in overlays options.
I finally found the solution myself :
to not display the overlays when the jqplot loads I set the overall overlays "show" option to true.
Then within each object I set show to false.
Instead of the external to the plot function I used before I switched to an even handler of the form:
$("input[type=checkbox][name=Na-ID]").change(function(){
plot1.plugins.canvasOverlay.get('Na-ID').options.show = this.checked;
plot1.replot();
});
Now the plot display the selected overlay when checkbox is ticked and not at the beginning.
Hope this will help someone who has the same issues.

How to edit style (font color) of dojo.TitlePane programatically

I have a TitlePane which I want to change the font color. I just cant. I need to do this programatically.
So far I have something like this:
var newPane = new TitlePane({title: paneName});
I have tried this as well:
var newPane = new TitlePane({title: paneName, id: paneName, style:{color:'red'}});
This sets the content of the pane red and no id is added anywhere :(
As per this API info I can only set three properties (title, content and open). How could I add an id and style(color) to the TitlePane! pls
Style it via Cascading Style Sheets. See how it works at jsFiddle: http://jsfiddle.net/phusick/63dHY/
To change the color of TitlePane title text by id
var titlePane1 = new TitlePane({
id: "titlePane1",
title: "some red title",
content: "Collapse me!"
}, "titlePane1");
use the following style:
#titlePane1 .dijitTitlePaneTextNode {
color: red;
}
Or by class
var titlePane2 = new TitlePane({
title: "some blue title",
content: "Collapse me!"
}, "titlePane2");
domClass.add(titlePane2.domNode, "blue"); // as of 'dojo/dom-class' module
use the following style:
.blue .dijitTitlePaneTextNode {
color: blue !important;
}
​
or change it directly via JavaScript (which I do not recommend):
titlePane2.titleNode.style.color = "green";
newPane.style({color: "red"});
OR
query(newPane).style({color: "red"});
OR
newPane.style.color = "red";

Dojo/Dijit TitlePane

How do you make a titlePane's height dynamic so that if content is added to the pane after the page has loaded the TitlePane will expand?
It looks like the rich content editor being an iframe that is loaded asynchronously confuses the initial layout.
As #missingno mentioned, the resize function is what you want to look at.
If you execute the following function on your page, you can see that it does correctly resize everything:
//iterate through all widgets
dijit.registry.forEach(function(widget){
//if widget has a resize function, call it
if(widget.resize){
widget.resize()
}
});
The above function iterates through all widgets and resizes all of them. This is probably unneccessary. I think you would only need to call it on each of your layout-related widgets, after the dijit.Editor is initialized.
The easiest way to do this on the actual page would probably to add it to your addOnLoad function. For exampe:
dojo.addOnLoad(function() {
dijit.byId("ContentLetterTemplate").set("href","index2.html");
//perform resize on widgets after they are created and parsed.
dijit.registry.forEach(function(widget){
//if widget has a resize function, call it
if(widget.resize){
widget.resize()
}
});
});
EDIT: Another possible fix to the problem is setting the doLayout property on your Content Panes to false. By default all ContentPane's (including subclasses such as TitlePane and dojox.layout.ContentPane) have this property set to true. This means that the size of the ContentPane is predetermined and static. By setting the doLayout property to false, the size of the ContentPanes will grow organically as the content becomes larger or smaller.
Layout widgets have a .resize() method that you can call to trigger a recalculation. Most of the time you don't need to call it yourself (as shown in the examples in the comments) but in some situations you have no choice.
I've made an example how to load data after the pane is open and build content of pane.
What bothers me is after creating grid, I have to first put it into DOM, and after that into title pane, otherwise title pane won't get proper height. There should be cleaner way to do this.
Check it out: http://jsfiddle.net/keemor/T46tt/2/
dojo.require("dijit.TitlePane");
dojo.require("dojo.store.Memory");
dojo.require("dojo.data.ObjectStore");
dojo.require("dojox.grid.DataGrid");
dojo.ready(function() {
var pane = new dijit.TitlePane({
title: 'Dynamic title pane',
open: false,
toggle: function() {
var self = this;
self.inherited('toggle', arguments);
self._setContent(self.onDownloadStart(), true);
if (!self.open) {
return;
}
var xhr = dojo.xhrGet({
url: '/echo/json/',
load: function(r) {
var someData = [{
id: 1,
name: "One"},
{
id: 2,
name: "Two"}];
var store = dojo.data.ObjectStore({
objectStore: new dojo.store.Memory({
data: someData
})
});
var grid = new dojox.grid.DataGrid({
store: store,
structure: [{
name: "Name",
field: "name",
width: "200px"}],
autoHeight: true
});
//After inserting grid anywhere on page it gets height
//Without this line title pane doesn't resize after inserting grid
dojo.place(grid.domNode, dojo.body());
grid.startup();
self.set('content', grid.domNode);
}
});
}
});
dojo.place(pane.domNode, dojo.body());
pane.toggle();
});​
My solution is to move innerWidget.startup() into the after advice to "toggle".
titlePane.aspect = aspect.after(titlePane, 'toggle', function () {
if (titlePane.open) {
titlePane.grid.startup();
titlePane.aspect.remove();
}
});
See the dojo/aspect reference documentation for more information.

How to position a dijit.menu relative to its trigger?

I've got a couple menus like this:
// Contextual Menu
// triggers
<div id="contextMenuTrigger0">0</div>
<div id="contextMenuTrigger1">1</div>
// menu
<div dojoType="dijit.Menu"
targetNodeIds="contextMenuTrigger0, contextMenuTrigger1"
leftClicktoOpen="true" style="display:none">
<div dojoType="dijit.MenuItem" class="first">Item One</div>
<div dojoType="dijit.MenuItem">Item Two</div>
<div dojoType="dijit.MenuItem">Item Three</div>
<div dojoType="dijit.MenuItem">Item Four is really, really long item.</div>
</div>
and this:
// Tools Menu
// trigger
<div id="toolsButton">Tools</div>
// menu
<div dojoType="dijit.Menu" class="toolsMenu"
targetNodeIds="toolsButton"
leftClicktoOpen="true" style="display:none">
<div dojoType="dijit.MenuItem" class="first">Item One</div>
<div dojoType="dijit.MenuItem">Item Two</div>
<div dojoType="dijit.MenuItem">Item Three</div>
<div dojoType="dijit.MenuItem">Item Four</div>
</div>
Right now, when the menu opens, it appears under the mouse. I want it to appear in a specific position relative to the trigger*. I found the startup and onOpen events and tried writing a function that sets the style of the menu's domNode in there, but they didn't seem to take effect.
Also, I didn't see a way of finding out which node was the trigger in the context case where there are multiple ones.
I saw this & this, but wasn't able to get much further with 'em.
* FWIW, I want them positioned so that the top-left corner of the menu is aligned with the top-right corner of the context triggers, and with the bottom-left corner of the Tools menu.
I found the following css override works nicely, if you just want a relative difference in the automated positioning:
.dijitMenuPopup {
margin-left: -25px !important;
margin-top: 15px !important;
}
It turns out that dojo.popup.open (which I guess Menu inherits from) has a parameter (orient) that you can use to orient a menu relative to a node. I wound up defining a custom trigger class that knows how to take advantage of that. (I also created sub-classes for other menu-types that have different orientations, but I'll leave those out for clarity's sake.)
UPDATE: according to this page, the variable substitution method I was using in the templateString isn't recommended. Instead, you're supposed to create an attributeMap, which I've done below.
http://docs.dojocampus.org/quickstart/writingWidgets
// Define a basic MenuTrigger
dojo.declare("my.MenuTrigger", [dijit._Widget, dijit._Templated], {
// summary:
// A button that shows a popup.
// Supply label and popup as parameter when instantiating this widget.
label: null,
orient: {'BL': 'TL', 'BR': 'TR'}, // see http://api.dojotoolkit.org/jsdoc/1.3.2/dijit.popup.__OpenArgs (orient)
templateString: "<a href='#' class='button enabled' dojoAttachEvent='onclick: openPopup' onClick='return false;' ><span dojoAttachPoint='labelNode'></span></a>",
disabled: false,
attributeMap: {
label: {
node: "labelNode",
type: "innerHTML"
}
},
openPopup: function(){
if (this.disabled) return;
var self = this;
dijit.popup.open({
popup: this.popup,
parent: this,
around: this.domNode,
orient: this.orient,
onCancel: function(){
console.log(self.id + ": cancel of child");
},
onExecute: function(){
console.log(self.id + ": execute of child");
dijit.popup.close(self.popup);
self.open = false;
}
});
this.open = true;
},
closePopup: function(){
if(this.open){
console.log(this.id + ": close popup due to blur");
dijit.popup.close(this.popup);
this.open = false;
}
},
toggleDisabled: function() {
this.disabled = !this.disabled
dojo.toggleClass(this.domNode, 'buttonDisabled');
dojo.toggleClass(this.domNode, 'enabled');
dojo.attr(this.domNode, 'disabled', this.disabled);
},
_onBlur: function(){
// summary:
// This is called from focus manager and when we get the signal we
// need to close the drop down
// (note: I don't fully understand where this comes from
// I couldn't find docs. Got the code from this example:
// http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/_base/test_popup.html
this.closePopup();
}
});
// create some menus & triggers and put them on the page
dojo.addOnLoad(function(){
// MENU
cMenu = new dijit.Menu();
cMenu.addChild(new dijit.MenuItem({ label: "First Item" }));
cMenu.addChild(new dijit.MenuItem({ label: "Second Item" }));
cMenu.addChild(new dijit.MenuItem({ label: "Third Item" }));
cMenu.addChild(new dijit.MenuItem({ label: "Fourth Item is truly a really, really, really long item" }));
// TRIGGER
cTrigger = new my.MenuTrigger({
id: "cTrigger",
popup: cMenu
}).placeAt(dojo.body());
cTrigger = new my.MenuTrigger({
id: "cTrigger2",
popup: cMenu
}).placeAt(dojo.byId('contextTriggerContainer2'));
});
As I can see from dijit.Menu source code the feature you want isn't supported out of box.
What I can think of is declaring a new widget inheriting from dijit.Menu and override bindDomNode method. It binds _openMyself handler to onClick event like this:
dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, "_openMyself")
_openMyself handler takes coords from the event object that comes in as an argument.
So the idea is to pass a fabricated event object with the desired coords.
dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, function(){
var e = { target: desiredTarget, pageX: desiredX, pageY: desiredY };
this._openMyself(e);
});