Toggle icon in tabcontainer - dojo

As the title of this post already says: I'm trying to toggle an icon in my tabcontainer.
I got a TabContainer with some ContentPanes in it.
If I get some values from the database I show them in the ContentPane and set the IconClass so the user see that there is some data.
In the my ContentPane I also got a delete and a save button.
If there was some data and the delete button is pressed I'd like to remove or to hide the Icon in the Tab.
Of course I want to do the other way, too.
But how do I do it?
I tried it with registry.byId("myIdOfTheContentPaneWhereTheIconClasswasDefined").className="dijitNoIcon"
without an effect.
Any ideas?

Try setting iconClass instead of className.
Proof-of-concept:
require([
'dijit/layout/TabContainer',
'dijit/layout/ContentPane'
], function(TabContainer, ContentPane){
var container = new TabContainer({ id: 'container' }).placeAt(document.body);
var pane = new ContentPane({
iconClass: 'dijitIconSave',
title: 'Tab'
}).placeAt(container);
container.startup();
setTimeout(function () {
pane.set('iconClass', '');
}, 2000);
});

registry.byId returns you a widget, not a domNode.
This should work:
registry.byId("myIdOfTheContentPaneWhereTheIconClasswasDefined").domNode.className="dijitNoIcon
although it is not elegant at all...

Related

How to pop to the parent window in a tab?

I am trying to replace the default Back button to a custom image button in a Titanium iOS project.
I am opening several windows in a tab with the following code:
currentTab.open(childWindow);
How do I "pop" back to the previous (parent) window?
I tried the following:
childWindow.close();
and:
currentTab.close(childWindow);
But both don't work. What am I doing wrong?
They added a method named popToRootWindow in Ti SDK 6.2
Reference : http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Tab-method-popToRootWindow
It's hard to say what is wrong on your side without checking the actual code. However here is the snippet of code which does exactly what you are looking for. It allows to open two windows in one tab. The onclick listener on the second window simple closes this window. It in turn triggers the first window to come up. Maybe it can be helpful to spot a problem in your code.
Here is the contents of index.js:
$.index.open();
var tabGroup = Titanium.UI.createTabGroup();
var win1 = Titanium.UI.createWindow({title: 'Window 1'});
win1.add(Titanium.UI.createLabel({text: 'Window 1'}));
var button1 = Titanium.UI.createButton({bottom: 0, title: 'Next'});
win1.add(button1);
button1.addEventListener('click', function (e) {
var win2 = Titanium.UI.createWindow({title: 'Window 2'});
win2.add(Titanium.UI.createLabel({text: 'Window 2'}));
var button2 = Titanium.UI.createButton({bottom: 0, title: 'Back to Window 1'});
win2.add(button2);
button2.addEventListener('click', function (e) {
win2.close();
});
tab.open(win2);
});
var tab = Titanium.UI.createTab({title: 'Tab 1', window: win1});
tabGroup.addTab(tab);
tabGroup.open();
Note: index.xml file for this example can be very simple: with only one empty element Window class="container"
Andrew's answer helped and I solved the problem with win.close() function call.
The reason it was giving the following error:
Undefined is not a variable.
was because I was trying to access the window variable with a wrong reference.
this.backButton.addEventListener("click", function() {
this.win.close();
});
this.win was the variable for the child window, and stupidly I used the same inside the backButton event listener, where this was recognized as the callback function and it gave me the above error.
Just changing it to the following helped.
_this = this;
this.backButton.addEventListener("click", function() {
_this.win.close();
});

setActiveItem doesn't work from panel sencha

I have a list in tab panel and i added onItemDisclosure which supposed to switch to an into page (inside the tab panel).
The setActiveItem does not work, and the error I got is that: [undefined] is not a function.
Code:
Toolbar.views.listPanel = Ext.extend(Ext.List,{
id:'mylist',
store:ListStore,
itemTpl: '<div class="stores"><b>{name}</b><br/><p style="font-size:small">{address}{distance}Km</p></div>',
//grouped:true,
onItemDisclosure: function(){
//Ext.Msg.alert("closure works!");
//Toolbar.views.detailPanel.update();
//alert(Toolbar.views.detailPanel);
Toolbar.views.Searchcard.setActiveItem(Toolbar.views.detailPanel,{type:'slide',direction:'left'});
}
});
The panel to switch to:
Toolbar.views.detailPanel = Ext.extend(Ext.Panel,{
id:'detailpanel',
tpl:'Hello!'
});
Ext.reg('searchcard', Toolbar.views.Searchcard);
Ext.reg('listPanel', Toolbar.views.listPanel);
Ext.reg('detailPanel', Toolbar.views.detailPanel);
Thanks in advance,
The problem is you're referencing the class not the instance of the Searchcard. You have to reference it using a component query.
Generally it follows this way:
masterComponent.getComponent('your_component_itemID');
Or you can use panel.query(selector)
http://docs.sencha.com/touch/1-1/#!/api/Ext.Panel-method-query
Really instead of just hacking it through have a look at this article:
http://www.sencha.com/learn/a-sencha-touch-mvc-application-with-phonegap/

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.

