Panel not hiding properly - sencha-touch

I have a panel whose items are a list and a panel like below
When I click on a button, I want to hide this panel. So far, I managed to do that, but this is what I get
I would like to know how to remove this grey space form the bottom of the panel.
I already this but it's not working :
this.toolsPnl.hide({type:'slide', direction:'up'});
this.doComponentLayout();
this.doLayout();
Update : Code
this.pasteBtn = new Ext.Button({
cls:'paste-copy-tools-panel',
text: 'Coller',
ui: 'normal',
handler : this.onPasteBtnTap,
scope:this
});
this.cancelBtn = new Ext.Button({
cls:'cancel-copy-tools-panel',
text: 'Annuler',
ui: 'normal',
handler: this.onCancelBtnTap,
scope:this
});
this.toolsPnl = new Ext.Panel({
layout:{type:'hbox', align:'stretch'},
height:40,
cls:'document-tools-panel',
hidden:true,
items:[this.pasteBtn,this.cancelBtn]
});
this.currentFolderPnl = new Ext.Panel({
cls:'document-current-folder-panel',
html:'/'
});
this.list = new Ext.List({
flex:1,
cls:'document-list',
id: 'document-list',
store: app.stores.Document,
itemTpl: app.templates.document
});
app.views.DocumentList.superclass.constructor.call(this, {
selectedCls : "x-item-selected",
dockedItems: [{
xtype: 'toolbar',
ui:'dark',
title: 'Documents',
items:[this.backBtn,{xtype:'spacer'},this.newBtn]
}],
layout: 'vbox',
items: [
this.currentFolderPnl,
this.list,
this.toolsPnl,
]
});

May help you with some hack. The main trick is in fixListHeight function, but for showing tools panel for the first time I have to call doComponentLayout for its container first. Don't know why this functionality doesn't work out of the box... have the feeling there is something I have missed. Nevertheless, here is the code.
new Ext.Application({
launch: function() {
// helper property
// indicates whether toolsPnl was shown already
this.first = true;
this.viewport = new Ext.TabPanel({
fullscreen: true,
layout: 'card',
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'spacer'
}, {
text: 'show',
listeners: {
tap: function (btn) {
var panel = Ext.getCmp('toolsPnl');
if (panel.isHidden()) {
panel.show({type:'slide', direction:'up'});
btn.setText('hide');
} else {
panel.hide({type:'slide', direction:'up'});
btn.setText('show');
this.fixListHeight();
}
},
scope: this
}
}]
}],
tabBar: {
layout: {
type: 'fit'
}
},
tabBarDock: 'bottom',
items: [{
title: 'Some tabs here...',
id: 'docTab',
iconCls: 'favorites',
layout: 'card',
dockedItems: [{
id: 'toolsPnl',
dock: 'bottom',
html: 'Tools panel',
style: {
'background-color': 'lightblue',
'line-height': '2em',
'text-align': 'center',
'height': '40px',
'width': '100%'
},
hidden:true,
listeners: {
show: function () {
if (this.first) {
Ext.getCmp('docTab').doComponentLayout();
this.fixListHeight();
this.first = false;
}
Ext.defer(function () {
this.fixListHeight(-1);
}, 250, this);
},
scope: this
}
}],
items : [{
xtype: 'list',
id: 'docList',
itemTpl: '{item}',
store: new Ext.data.Store({
data: [{item: 'Some data in the list...'}],
fields: ['item']
})
}]
}]
});
this.fixListHeight = function (direction) {
var panel = Ext.getCmp('toolsPnl'),
tab = Ext.getCmp('docTab'),
list = Ext.getCmp('docList'),
el,
h = list.getHeight(),
dh = panel.getHeight(),
dir = direction || 1;
el = tab.getEl().child('.x-panel-body');
el.setHeight(h + dh * dir);
el.child('.x-list').setHeight(h + dh * dir);
el.down('.x-scroller').setHeight(h + dh * dir);
};
}
});

That looks like the default sencha touch grey. A simple work around would be adding the code below to the panel
style:'background-color:White'

Related

Button Event not getting fired when put inside Tab Panel in Sencha Touch 2

