Adding a Panel into a Panel - extjs

I have a card layout set in my app.js. here's the code;
...
launch: function() {
var vp = Ext.create('Ext.container.Viewport', {
layout: 'card',
items: [
{
xtype: 'doctor'
},
{
xtype:'nurse'
}
]
});
}, ...
and, the first view that will load. here's the code;
Ext.define('RoyProject.view.user.Doctor', {
extend:'Ext.form.Panel',
alias : 'widget.doctor',
id:'docform',
defaultType: 'textfield',
items: [{
fieldLabel: 'Name',
name: 'name'
}],
buttons: [, {
text: 'Send',
action:'send'
}]
});
Since i am using card layout in the app.js, all the first view has got stretched out, and occupies the whole screen. Therefore, to get rid of this i thought to add a Panel and within that Panel to add my view (which is RoyProject.view.user.Doctor). Can someone help me to add this view into a Panel, without changing the logic of the code :)

launch: function() {
var vp = Ext.create('Ext.container.Viewport', {
layout: 'card',
items: [
{
xtype: 'panel',
items: { xtype: 'doctor' }
},
{
xtype:'nurse'
}
]
});
}, ...

I think you're trying to solve wrong problem. You don't need to enclose your doctor panel into another one. In general idea of nesting panels one inside another is bad...
What you need to do is to either specify fixed width for your doctor panel or play is its layout to see which one fits you better.

Related

How to remove active tab from Tab in Ext js?

I want to remove the active tab from sencha ext.
Assume that am into controller file of the view.
Note: I have used remove() as well as destroy().
destroy() function works fine but tab header is not getting removed.
coseResultTab() {
this.getView().destroy();
}
Before Clicking on Cancel button:
After Clicking on Cancel button
You should destroy the active tab in your tabpanel, eg:
Controller
Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myview',
destroyTab: function() {
this.getView().down('tabpanel').getActiveTab().destroy();
}
});
View
Ext.create('Ext.Panel', {
width: 400,
height: 400,
renderTo: document.body,
title: 'Panel',
id: 'myPanel',
controller: 'myview',
items: [{
xtype: 'tabpanel',
items: [{
title: 'Foo',
items: [{
xtype: 'button',
text: 'Destroy!',
handler(btn) {
Ext.getCmp('myPanel').getController().destroyTab();
}
}]
}, {
title: 'Bar',
items: [{
xtype: 'button',
text: 'Destroy!',
handler(btn) {
Ext.getCmp('myPanel').getController().destroyTab();
}
}]
}]
}]
});
Fiddle
I enhanced the answer from Matheus to meet the requirement a bit more:
not destroying the entire tab, but only the content
setting the button handler without the use of getController (please try not to use this, as it is considered bad practice by Sencha)
removed the outer panel which only added a title
Fiddle
You can also remove it using the tab bar using closeTab() which pretty much just runs a tabs.remove(tabRefOrObj);
https://docs.sencha.com/extjs/6.5.3/modern/Ext.tab.Bar.html#method-closeTab

Need help to use Controller

I'm trying to use controller in my program.Controller name is "Main" and code is given below.
refs: [
{
ref: 'navigation',
selector: 'navigation'
},
{
ref: 'ContentPanel',
selector: 'ContentPanel'
},
{
ref: 'viewport',
selector: 'viewport'
}
]
and i have a view port with following code.
Ext.define('MyApp.view.MyViewport', {
extend: 'Ext.container.Viewport',
requires: [
'MyApp.view.Header',
'MyApp.view.Navigation',
'MyApp.view.ContentPanel'
],
layout: {
type: 'border'
},
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'header',
height: 136,
region: 'north'
},
{
xtype: 'navigation',
width: 207,
region: 'west'
},
{
xtype: 'ContentPanel',
width: 431,
flex: 2,
region: 'center'
}
]
});
now my problem is i have to get an object of ContentPanel when i click on naviagation(tree panel). i tried using
var content= this.getContentPanel();
i have one more form panel add i want to add that to the controller. and i want to get the instance of the form and put it inside the content panel and display.
var form= this.getMyform();// i didnt add Myform to the controller yet because i dont know to add reference properly
content.add(form);
My main problem is that i cant instantiate the content panel and form in ItemClick event of navigation(tree panel)
thank you
A ref should start with a lower case letter. The same is valid for xtypes. ref: 'contentPanel' will define a getter getContentPanel. Since contentPanelis different from ContentPanel, I'm not sure, if in your case the getter is created or not.

