Dojo - Adding dijit to a closed TitlePane - javascript

When the open property of TitlePane is set to false, I can't add an widgets dynamically to the content.
For example, the following code does not work.
var tp = new dijit.TitlePane({
title: "Title Pane"
, content: ""
, open: false
})
var tabs = new dijit.layout.TabContainer({
region:"center"
, content:"Service Details"
, tabStrip: true
}).placeAt(tp.containerNode);
But when the open property is set to true, the tab container appears.
var tp = new dijit.TitlePane({
title: "Title Pane"
, content: ""
, open: true
})
var tabs = new dijit.layout.TabContainer({
region:"center"
, content:"Service Details"
, tabStrip: true
}).placeAt(tp.containerNode);
How can I add widgets to a TitlePane when the open property set to false?

Are you sure you're calling startup properly on your programmatically-created widgets? The following works for me whether open is true or false:
dojo.require('dijit.TitlePane');
dojo.require('dijit.layout.TabContainer');
dojo.require('dijit.layout.ContentPane');
dojo.ready(function() {
var tp = new dijit.TitlePane({
title: "Title Pane",
content: "",
open: false
}).placeAt(dojo.body());
var tabs = new dijit.layout.TabContainer({
region: "center",
content: "Service Details",
tabStrip: true
}).placeAt(tp.containerNode);
tabs.startup();
tabs.addChild(new dijit.layout.ContentPane({
title: 'foo', content: 'bar'
}));
//putting this after adding the tabcontainer
//avoids problems when open is initially true
tp.startup();
});
To clarify on calling startup:
Generally, any time you programatically create a widget, you need to manually call its startup. However...
The general exception to this is when dealing with children of container or layout widgets (in this case dijit.TitlePane which extends dijit.layout.ContentPane, which behaves like a layout widget) - these look for children to call startup on when they are started themselves (or in the case of ContentPane, also when new content is set/loaded).
Container widgets (not ContentPane, but e.g. BorderContainer, StackContainer and its subclasses such as AccordionContainer and TabContainer) also call startup on children added after the container is already started.

Related

ExtJS Hide tab on close, not delete

