How can I replace the content of a panel with new content? - extjs

I have a regionContent panel which I add to my viewport.
How can I replace its content with new content?
...
var regionContent = new Ext.Panel({
id: 'contentArea',
region: 'center',
padding:'10',
autoScroll: true,
html: 'this is the original content'
});
var viewport = new Ext.Viewport({
layout: 'border',
items: [ regionMenu, regionContent ]
});
var newPanel = new Ext.Panel({
region: 'east',
title: 'Info Panel',
width: 300,
html: 'this is a panel that is added'
});
// regionContent.update(newPanel); //renders as javascript code ???
// regionContent.remove(...) //how do I remove ALL CONTENT, I will not know what is in this panel to remove it specifically
regionContent.add(newPanel); //adds to original content but does not replace it
regionContent.doLayout();
...
.update() does this:
.add() does this:

You'll want to use a panel with card layout:
var card=new Ext.Panel({
layout:'card',
activeItem:0,
items:[ regionContent , newPanel ]
});
That panel can then go inside your viewport. To switch between them you'll use something like this:
card.getLayout().setActiveItem(1);
Take a look at the two card layouts for working examples:
http://dev.extjs.com/deploy/dev/examples/layout-browser/layout-browser.html

You cannot remove the HTML using .remove(), because it's not considered an item of a panel. So you need to use .update() to get rid of that HTML, and then add your new panel.
// clear the html by replacing it with an empty string.
// calling update with no arguments would work as well.
regionContent.update('');
// add the new component
regionContent.add(newPanel);
// redraw the containing panel
regionContent.doLayout();
From your screenshot, it looks like you may have used .update() by passing in the new panel, e.g., .update(newPanel). That method is used to update HTML, not replace components. To go the opposite way:
regionContent.removeAll(); // if you want to remove all the items
regionContent.update('this is the original content');
regionContent.doLayout();
Did you really use the solution you posted to solve this exact problem? For me clearExtjsComponent() leaves the HTML string "This is the original content" behind, just like in your screenshot.

Ext.getCmp('content-panel').body.update(record.get('id'));
This will really work

Here's how I solved this:
function clearExtjsComponent(cmp) {
var f;
while(f = cmp.items.first()){
cmp.remove(f, true);
}
}
then when I want to replace the content of a panel with new content, I use this:
function replaceComponentContent(cmpParent, cmpContent) {
clearExtjsComponent(cmpParent);
cmpParent.add(cmpContent);
cmpParent.doLayout();
}

Related

Add a CSS class to the TAB in TabBar, not the tab it self

Here is a screenshot to visualize what I want to do.
There is an extra tab which is iconless (between exit and project).
The blue highlighted line is the element itself in the inspector.
My goal is to set the tab's width in the tabbar and not in the tabpanel to 5px.
So That it would act has a spacer between tabs' icons.
I tried to manually add a CSS class so that I could create a very specific rule pointing to that element and inside this rule set the width to 5px with an !important tag.
.x-tab .x-tab-normal .x-item-disabled .x-iconalign-center .x-tab-icon .x-layout-box-item .x-stretched
{
width:5px !important;
}
Sadly I never found a way to add a class at that particular level of the component hierarchy.
So I tried to replace an existing CSS class of that component (.x-item-disabled).
I changed .x-item-disabled to .fake and than created a CSS rule accordingly...
It did not work and has in the first case, the component's css classes in the inspector did not changed at all..
I'm pretty sure I need to do it that way since it's not something sencha allows us to do.
Can someone help me out plz?
Ext.tab.Bar and Ext.tab.Tab are private classes and Ext.tab.Panel does not seem to expose that feature, so I guess at the moment there is no simple way to do what you ask. Those tabs are built based on the Panel items configuration, but the data you pass in are not directly mapped to them. Indeed if you apply a cls or style property to an item configuration, that goes to the content of the panel, not to its associated tab. You can however modify the tab after your panel has been initialized:
Try this:
Ext.create('Ext.TabPanel', {
fullscreen: true,
tabBarPosition: 'bottom',
defaults: {
styleHtmlContent: true
},
items: [
{
title: 'Home',
iconCls: 'home',
html: 'Home Screen'
},
{
title: '',
iconCls: 'dummy',
html: ''
},
{
title: 'Contact',
iconCls: 'user',
html: 'Contact Screen'
}
],
initialize: function() {
// get spacer by position, it's ugly but it works
// without extending Sencha components
var spacer = this.getTabBar().getAt(1);
// of course here you could apply a CSS class
// if you prefer
spacer.setStyle('width:5px; min-width:5px;');
// let's also disable the button
spacer.setDisabled(true);
// and remove the icon since it is mandatory in Panel
// config but we don't really want it
spacer.setIcon(false);
}
});
See the fiddle.
Add
this.callParent(arguments);
code in your initialize function in answer 1