ExtJs: Ext.grid.Panel: Grid refreshes automatically and becomes blank

I am using a Grid to display data on a modal window.
It has two columns, 1. Label 2. TextField
The problem I am facing is whenever I enter anything in the textfield and lose focus from that textfield (by pressing TAB or clicking somewhere else), the grid clears itself completely and I get a blank grid!
I know this has something to do with the autoSync property of the Store associated with the grid.
So I set it to false autoSync: false.
After doing this the data gets retained and works fine.
BUT when I close this modal window and re-open it with the same store data, I get a blank screen!
Following is my code:
Model
Ext.define('Ext.ux.window.visualsqlquerybuilder.SQLAttributeValueModel', {
extend: 'Ext.data.Model',
fields: [
{
name: 'attribute',
type: 'string'
},
{ name: 'attributeValue',
type: 'string'
}
]
});
Store
var attrValueStore = Ext.create('Ext.data.ArrayStore', {
autoSync: true, //tried setting it to false but got error as mentioned above
model: 'Ext.ux.window.visualsqlquerybuilder.SQLAttributeValueModel'
});
GRID
Ext.define('Ext.ux.window.visualsqlquerybuilder.SQLAttributeValueGrid', {
autoRender: true,
extend: 'Ext.grid.Panel',
alias: ['widget.attributevaluegrid'],
id: 'SQLAttributeValueGrid',
store: attrValueStore,
columnLines: true,
plugins: [Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})],
columns: [
{ /*Expression */
xtype: 'gridcolumn',
text: 'Attribute',
sortable: false,
menuDisabled: true,
flex: 0.225,
dataIndex: 'attribute'
},
{ /*Attribute Values*/
xtype: 'gridcolumn',
editor: 'textfield',
text: 'Values',
flex: 0.225,
dataIndex: 'attributeValue'
}
],
initComponent: function () {
this.callParent(arguments);
}
});
MODAL WINDOW
var attributeValueForm = Ext.create('Ext.window.Window', {
title:'Missing Attribute Values',
id: 'attributeValueForm',
height:500,
width:400,
modal:true,
renderTo: Ext.getBody(),
closeAction: 'hide',
items:[
{
xtype: 'attributevaluegrid',
border: false,
//height: 80,
region: 'center',
split: true
}
],
buttons: [
{
id: 'OKBtn',
itemId: 'OKBtn',
text: 'OK',
handler: function () {
Ext.getCmp('attributeValueForm').close();
}
},
{
text: 'Cancel',
handler: function () {
Ext.getCmp('attributeValueForm').close();
}
}
]
});
Please help. This is making me go mad!!
It would be helpful if you could provide details on how you create the Window itself, as it may be part of the problem.
One cause of this can be that you are hiding the window instead of closing it and then creating a new instance when you re-open. This will cause your DOM to have two windows instances and may not sync the data correctly in the second instance.
Some more details on how you create the actual window would help shed some light on whether this is the case.
I would probably want to jail myself after writing this.
The real issue was that I had created a similar grid for a different modal window and since I had copied the code I missed out on changing the ID of the new grid.
Both grids had the same IDs.
Changed it now and it is working fine now.
Thanks for your help!

How To Get Reference to base component in Viewport from pop up window in ExtJS 4