I have the following code which creates a tab inside of a tabpanel:
id: 'tabs',
region: 'center',
xtype: 'tabpanel',
autoDestroy: false,
items:[{
xtype: 'country-rate-grid',
id: 'LegalCompliance',
title: 'Legal Compliance',
store: 'RateManagement.store.LegalRateStore',
hidden: true,
closable: true,
listeners: {
'close': function(tab, eOpts) {
tab.hide();
}
}
}
When I close the tab via the X button, and then try to re-open it via tabs.child('#'+record.data.id).tab.show();, I get this error in the console:
Uncaught TypeError: Cannot read property 'tab' of null
It looks like it is deleting the tab instead of hiding it. How can I just show and hide my tabs instead of deleting them from the DOM when someone clicks the close button on the tab?
Quoting Ext JS 4.2.2 docs:
Note: By default, a tab's close tool destroys the child tab Component and all its descendants. This makes the child tab Component, and all its descendants unusable. To enable re-use of a tab, configure the TabPanel with autoDestroy: false.
EDIT: Ok, now I think I get what you're trying to do and where it went wrong. I've looked up the code and it looks like autoDestroy: false does not in fact destroy a container's child, but it detaches that child from the document body and removes it from the container's children collection. That's why you're seeing it disappearing from the DOM. The DOM nodes are not lost however, and are appended to the detached body element that is available through Ext.getDetachedBody(). That's also why you can't refer to the component by calling tabs.child(blah) - the tab has been removed from there.
So if you're trying to kind of hide a tab panel upon closing, to be able to show it again, you'd have to re-insert it back into the tab panel:
Ext.onReady(function() {
var tabs = Ext.create('Ext.tab.Panel', {
renderTo: document.body,
width: 300,
height: 200,
autoDestroy: false,
items: [{
id: 'foo',
title: 'Foo',
closable: true,
html: 'foo bar'
}, {
id: 'bar',
title: 'bar',
closable: false,
items: [{
xtype: 'button',
text: 'Bring foo back!',
handler: function() {
var foo = Ext.getCmp('foo');
foo.ensureAttachedToBody();
tabs.insert(foo);
}
}]
}]
});
});
foo.ensureAttachedToBody() will re-attach the DOM nodes for that panel back to the document body, and then we insert it into the tab panel as if nothing had happened. Voila.

Ember.js - having a subnav display on application.hbs on click only without rendering a different template

I'm having issues trying to get a subnav to display on click in Ember. In my application template I have a nav bar, and at the root I have the index template which is a full browser width template sitting behind the navbar on application template. Looks like this:
What I want to happen is when 'ABOUT' is clicked, a subnav displays on the white horizontal bar directly below the main nav. The white horizontal bar is also part of the application template. That's the only thing on the page that I want to change though when 'ABOUT' is clicked. Then when when you click an item on the subnav, say 'STAFF' it renders the about.staff template.
My problem is getting this to happen on the application template. Because if the user is currently on the 'PROGRAMS' template, and then they click about, I want the user to stay on the programs template but the subnav to still drop down below the main nav.
I've tried nested routes:
Ew.Router.map ->
#.resource "about", ->
#.route "philosophy"
#.route "leadership"
#.route "staff"
#.route "affiliations"
#.route "conditions"
#.route "programs"
#.route "testimonials"
Then I tried rendering a named outlet in application hbs with the following ApplicationRoute
Ew.ApplicationRoute = Ember.Route.extend(
renderTemplate: ->
#.render
#.render 'about',
outlet: 'about',
into: 'application'
)
But I'm just getting an error:
Error while loading route: TypeError {} ember.js?body=1:382
Uncaught TypeError: Cannot call method 'connectOutlet' of undefined
I would like to do this without having to hack a bunch of jquery into it. I hope this makes sense, I really appreciate any help.
The way I've set up my sub nav, is just using a sub-nav.hbs template, and a SubNavController to manage the active state. I render it from my main template like this:
{{render 'sub-nav'}}
You could write code in your SubNavController to determine which links to show. Hope this helps a little.
Here's my SubNavController. This is for something like a "wizard" flow, so I don't want all the links to be enabled. (I'm also using an Ember StateManager object to manage the state of my app.)
MyApp.SubNavController = Ember.Controller.extend({
getAllStates: function() {
return [
{ name: "start", label: "Start", active: true, enabled: true, href: "#/myapp/start"},
{ name: "drivers", label: "Driver", href: "#/myapp/driver"},
{ name: "vehicles", label: "Vehicle", href: "#/myapp/vehicle"},
{ name: "details", label: "Details", href: "#/myapp/details"}
];
},
init: function() {
this.set('states', this.getAllStates());
this.setActive();
},
setActive: function() {
// TODO: Clean this up. it's a little hacky.
Ember.Logger.debug("current state: " + MyApp.stateManager.get('currentState.name'));
var i = 0,
newStates = this.getAllStates(),
statesLength = newStates.length,
activeIndex = 0;
for (i=0; i< statesLength; i++) {
newStates[i].active = false;
if (newStates[i].name===MyApp.stateManager.get('currentState.name')) {
newStates[i].active = true;
activeIndex = i;
}
}
for(i=activeIndex; i<statesLength; i++) {
delete newStates[i].href;
}
this.set('states', newStates);
}.observes('MyApp.stateManager.currentState')
});

How to submit data from Ext.FormPanel with tabs?

There are several tabs on a FormPanel:
Code:
var podform = new Ext.FormPanel({
labelAlign: 'left',
id: 'tab_6',
frame:true,
title: 'Договоры подряда',
bodyStyle:'padding:5px 5px 0',
width: 600,
listeners: {
'activate' : function(podform,records,options) {
console.log("store:"+store_form);
this.loaded = true;
var record = store_form.getAt(0);
podform.getForm().loadRecord(record);
}
},
reader : new Ext.data.XmlReader({
record : 'zem',
// success: '#success'
}, [
]),
items: []
});
podform.add(tabs_pod);
Now i try submit data to server:
podform.addButton({
text: 'Submit',
//disabled:true,
handler: function(){
podform.getForm().submit({
url:url_servlet+'submit.jsp',
waitMsg:'Saving Data...',
success: function(form, action) {
Ext.Msg.show({
title:'Success'
,msg:'Form submitted successfully'
,modal:true
,icon:Ext.Msg.INFO
,buttons:Ext.Msg.OK
});
}
});
}
});
But firebug says that i subbmit data only with panels that I have seen. Its means if i not click on second tab i cant get data from it.
Its possible to fix it?
UPDATE
When i use deferredRender:false, first tab shows normal but another tabs looks like this:
I think the problem you are seeing is that the tab panel is not rendering the fields in inactive tabs dues to lazy rendering - a performance enhancing technique. You can try to explicitly force rendering of those sub panels with deferredRender:false
see full doc here
ExtJS 3.4 -> http://docs.sencha.com/ext-js/3-4/#!/api/Ext.TabPanel-cfg-deferredRender
ExtJS 4.1 -> http://docs.sencha.com/ext-js/4-1/#!/api/Ext.tab.Panel-cfg-deferredRender

how to load mask while the grid is double clicked to wait for the detail window

forum member I am having one problem while using the loadMask property of the extjs 4.0.2a. Actually I am having one grid which on click open the window with detail information.
As my detail window takes more time to come on screen, so I just decided to make use of the loadMask property of Extjs. But don't know why the loading message is not shown when I double click the grid row and after some time the detail window is shown on the screen.
on grid double click I am executing the below code
projectEditTask: function(grid,cell,row,col,e) {
var myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Loading.."});
myMask.show();
var win = this.getProjectGanttwindow();
win.on('show', myMask.hide, myMask);
}
but don't know the loading is not displayed and after waiting for some moment my window is shown correctly.
I just want when I double click the grid Loading message should be displayed and after when the window is load completely Loading message should be dissapear and detail window should be viewed.
when I made the changes as per you said the loading message is displayed but my window is not opened yet. below is the code of window I am trying to open
my projectGanttwindow is
Ext.define('gantt.view.projectmgt.projectGanttwindow' ,{
extend: 'Ext.window.Window',
alias : 'widget.projectganttwindow',
requires: ['gantt.view.projectmgt.projectGanttpanel'],
editform:1,
id: 'projectganttwindow',
title: 'Project Management',
width: '100%',
height: '100%',
closeAction: 'destroy',
isWindow: true,
flex:1,
isModal: true,
constrain: true,
maximizable: true,
stateful: false,
projectId: null, // this will be set before showing window
listeners: {
hide: function() {
alert('hide');
//var store = Ext.data.StoreManager.lookup('taskStore').destroyStore();
//Ext.destroy(store);
//store.destroyStore();
console.log('Done destroying');
}
},
initComponent: function() {
var me = this;
me.layoutConfig = {
align: 'stretch'
};
me.items = [{
xtype: 'projectganttpanel',
allowBlank: false
}];
me.callParent(arguments);
me.on({
scope: me,
beforeshow: me.onBeforeShow
});
},
onBeforeShow: function() {
var projectId = this.projectId;
console.log('BEFOR SHOW ::'+projectId);
if(projectId != null) {
var store = Ext.data.StoreManager.lookup('taskStore');
store.load({
params: {'id': projectId}
});
}
}
});
Try this
function loadMask(el,flag,msg){
var Mask = new Ext.LoadMask(Ext.get(el), {msg:msg});
if(flag)
Mask.show();
else
Mask.hide();
}
When u click on grid call this function
//Enable mask message
loadMask(Ext.getBody(),'1','Please wait...');
After pop loaded call
//Disable mask Message
loadMask(Ext.getBody(),'','Please wait...');

ExtJS buttons won't accept "id" config parameter?

I need specific IDs on ExtJS generated window buttons, but I'm having trouble specifying the ID. The documentation claims that this should be possible, but I still get an autogenerated id when I specify my own.
What gives?
dialog = new Ext.Window({
closeAction:'hide',
plain: true,
buttons: [
{
id: 'my-dialog',
text: 'Done',
handler: function() {
dialog.hide();
}
}
],
items:new Ext.Panel({
applyTo:'add-document-popup-panel'
}),
title: 'Add Documents',
layout: 'fit',
resizable: false,
draggable: false,
width: 300,
height: 300,
modal: true
});
}
dialog.show(this);
Check this topic: http://www.sencha.com/forum/showthread.php?24433-CLOSED-Cannot-assign-id-to-button-extjs-bug
The id of the container of the button is set, not the HTML button itself.
The id you specify is assigned to the button component (specific to extjs) and not necessarily to the underlying html button.
Does Ext.getCmp('my-dialog') successfully return the extjs button component?
The ID is set, but not on the actual button element. One of the containers is set with the correct id, and you can probably key off of this to get at whatever you need.
I had the same problem and I confirm:
The ID is set in the button's TABLE container.
Ext.getCmp('my-button') returns the extjs button component (object with xtype="button" and id="my-button").

Categories