I have put two buttons inside a tab Panel in Sencha Touch 2 application. The code is given below:
var btnAttendance = Ext.create('Ext.Button', {
text: 'Take Attendance',
padding: 10,
width: 200,
handler: function () {
alert('a');
}
});
var btnAddUser = Ext.create('Ext.Button', {
text: 'Add User',
padding: 10,
width: 200,
handler: function () {
alert('a');
}
});
var buttonContainer = Ext.create('Ext.Panel', {
fullscreen: true,
title: 'Home',
defaults: {
margin: 5
},
layout: {
type: 'vbox',
align: 'center'
},
padding: 10,
items: [
btnAttendance,
btnAddUser
]
});
Ext.application({
requires: [
'Ext.tab.Panel'
],
launch: function () {
Ext.Viewport.add({
xtype: 'tabpanel',
items: [
buttonContainer,
{
title: 'Present',
items: {
html: '2',
centered: true
},
cls: 'present'
},
{
title: 'Absent',
items: {
html: '3',
centered: true
},
cls: 'absent'
}
]
});
}
});
I have tried modifying the handler function as:
handler: function (button, event)
But this also doesn't work.
Thanks,
Nitin
You need to put all your code inside Ext.application... and launch:function(){...}.... Your code is working fine. See demonstration here.
But then again, buttonContainer is not really being added to any tab panel. If you change the tab, you can see buttonContainer is gone once to change the tabs. If you want to add it inside any tab do this-
First -
Set fullscreen:false to you buttonContainer panel.
var buttonContainer = Ext.create('Ext.Panel', {
fullscreen: false,
....... //rest of the code.
And suppose you want to add those buttons in Present tab. You can do this with following--
Ext.Viewport.add({
xtype: 'tabpanel',
items: [
{
title: 'Present',
cls: 'present',
items: [
{
html: '2',
centered: true
},
buttonContainer
]
},
{
title: 'Absent',
items: {
html: '3',
centered: true
},
cls: 'absent'
}
]
});
Here, buttonContainer is added as an item inside present tab only. You can switch the tabs and can see buttons there with correct event handler.
See this demo here
If you follow MVC architecture, your job becomes much easier writing application having multiple views and user interactions. ST is all about MVC and it's good practice to follow it.

Re-sizing form content to fit browser window - Using Card Layout

I need the tab-panels to fit browser window size. I have used card layout, and it is not re-sizing to fit the browser window. I think i'm missing some properties in my viewPort.
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'card',
items: [
{
xtype: 'panel',
items: { xtype: 'tabP1' }
},
{
xtype: 'panel',
items: { xtype:'tabP2' }
}
,
{
xtype: 'panel',
items: { xtype:'tabP3' }
}
]
});
},
2.) One of my tabpanels; I am using absolute layout. I am using this layout because it's easy to set form components where i ever i desire it to be. Therefore, i would like a solution that works with the same layout.
Ext.define('MyApp.view.MyForm', {
extend: 'Ext.form.Panel',
alias:'widget.tabP1',
// height: 250,
// width: 726,
layout: {
type: 'absolute'
},
bodyPadding: 10,
title: 'My Form',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'gridpanel',
title: 'My Grid Panel',
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'string',
text: 'String'
},
{
xtype: 'numbercolumn',
dataIndex: 'number',
text: 'Number'
},
{
xtype: 'datecolumn',
dataIndex: 'date',
text: 'Date'
},
{
xtype: 'booleancolumn',
dataIndex: 'bool',
text: 'Boolean'
}
],
viewConfig: {
}
}
]
});
me.callParent(arguments);
}
});
UPDATE 2
UPDATE 2
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'card',
items: [
{
xtype: 'tabP1'
},
{
xtype:'tabP2'
}
,
{
xtype:'tabP3'
}
]
});
},
onSuccess: function() {
this.getViewport().getLayout().setActiveItem(1);
},
I get an error when i use your code, saying that this.getViewport().getLayout().setActiveItem(1) is not a function. I think this is because i used border layout. How can i resolve this ?
Your problem is "over-nesting" Why are you putting 'tabPFoo' inside a panel with no layout? They are at best, redundant, also causing the layout system to spend more cycles when it's not needed.
Ext.require('*');
Ext.onReady(function(){
var vp = new Ext.container.Viewport({
layout: 'card',
items: [{
xtype: 'grid',
store: {
fields: ['name'],
data: [{
name: 'Name 1'
}]
},
columns: [{
flex: 1,
dataIndex: 'name',
text: 'Name'
}],
listeners: {
itemclick: function(view){
var grid = view.ownerCt,
next = grid.nextSibling();
vp.getLayout().setActiveItem(next);
}
}
}, {
xtype: 'grid',
store: {
fields: ['name'],
data: [{
name: 'Name 2'
}]
},
columns: [{
flex: 1,
dataIndex: 'name',
text: 'Name'
}],
listeners: {
itemclick: function(view){
var grid = view.ownerCt,
next = grid.nextSibling();
vp.getLayout().setActiveItem(next);
}
}
}, {
xtype: 'grid',
store: {
fields: ['name'],
data: [{
name: 'Name 3'
}]
},
columns: [{
flex: 1,
dataIndex: 'name',
text: 'Name'
}],
listeners: {
itemclick: function(view){
var grid = view.ownerCt,
next = grid.previousSibling().previousSibling();
vp.getLayout().setActiveItem(next);
}
}
}]
});
});
Obviously that's not MVC style, but that's the structure the layout should take.