I'm struggling with getting references and not using Ext.getCmp(..). I understand why it is best not to use Ext.getCmp in production apps, primarily because of potential confusion around duplicated DOM id's. I've create a basic sample below that I've put some comments in that I'm hoping, if I can find answers to will help me better understand how to get references.
I'm also looking for some really good explanations, tutorials, etc on this topic. I gather that learning how to do ComponentQuery's would be best but I'm not even sure if that is the case. So without further words, here the code. Please take a look at button event in pop up window for what I'm hoping to figure out.
Ext.define('MyApp.view.MyViewport', {
extend: 'Ext.container.Viewport',
layout: {
type: 'border'
},
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'panel',
flex: 2,
region: 'center',
title: 'My Panel',
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'button',
text: 'MyButton',
listeners: {
click: {
fn: me.onButtonClick,
scope: me
}
}
}]
}],
items: [{
xtype: 'component',
html: '<b>my component</b>'
}]
}]
});
me.callParent(arguments);
},
onButtonClick: function (button, e, eOpts) {
Ext.define('MyApp.view.MyWindow', {
extend: 'Ext.window.Window',
height: 250,
width: 400,
title: 'My Window',
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'button',
text: 'Want to get link to my component in window that opened this',
listeners: {
click: {
fn: me.onButtonClick,
scope: me
}
}
}]
});
me.callParent(arguments);
},
onButtonClick: function (button, e, eOpts) {
// I would like to set the html property of the
// component in the window below
// I would like to do this efficintly
// user itemId?
// use componentquery?
// use up/down/etc.
//
// Need help with componentquery, extjs help is not helpful for me
// I need more basics I think.
this.up('panel').up('panel').down('component').html = '<i>set from button</i>';
console.log(this.up('panel').up('panel').down('component'));
}
});
var win = Ext.create('MyApp1.view.MyWindow', {});
win.show();
}
});
Windows are floating so you cant use up to get back to your viewport. Likewise, you can't use down in your viewport to find any components in windows. Your outer onButtonClick method is called in the scope of the viewport. If you save off a reference to this at that point, you can use it with down to grab your component.
onButtonClick: function() {
var viewport = this;
Ext.define('YourWindow', {
// setup everything
onButtonClick: function() {
// this may not return what you want since everything
// else inside the viewport is technically also a component
// You'd be better off adding an itemId to the component
// you wish to grab and using that in the call to down.
console.log(viewport.down('component'));
}
});
// show window
}
On a side note, I'm not sure that you want to be defining your window class on button click. Unless you can guaranty that the button will only ever be clicked once, you should define your class elsewhere and just create the window in the click handler. That complicates getting a reference to the viewport, but you could easily set it as a property on the window when you create it, or just add the onButtonClick method in the window's configuration object.

Extjs: Reuse the same grid in TabPanel