ExtJS (3.4): Update ToolTip for a Panel in a TabPanel

How do I change the tooltip for a panel located in a tab panel? Originally, I created a tooltip using the tabtip parameter of the panel constructor as the panel was added to the tabpanel.
You need to grab the DOM element that represents your tab's tab strip. You can use tabPanel.getTabEl(tabID) to get the strip element. You can then grab the .x-tab-strip-text span and set its qtip property.
// be sure to set your tab's itemId
var tabPanel = new Ext.TabPanel({
items: [{
title: 'one tab',
tabTip: 'something',
itemId: 'firstTabID',
html: 'haha wooo'
}]
});
// later...
// .getTabEl grabs the tabstrip DOM element
// Ext.get converts it to an Ext.Element
Ext.get( tabPanel.getTabEl('firstTabID') )
// find its descendent span that contains the tab's title text
.child('span.x-tab-strip-text', true)
// and set the tool tip
.qtip = 'something completely different!';
I'd never changed tab tooltips before so I dug around the Ext.TabPanel source looking at how they set it. I learned something too :)

Can't redraw Panel in ExtJS

I made the sufficient investigation of this problem. But unfortunately didn't find any solution, even in stackoverflow questions, that look like this one.
I need to redraw(refresh, re-render) a panel, that contains a tabPanel with different tabs, that are rebuilding each time when I open the panel. Here is the code below to build tabs
//the first tab
categoryTpl: function(){
var categoriesTab = new Ext.Panel({
id: '_Categories',
title: 'X-Axis',
layout: 'form',
padding: 10,
labelWidth: 101,
items: [...]
})
}
Here is code to build the TabPanel
setAxesInfo: function(){
var categoryTab = this.categoryTpl();
//initialize the controls in the first tab
FC.Var.CM.initAxis(categoryTab, undefined);
delete this.axesTabPan;
this.axesTabPan = new Ext.TabPanel({
activeTab: 0,
plain: true,
enableTabScroll: true,
autoScroll: false,
defaults: { autoScroll: true },
items: [categoryTab]
});
}
This is the code to build Panel
create: function(){
this.setAxesInfo();
this.axes = new Ext.Panel({
layout: 'fit',
border: false,
items: this.axesTabPan
});
return {
id: 'axesStep',
title: 'Series Customization',
items: this.axes
}
}
So, I make changes in tab controls and then I want to rebuild(refresh, re-render) my panel I click the button, which have the next handler
refreshAxes: function() {
this.axes.removeAll();
this.setAxesInfo();
this.axes.add(this.axesTabPan);
this.axes.doLayout();
}
So, in debugger I can see, that all my controls in the tab have default initial values (they were rebuilt as I see). But in the browser I see only the previous changed values. It's notable, that if I change the focus of my panel (for example switch to another panel) and then return to this panel all data have the default values. Why I don't see the default values without loosing focus?
I am using the Ext Js 3.4 (this version is the requirement). I'll appreciate any help. Thank you.
Try doing a doLayout() on the Panel.

Why doesn't a simple click: function()... work in ExtJS?