Dojo - How to programatically create ToolTip Dialog on link click

As the title says. I want to create TooltipDialog, after I click link and load custom content into that dialog. The tooltip body is complete placeholder, I just haven't done any server logic to handle this.
So far i got to this point:
PreviewThread: function (ThreadID) {
var tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation
});
},
Preview
The point is not even how to load content, into dialog, but how to open it in the first place ?
After more googling and trial & error I finally got to this:
PreviewThread: function (ThreadID) {
var tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation,
closable: true
});
dojo.query(".thread-preview").connect("onclick", function () {
dijit.popup.open({ popup: tooltip, around: this });
});
},
It's somehow working. ToolTipDialog opens, but.. I have to click twice and and I can't close dialog after click outside it, or after mouseleave.
Ok this, going to start look like dev log, but hopefully it will save others some headchace:
I finally managed to popup it where I want to:
PreviewThread: function (ThreadID) {
var tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation,
closable: true
});
dijit.popup.open({ popup: tooltip, around: dojo.byId("thread-preview-" + ThreadID) });
},
<a href="javascript:Jaxi.PreviewThread(#thread.ThreadID)" id="#tp.ToString()" >Click Me</a>
Note that I'm using Asp .NET MVC.
Now only thing left is to close damn thing in user friendly manner..
There are afaik two ways you can do this, and neither one is very elegant tbh :-P
The first is to use dijit.popup.open() and close() to show and hide the dialog. In this case, you have to provide the desired coordinates. I see that you only provide your PreviewThread function with a thread id, but assuming you also tack on the event object, you can do:
PreviewThread: function (ThreadID, event) {
Jaxi.tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation
});
dijit.popup.open({
popup: Jaxi.tooltip,
x: event.target.pageX,
y: event.target.pageY
});
}
When you're using this method, you also have to manually close the popup, for example when something outside is clicked. This means you need a reference to your tooltip dijit somewhere, for example Jaxi.tooltip like I did above. (Side note: dijit.TooltipDialog is actually a singleton, so there won't be lots of hidden tooltips around your page). I usually end up with something like this for hiding my tooltip dialogs.
dojo.connect(dojo.body(), "click", function(event)
{
if(!dojo.hasClass(event.target, "dijitTooltipContents"))
dijit.popup.close(Jaxi.tooltip);
});
This may of course not work for you, so you'll have to figure out something that suits your particular arrangement.
The second way is to use the dijit.form.DropDownButton, but styling it as if it was a link. I'm not going to go into details on this, just instantiate a DropDownButton on your page and use Firebug to tweak it until it looks like your regular links. FYC, link to DropDownButton reference guide.
You may try:
PreviewThread: function (ThreadID) {
var tooltip = new dijit.TooltipDialog({
href: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation,
closable: true,
onMouseLeave: function(){dijit.popup.close(tooltip);}
});
dijit.popup.open({ popup: tooltip, around: dojo.byId("thread-preview-" + ThreadID) });
},
This will close the dialog as soon as you moove the mouse out of the dialog.
Check the API for all possible events:
http://dojotoolkit.org/api/

Dojo: create programatically a menu in an enhancedgrid

I'm trying to create programatically an EnahncedGrid with a menu. I've got the grid to work, but I've been unable to use the menu. It just not shows up. The code is as follows:
<script>
sMenu = new dijit.Menu({});
sMenu.addChild(new dijit.MenuItem({
label: "Delete Record",
iconClass: "dijitEditorIcon dijitEditorIconCancel",
onClick : function(){
alert(1);
}
}));
sMenu.startup();
/**
* El grid propiamente dicho
*/
var grid = new dojox.grid.EnhancedGrid({
id: "grid_"+i,
query: {
idDocument: '*'
},
plugins: {
nestedSorting: true,
indirectSelection: true,
menus: {rowMenu:sMenu}
},
onRowDblClick: openFile,
structure: layout
})
</script>
Any idea what I'm doing wrong?
I haven't used this myself, but I have two possible suggestions:
First, make sure you're dojo.require-ing "dojox.grid.enhanced.plugins.Menu" and are only instantiating the widgets within a dojo.addOnLoad or dojo.ready.
If you've already done that, the second thing I'd suggest is giving your menu an id, and passing that id to the rowMenu property of the menus object (in other words, pass a string, not the widget itself). Although, the way you're doing it seems like it should work, judging from the code.
You can see a test page with working menus here: http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/grid/tests/enhanced/test_enhanced_grid_menus.html