in a Extjs application I have a Grid and a Tabs line over it. Content of the Grid depends on the selected Tab.
Say tabs has Jan-Feb-Mar-... values. Clicking of the Tab I would reload grid's store
Question: is it possible to avoid duplicating of the 12 grid components in favor to have one shared instance?
Thanks
Disclaimer: searching at the sencha's forum, google, stackoverflow was not successful :(
It is, but it would require more effort than it is worth. Just create a prototype for your component, so that you can create new instances really quickly.
I haven't tried this myself, but I imagine that you could create a TabPanel with empty tabs and size the TabPanel so that only the tab strip is visible. Under that (using the appropriate layout, border, vbox, etc.) create your GridPanel and use the TabPanel's activate event to reload the grid based on the currently-active tab.
Hope the following implementation meet your needs
1. Create your custom grid and register it
2. place it tab panel
As the grid is created using xtype, it would not create 12 instances when you change tabs.
Application.PersonnelGrid = Ext.extend(Ext.grid.GridPanel, {
border:false
,initComponent:function() {
Ext.apply(this, {
store:new Ext.data.Store({...})
,columns:[{...}, {...}]
,plugins:[...]
,viewConfig:{forceFit:true}
,tbar:[...]
,bbar:[...]
});
Application.PersonnelGrid.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
,onRender:function() {
this.store.load();
Application.PersonnelGrid.superclass.onRender.apply(this, arguments);
} // eo function onRender
});
Ext.reg('personnelgrid', Application.PersonnelGrid);
var panel = new Ext.TabPanel({
items:[{
title:'Jan',
items: [{xtype:'personnelgrid'}]
}, {
title: 'Feb',
items: [{xtype:'personnelgrid'}]
}
....
{
title: 'Dec',
items: [{xtype:'personnelgrid'}]
}]
})
Since this is the only place discussed about this until now, I share what I just found.
The trick is use dockedItems in ExtJs 4 (Not sure either grid can be added into tbar in ExtJs 3)
When changing the active tab, only body will be change but not the docked item. Just set the grid height equal to the body during boxready and resize so that we can't see the body anymore.
This is the code for ExtJs 4.2 MVC that also make use of refs.
Ext.define('app.controller.Notification', {
extend: 'Ext.app.Controller',
views: ['notification.List'],
stores: ['Notification'],
models: ['Notification'],
refs: [{
ref: 'pnlNotif',
selector: 'pnlNotif'
}, {
ref: 'notifList',
selector: 'notifList'
}],
init: function () {
this.control({
'dbPnlNotif': {
added: this.pnlNotifAdded,
boxready: this.calcNotifListSize,
resize: this.calcNotifListSize,
tabchange: this.pnlNotifTabChange
}
});
},
pnlNotifAdded: function (pnlNotif) {
pnlNotif.add({ title: '1', html: '1' });
pnlNotif.add({ title: '2', html: '2' });
pnlNotif.add({ title: '3', html: '3' });
},
calcNotifListSize: function (pnlNotif) {
// calc the notification list height to make sure it use the whole body
// This way we can use only one instance of list to display for each tabs
// because the list is rendered as dockedItems
var height = pnlNotif.getHeight();
var headerHeight = pnlNotif.getDockedItems()[0].getHeight();
var tabBarHeight = pnlNotif.getDockedItems()[1].getHeight();
height = height - headerHeight - tabBarHeight;
if (this.getNotifList().getHeight() !== height) {
this.getNotifList().setHeight(height - 1);// - 1 to include border bottom
}
},
pnlNotifTabChange: function (pnlNotif, newTab) {
// do something to filter the list based on selected tab.
}
});
Ext.define('ML.view.Notification', {
extend: 'Ext.tab.Panel',
alias: ['widget.pnlNotif'],
title: 'Notification',
dockedItems: [{
xtype: 'notifList'
}]
});
Ext.define('ML.view.notification.List', {
extend: 'Ext.grid.Panel',
alias: 'widget.notifList',
dock: 'top',
store: 'Notification',
initComponent: function () {
this.columns = [
...
];
this.callParent(arguments);
}
});
Try this
var gridJanName = Ext.create('Ext.grid.Panel', {
enableColumnHide: false,
autoScroll:true,
store: storeJanNameGroup,
border:true,
stripeRows: true,
columnLines:false,
loadMask: true,
tbar:tbgridTools,
margin: '1 1 1 1',
pageSize: 100,
maxWidth:700,
features: [groupFeature],
selModel: {
mode: 'MULTI'
},
columns: [
{xtype:'rownumberer',width:50},
{dataIndex:'id', hidden:true},
//etc
]
});
var gridFebName = Ext.create('Ext.grid.Panel', {
enableColumnHide: false,
autoScroll:true,
store: storeJanNameGroup,
border:true,
stripeRows: true,
columnLines:false,
loadMask: true,
tbar:tbgridTools,
margin: '1 1 1 1',
pageSize: 100,
maxWidth:700,
features: [groupFeature],
selModel: {
mode: 'MULTI'
},
columns: [
{xtype:'rownumberer',width:50},
{dataIndex:'id', hidden:true},
//etc
]
});
//
//etc grid
//
var JanPanel = Ext.create('Ext.panel.Panel', {
title:'Jan',
bodyPadding: 5,
Width:780,
layout: {
type: 'hbox',
align: 'stretch'
},
items: [gridJanName]
});
var FebPanel = Ext.create('Ext.panel.Panel', {
title:'Feb',
bodyPadding: 5,
Width:780,
layout: {
type: 'hbox',
align: 'stretch'
}
//,items: [gridFebName]
});
var MarPanel = Ext.create('Ext.panel.Panel', {
title:'Mar',
bodyPadding: 5,
Width:780,
layout: {
type: 'hbox',
align: 'stretch'
}
//,items: [gridMarName]
});
//etc
var eachMonthstabs = Ext.create('Ext.tab.Panel', {
minTabWidth: 130,
tabWidth:150,
//Width:750,
scroll:false,
autoHeight: true,
id:'timestabs',
enableTabScroll:true,
items: [
{
xtype:JanPanel
},
{
xtype:FebPanel
},
{
xtype:MarPanel
}
///etc
]
});
For me good solution was to use a left toolbar called lbar with list of buttons and a single grid instead of tabpanel

Resources