extjs4 on load listener not being invoked

Pardon me if this doesnt make much sense as i am still trying to understand certain aspects of extjs.. I m trying to to dynamically fetch a menu when a page is loaded. But seems like my MenuFetch() function does not get called.
Here is my code and here is the page:
http://srikanthrajan.com/test/
Center = Ext.create('Ext.panel.Panel', {
title: "User Admin",
region: 'center',
layout: 'fit',
dockedItems: {
xtype: 'panel',
dock: 'left',
title: 'Main Menu',
width: 160,
layout: 'anchor',
collapsible: true,
collapseDirection: 'left',
items: [
{
defaults: {
width: 140,
layout: 'vbox',
xtype: 'linkbutton'
},
id: 'MainMenu',
xtype: 'panel',
listeners: {
load: function(menu) {
menu.show()
MenuFetch()
this.load()
}
}
}
]
}
});
//function that uses ajax to fetch menu items and add them
function MenuFetch() {
Ext.getBody().mask('loading')
var menu = Ext.ComponentManager.get('MainMenu')
menu.removeAll(true)
Ext.Ajax.request({
url: 'PanelScripts/getMenu.php',
method: 'POST',
callback: function(opt, success, response) {
var text = response.responseText;
var obj = Ext.JSON.decode(text);
if (success && !obj.failure) {
menu.add(obj)
Ext.getBody().unmask()
menu.show()
} else {
obj = Ext.JSON.decode(response.responseText);
Ext.Msg.alert('Error',obj.Error)
Ext.getBody().unmask()
}
}
});
}
PS: I am not sure if I even need the load listener. Basically I need to call the menuftech function which fetches the menu items in a json format.
Use the Ext.ComponentLoader (or loader config property) to load remote content for the menu. It seems like the xtype should be 'menu' instead of 'panel' based on what you are trying to accomplish. Try something like this:
var adminPanel = Ext.create('Ext.panel.Panel', {
title: 'User Admin',
region: 'center',
layout: 'fit',
dockedItems: {
xtype: 'panel',
dock: 'left',
title: 'Main Menu',
width: 160,
layout: 'anchor',
renderTo: Ext.getBody(),
items:[
{
xtype: 'menu',
width: 100,
loader: {
url: 'foo.bar',
autoLoad: true,
callback: function(loader, success, response, options) {
var menu = adminPanel.down('menu');
if (success) {
menu.add(response.items);
menu.show();
}
},
scope: this
}
}
]
}
});

Extjs 4 portlet on load collapsed not working properly