When the user clicks on this element, I want it to show an alert.
However, when I click on the DIV that this Panel generates, nothing happens.
How can I make an alert execute when the user clicks on the following panel?
var content = new Ext.Panel({
region:'center',
margins:'5 0 5 5',
cls:'empty',
bodyStyle:'background:ivory; font-size: 13pt',
html:'<p id="test123">This is where the content goes for each selection.</p>',
click: function() {
alert('was clicked');
}
});
You haven't accepted an answer, so I'll assume you're still unclear on this. Here are a few pointers...
First, as coded your Panel will render as a plain square. If you're expecting it to look like a Panel, you should give it a title (so the title bar will render).
Second, as mentioned, click is not a Panel event (it's an Element event). So you have several ways of getting to the behavior you want. You can manually attach a listener to the underlying DOM element after the Panel is rendered:
Ext.get('txest123').on('click', function(){
alert('foo');
});
You could also do as I mentioned in the comments of another answer to generically handle any body click:
// .body is a Panel property for the body element
content.body.on('click', function(){
alert('foo');
});
If you really want to restrict the click to only the child p you could add a check:
// e is the event object, t is the target DOM node
content.body.on('click', function(e,t){
if(t.id == 'txest123'){
alert('clicked the p');
}
});
If I was coding this, I'd probably do something more like this:
var content = new Ext.Panel({
region:'center',
renderTo: document.body,
margins:'5 0 5 5',
cls:'empty',
title: 'My Panel',
id: 'txest123',
bodyStyle:'background:ivory; font-size: 13pt',
html:'This is where the content goes for each selection.',
listeners: {
'render': {
fn: function() {
this.body.on('click', this.handleClick, this);
},
scope: content,
single: true
}
},
handleClick: function(e, t){
alert(this.id); // the panel
alert(t.innerHTML); // the clicked el
}
});
Now the id is on the Panel (where it should be) and you can use Panel and/or Element methods to access child elements as needed. It's best to keep id's at the highest level possible. You'll notice too that the callback function is executed in the scope of the Panel (scope:this) so that inside handleClick you can treat this as the Panel itself and access any of its properties or methods.
So, without knowing exactly what you're trying to achieve, I can't provide you with the exact code you need. However, this should hopefully give you some ideas.
EDIT: I meant to say this originally... in your code (as posted) you are not actually rendering the Panel. As I mentioned in my answer to your related question, if you are adding the Panel as an item to a container that is lazy-rendered, the Panel's DOM won't be available for selection until after the container has rendered it. In my code above I added renderTo so that I don't have this issue, but if you're not doing that you'll have to wait until the Panel is rendered at some time later to access it.
The Panel Component does not expose a click event, so the one you're passing into the config never gets fired.
Try putting an id on your Ext.Panel object and then getting its element using Ext.get(). Then add a click event through on():
var content = new Ext.Panel({
id: 'myPanel',
region:'center',
margins:'5 0 5 5',
cls:'empty',
bodyStyle:'background:ivory; font-size: 13pt',
html:'<p id="txest123">This is where the content goes for each selection.</p>'
});
Ext.get('myPanel').on('click', function() {alert('You clicked me');});
The following sample is a bit rough but it works for me. It is a panel with a box component, which is showing a thumbnail. When clicking on the thumbnail, it is showing a lightbox with slimbox2. Not pretty, but very effective. The hardcoded images are just for test here.
var panel = new Ext.Panel({
title : 'Image',
header : false,
frame : true,
border : false,
bodyStyle : 'padding : 5px',
width : 125,
items : [{
xtype : 'box',
height : 115,
width : 115,
listeners : {
'render': function() {
var id = Ext.id(this);
Ext.fly(id).addListener('click', function () {
jQuery.slimbox('thisisnotanimage', 'CBX');
});
}
},
autoEl: {
tag : 'div',
html : 'somehtmltagstuff'
}
}
]
});
According to the API, click is not a valid event for Panels... However, you should still be able to add the click event to the underlying DIV element.
Ext.fly(e.id).addListener('click', Ext.getCmp(e.id) , this);
I believe you need something like:
var content = new Ext.Panel({
region:'center',
margins:'5 0 5 5',
cls:'empty',
bodyStyle:'background:ivory; font-size: 13pt',
html:'<p id="test123">This is where the content goes for each selection.</p>',
listeners: {
click: function() {
alert('was clicked');
}
}
});

Ext.form.combobox inside ext.window displays values at top left of screen

I have a combobox inside of a ext.panel, inside of an ext.window. When I click the down arrow to show the possible SELECT options, the options pop up at the top-left of the browser window, instead of below the SELECT box. The funny thing is if I attach the drugDetailsPanel (see code below) to a div on the page (instead of inside an ext.window), the combobox works correctly. This also happens when I change ext.panel to ext.form.formpanel, by the way.
Any ideas?
My code:
drugDetailsPanel = new Ext.Panel({
layout:'form',
id:'drug-details-panel',
region:'center',
title:'Drug Details',
height:200,
collapsed:false,
collapsible:false,
items:[
new Ext.form.ComboBox({
fieldLabel:'What is the status of this drug?',
typeAhead:false,
store:drugStatusStore,
displayField:'lookup',
mode:'remote',
triggerAction:'all',
editable:false,
allowBlank:false,
emptyText:'Select a status..',
name:'/drug/drug-status',
id:'drug-status'
})
]
});
newDrugWindow = new Ext.Window({
title: 'Add Drug',
closable:true,
width:650,
height:650,
//border:false,
plain:true,
layout: 'border',
items: [drugDetailsPanel],
closeAction:'hide',
modal:true,
buttons: [
{
text:'Close',
disabled:false,
handler: function(){
newDrugWindow.hide();
}
},
{
text:'Save Drug',
handler: function(){
newDrugDialog.hide();
}
}]
});
Try to add shim: true to combo-box control.
Older versions of Ext had issues like this in certain browsers (FF 2.x) in certain situations dealing with nested positioning, the specifics of which escape me now. If that's the case, search the Ext forums for more info. If not, then I'm not sure...
This forum thread helped me: http://www.sencha.com/forum/showthread.php?177677-IE-displays-combobox-dropdown-in-the-top-left-corner-of-browser-window
Just give the combobox a (unique) name. Giving the combobox an inputId should also help
Seems like IE does not respect the position of the element if it does not have an explicit name/inputId. This thread goes more deeply into it: http://www.sencha.com/forum/showthread.php?154412-Combo-Box-options-appears-in-Top-Left-Corner-in-IE-9

Resources