ExtJS Hide tab on close, not delete - javascript

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.

Related

Extjs4 fieldset.show() and fieldset.hide() is not a function issue

I have a problem with fieldsets show and hide functions.
In my app at the left side I have a combobox with change listener. At the right side I have several different textfields which are showing and hiding according as chosen value in combobox.
Every hide and show functions are working with fieldsets, but if I can't to show/hide fieldset. Fieldset reference is visible, I can list this component with console.log() function.
Here's a piece of my code:
var rigthPanelLeftContainer = {
flex: 1,
minWidth: 200,
defaults: {
xtype: 'textfield',
minWidth: 180,
anchor: '100%'
},
items: [
//some working textfields here
{
xtype: 'fieldset',
labelWidth: 160,
anchor: '100%',
height: 40,
itemId: 'remarkId',
title: 'title'],
hidden : !ifHideIt, //boolean
items: [{
xtype: 'text',
height: 25,
text: 'sometext']
}]
}
]};
var comboBoxConnectors = {
xtype: 'combobox',
fieldLabel: Ext.translations.map['field.label.common'],
store: Ext.state.Manager.get('conTypes'),
editable: false,
queryMode: 'local',
name: 'conType',
itemId: 'conTypeField',
value: connObj === null ? conTypes[0] : connObj.type,
labelWidth: 160,
anchor: '100%',
listeners: {
change: function(obj, newValue, oldValue) {
//many hide/show working on textfield functions
var remarkId = me.query('#remarkId');
console.log(remarkId); //returns my fieldset element
remarkId.hide(); //returns remarkId.hide is not a function
}
}
}
I really need your help guys, whats wrong with this?
In your code, you have a comment that says that me.query( '#remarkId' ) returns your fieldset element. This is not technically correct. Assuming that me.query() is a component query, what you are actually getting in return is an array of matched components. So then, you're getting the undefined function error because, most definitely, an array does not have a hide() method. If you access the first element in the array and then call the hide() method, it should work.
However, you should probably also consider going about this a bit differently. Instead of getting an array of elements with query() (which may always be one, but not necessarily...), you could use the built in traversal methods to find the correct component. For example, assuming that the combobox and the fieldset are both children of the same form panel, you could do something like this: mycombobox.up( 'form' ).down( 'fieldset#remarkId' ). This basically instructs the code to traverse up the component hierarchy to the nearest form, then to drill down to the first descendant of the form that is a fieldset with the itemId of "remarkId". This will only ever give you a single component as a result, so you don't have to bother with accessing a component out of an array of components.

EXTJS Display a View within Ext.window.Window

I am using version 4.2.
I currently have a view which extends a panel. On this panel there is a button which displays a modal window. The controller code when the button is clicked is below (which I pulled from the extjs docs):
displaySearch : function(btn) {
var panel = Ext.create('Ext.window.Window', {
title: 'Hello',
height: 200,
width: 400,
layout: 'fit',
modal : true,
items: {
...
}
}).show();
}
I want a View I already have created to be rendered INSIDE the modal window I just defined.
How do I do that?
If you have defined an alias (xtype) for that view, let's say it is 'myview', then you just add it to items like this:
var panel = Ext.create('Ext.window.Window', {
title: 'Hello',
height: 200,
width: 400,
autoShow:true,
layout: 'fit',
modal : true,
items: [{
xtype:'myview'
}]
});
Also, you don't need to call show() on the created window, it is enough if you configure autoShow:true.

extjs displaying loadmask on panel when store loads

I added a loadmask to a panel and I want the spinner to be displayed each time stores associated with the loadmask are loaded. The panel is a large tooltip and the stores are loaded each time a point is visited in a line chart. Thus, when I hover over a point, I'm expecting a load message to appear for a short period of time before I see the contents in the panel. What I'm getting is an empty panel however. If I remove the code that I have which adds the load mask (the initComponent function), it works (without the load message though). How would I use the loadmask in this manner as opposed to explicitly calling the setLoading() method for each panel?
Here's the code:
tips:
{
...
items:{
xtype: 'panel',
initComponent: function(){
var loadMask = new Ext.LoadMask(this, {
store: Ext.getStore('CompanyContext')
});
},
id: 'bar-tip-panel',
width: 700,
height: 700,
layout: {
type: 'accordion',
align : 'stretch',
padding: '5 5 5 5'
},
items:...
}
}
config object isn't the proper place to override initComponent method. What you should do is to define a subclass of Panel, and override the method there.
Ext.define('MyPanel', {
extend: 'Ext.panel.Panel',
xtype: 'mypanel',
initComponent: function() {
this.callParent(arguments); // MUST call parent's method
var loadMask = new Ext.LoadMask(this, {
store: ...
});
},
});
Then, you can use xtype mypanel in your tips configuration.

Sencha Touch 2: How to override back button on Navigation View

I was wondering how to ovverride the back button on a navigation view. I tried using onBackButtonTap but it doesnt seem to work http://www.senchafiddle.com/#8zaXf
var view = Ext.Viewport.add({
xtype: 'navigationview',
onBackButtonTap: function () {
alert('Back Button Pressed');
},
//we only give it one item by default, which will be the only item in the 'stack' when it loads
items: [
{
//items can have titles
title: 'Navigation View',
padding: 10,
//inside this first item we are going to add a button
items: [
{
xtype: 'button',
text: 'Push another view!',
handler: function() {
//when someone taps this button, it will push another view into stack
view.push({
//this one also has a title
title: 'Second View',
padding: 10,
//once again, this view has one button
items: [
{
xtype: 'button',
text: 'Pop this view!',
handler: function() {
//and when you press this button, it will pop the current view (this) out of the stack
view.pop();
}
}
]
});
The fiddle you've mentioned works well in my local project on my machine. For some reason, it doesn't work on fiddle site. Try running it on your local project.
Still instead of using onBackButtonTap config, it's good to extend Ext.navigation.View class and override onBackButtonTap method. That way you'll have more control over whole components. You'd also like to override other configs as well. Here's what I'd use -
Ext.namespace('Ext.ux.so');
Ext.define('Ext.ux.so.CustomNav',{
extend:'Ext.navigation.View',
xtype:'customnav',
config:{
},
onBackButtonTap:function(){
this.callParent(arguments);
alert('back button pressed');
}
});
the line this.callParent(arguments) will allow component to behave in default way + the way to wanted it to behave. And if you want to completely override the back button behavior you can remove this line. Try doing both ways.
To use this custom component, you can use -
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
var view = Ext.create('Ext.ux.so.CustomNav', {
fullscreen: true,
items: [{
title: 'First',
items: [{
xtype: 'button',
text: 'Push a new view!',
handler: function() {
//use the push() method to push another view. It works much like
//add() or setActiveItem(). it accepts a view instance, or you can give it
//a view config.
view.push({
title: 'Second',
html: 'Second view!'
});
}
}]
}]
});
}
Give this a shot. It'll work for you yoo.

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