I am using ExtJS portal code in my application
I want to make portlet in collapsed state at the time of loading the page. So I have done something like
items: [{
id: 'portlet-1',
title: 'Grid Portlet Texsds',
tools: this.getTools(),
height:200,
**collapsed:true,**
autoScroll :true,
items: Ext.create('Ext.app.GridPortlet'),
listeners: {
'close': Ext.bind(this.onPortletClose, this),
'endDrag': Ext.bind(this.onPortletDrag, this),
'resize' :Ext.bind(this.onPortletResize, this)
}
}
I have made collapsed property to true. But because of this when I am trying to expand the portlet [after page load] I can see blank Grid.Plz. refer the attached image.
What is the problem ? do I need to do refresh or something ? because when I set collapsed to false I can see the grid.
Please suggest what is missing here.
This is a code for the getTools: function(){
{
type: 'Minimize',
handler: function(e,target,panelHeader,tool){
//panelHeader.ownerCt.toggleCollapse();
if (panelHeader.ownerCt.collapsed)
{
panelHeader.ownerCt.expand();
}
else {
panelHeader.ownerCt.collapse();
}
}
}
for the first time when the portlet get load it is in collapsed state, Now when I click on cross icon not [the "^" for expand icons ] I can see the Blank grid.
Hope this time I am able to explain well.
I took the Ext JS 4 example portal app and added your code (without the asterisks) to portlet-1. It is properly collapsed on load and expands to show the grid.
I don't think there is anything wrong with the code you've posted. Perhaps you've changed the layout or layout properties of the surrounding container and that is affecting your portlet.
Here is my complete portal.js:
Ext.define('Ext.app.Portal', {
extend: 'Ext.container.Viewport',
//requires: [ 'Ext.diag.layout.ContextItem', 'Ext.diag.layout.Context' ],
uses: ['Ext.app.PortalPanel', 'Ext.app.PortalColumn', 'Ext.app.GridPortlet', 'Ext.app.ChartPortlet'],
getTools: function(){
return [{
xtype: 'tool',
type: 'gear',
handler: function(e, target, panelHeader, tool){
var portlet = panelHeader.ownerCt;
portlet.setLoading('Loading...');
Ext.defer(function() {
portlet.setLoading(false);
}, 2000);
}
}];
},
initComponent: function(){
var content = '<div class="portlet-content">'+Ext.example.shortBogusMarkup+'</div>';
Ext.apply(this, {
id: 'app-viewport',
layout: {
type: 'border',
padding: '0 5 5 5' // pad the layout from the window edges
},
items: [{
id: 'app-header',
xtype: 'box',
region: 'north',
height: 40,
html: 'Ext Portal'
},{
xtype: 'container',
region: 'center',
layout: 'border',
items: [{
id: 'app-options',
title: 'Options',
region: 'west',
animCollapse: true,
width: 200,
minWidth: 150,
maxWidth: 400,
split: true,
collapsible: true,
layout:{
type: 'accordion',
animate: true
},
items: [{
html: content,
title:'Navigation',
autoScroll: true,
border: false,
iconCls: 'nav'
},{
title:'Settings',
html: content,
border: false,
autoScroll: true,
iconCls: 'settings'
}]
},{
id: 'app-portal',
xtype: 'portalpanel',
region: 'center',
items: [{
id: 'col-1',
items: [{
id: 'portlet-1',
title: 'Grid Portlet',
tools: this.getTools(),
collapsed: true,
height: 200,
autoscroll: true,
items: Ext.create('Ext.app.GridPortlet'),
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
},{
id: 'portlet-2',
title: 'Portlet 2',
tools: this.getTools(),
html: content,
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}]
},{
id: 'col-2',
items: [{
id: 'portlet-3',
title: 'Portlet 3',
tools: this.getTools(),
html: '<div class="portlet-content">'+Ext.example.bogusMarkup+'</div>',
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}]
},{
id: 'col-3',
items: [{
id: 'portlet-4',
title: 'Stock Portlet',
tools: this.getTools(),
items: Ext.create('Ext.app.ChartPortlet'),
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}]
}]
}]
}]
});
this.callParent(arguments);
},
onPortletClose: function(portlet) {
this.showMsg('"' + portlet.title + '" was removed');
},
showMsg: function(msg) {
var el = Ext.get('app-msg'),
msgId = Ext.id();
this.msgId = msgId;
el.update(msg).show();
Ext.defer(this.clearMsg, 3000, this, [msgId]);
},
clearMsg: function(msgId) {
if (msgId === this.msgId) {
Ext.get('app-msg').hide();
}
}
});

Changing the Detail Container in a NestedList?

In a small program that I have, I'm trying to have custom containers for every leaf node of my Nested List.
Here are a couple arbitrary example containers that I'm trying to test with:
Ext.define('DetailContainer1', {
extend: 'Ext.Container',
xtype: 'detail-container1',
layout: {
type: 'vbox'
},
height: 300,
style: 'background-color: #a9a9a9;',
// flex: 1,
items: [{
html: 'Detail Container1'
}]
});
Ext.define('DetailContainer2', {
extend: 'Ext.Container',
xtype: 'detail-container2',
layout: {
type: 'vbox'
},
height: 300,
style: 'background-color: #c9c9c9;',
// flex: 1,
items: [{
html: 'Detail Container2',
flex: 1
}, {
xtype: 'button',
text: 'Hit me!',
flex: 1
}]
});
How can I switch in the new containers when the user clicks on the leaf node?
This action should happen in onLeafItemTap(). Btw the initial container (#2) isn't showing at the moment. Is this a layout issue?
Here's some idea of what the screen should look like:
Complete source:
Ext.Loader.setConfig({
enabled: true
});
Ext.define('DetailContainer1', {
extend: 'Ext.Container',
xtype: 'detail-container1',
layout: {
type: 'vbox'
},
height: 300,
style: 'background-color: #a9a9a9;',
// flex: 1,
items: [{
html: 'Detail Container1'
}]
});
Ext.define('DetailContainer2', {
extend: 'Ext.Container',
xtype: 'detail-container2',
layout: {
type: 'vbox'
},
height: 300,
style: 'background-color: #c9c9c9;',
// flex: 1,
items: [{
html: 'Detail Container2',
flex: 1
}, {
xtype: 'button',
text: 'Hit me!',
flex: 1
}]
});
Ext.define('ListItem', {
extend: 'Ext.data.Model',
config: {
fields: ['text']
}
});
Ext.define('Sencha.view.MainView', {
extend: 'Ext.Container',
xtype: 'mainview',
layout: {
type: 'hbox'
},
initialize: function() {
this.treeStore = Ext.create('Ext.data.TreeStore', {
model: 'ListItem',
defaultRootProperty: 'items',
root: {
items: [{
text: 'Containers',
items: [{
text: 'Detail #1',
leaf: true
}, {
text: 'Detail #2',
leaf: true
}]
}]
}
});
this.detailContainer = Ext.create("DetailContainer2", {});
this.nestedList = Ext.create('Ext.NestedList', {
docked: 'left',
width: 300,
flex: 1,
store: this.treeStore,
detailCard: true,
detailContainer: this.detailContainer,
listeners: {
scope: this,
leafitemtap: this.onLeafItemTap
}
});
this.setItems([this.detailContainer, this.nestedList]);
},
onLeafItemTap: function(nestedList, list, index, node, record, e) {
var detailCard = nestedList.getDetailCard();
// nestedList.setDetailContainer(Ext.create("DetailContainer1", {}))
// detailCard.setHtml(record.get('text') + "...");
}
});
Ext.application({
launch: function() {
var container = Ext.create("Ext.Container", {
layout: {
type: 'hbox'
},
items: [{
xtype: 'mainview'
}]
});
Ext.Viewport.add(container);
}
});
Finally I've figured out the proper way to solve your problem.
Some explanations:
If you want to display "customized detailContainer" at the right side of your hbox, it's quite obvious that you should disable detailCard config for your Ext.NestedList because it's designed to display inline (i.e. take place of your Ext.NestedList).
When using Ext.define, everything should be included in config (except extend, xtype, alias, id, so in this case, layout has to be put in config).
flex should be defined in config as well.
At leafitemtap event, simply update your detailContainer config and remove/add it again as it would not be updated dynamically.
Please take a look at modified code snippet below, it works perfectly for me.
Ext.Loader.setConfig({ enabled: true });
Ext.define('DetailContainer1', {
extend: 'Ext.Container',
xtype: 'detail-container1',
config: {
flex: 1,
layout: {
type: 'vbox'
},
style: 'background-color: #a9a9a9;',
items: [
{html: 'Detail Container1'}
]
}
});
Ext.define('DetailContainer2', {
extend: 'Ext.Container',
xtype: 'detail-container2',
config: {
flex: 1,
layout: {
type: 'vbox'
},
style: 'background-color: #c9c9c9;',
items: [
{html: 'Detail Container2', flex: 1},
{xtype: 'button', text: 'Hit me!', flex: 1}
]
}
});
Ext.define('ListItem', {
extend: 'Ext.data.Model',
config: {
fields: ['text']
}
});
Ext.define('Sencha.view.MainView', {
extend: 'Ext.Container',
xtype: 'mainview',
id: 'mainview',
config: {
layout: {
type: 'hbox'
},
},
initialize: function() {
this.treeStore = Ext.create('Ext.data.TreeStore', {
model: 'ListItem',
defaultRootProperty: 'items',
root: {
items: [
{
text: 'Containers',
items: [
{ text: 'Detail #1', leaf: true },
{ text: 'Detail #2', leaf: true }
]
}
]
}
});
this.detailContainer = Ext.create("DetailContainer2");
this.nestedList = Ext.create('Ext.NestedList', {
flex: 1,
store: this.treeStore,
listeners: {
scope: this,
leafitemtap: this.onLeafItemTap
}
});
this.setItems([this.nestedList, this.detailContainer]);
},
onLeafItemTap: function(nestedList, list, index, node, record, e) {
mainview = Ext.getCmp('mainview');
if (index==0) {
mainview.detailContainer = Ext.create("DetailContainer1");
} else {
mainview.detailContainer = Ext.create("DetailContainer2");
}
mainview.removeAt(1);
mainview.add(mainview.detailContainer);
}
});
Ext.application({
launch: function() {
Ext.Viewport.add(
Ext.create("Ext.Container", {
layout: {
type: 'card'
},
items: [
{ xtype : 'mainview'}
]
}));
}
});