how to show different panel on the center of the window based on button click event extjs4 - extjs4

forum member
I am having some problems in displaying different panel on the center area of border layout window.
Consider I am having border layout window with east side containing different button, which on click will display the grid on the center of the layout window.
my window is shown below with east containing buttons and center is empty.
my updated controller code is given below
Ext.define('rms.controller.companymgt.CompanyMgtController',{
extend: 'Ext.app.Controller',
stores:['companyStore'],
models:['companyModel'],
views: [
'companymgt.companyMain',
'companymgt.companyView',
'companymgt.companyDetail',
'companymgt.companyAdd',
'companymgt.fileUpload'
,'companymgt.departmentDetail',
'companymgt.designationDetail',
'companymgt.groupDetail'
],
refs: [{
ref: 'companyMain',
autoCreate: true,
selector: 'companymain',
xtype: 'companymain'
},{
ref: 'companyAdd',
autoCreate: true,
selector: 'companyadd',
xtype: 'companyadd'
},{
ref: 'fileUpload',
autoCreate: true,
selector: 'fileupload',
xtype: 'fileupload'
},{
ref: 'departmentDetail',
autoCreate: true,
selector: '#departmentdetail',
xtype: 'departmentdetail'
},{
ref: 'designationDetail',
autoCreate: true,
selector: '#designationdetail',
xtype: 'designationdetail'
},{
ref: 'groupDetail',
autoCreate: true,
selector: '#groupdetail',
xtype: 'groupdetail'
},{
ref: 'companyDetail',
autCreate: true,
selector: '#companydetail',
xtype: 'companydetail'
}],
init: function() {
this.control({
'#companyview button[action=company-view]': {
click: this.createCompanyview
},
'#companyview button[action=department-view]': {
click: this.createDepartmentview
},
'#companyview button[action=designation-view]': {
click: this.createDesignationview
},
'#companyview button[action=group-view]': {
click: this.createGroupview
},
'#companyview button[action=file-view]': {
click: this.createFilemgtview
},
'#companydetailtoolbar #mnuDept': {
click: this.createDepartmentnew
},
'#companydetailtoolbar #mnuExcel': {
click: this.exportExcel
},
'#companydetailtoolbar #mnuCSV': {
click: this.exportCSV
}
});
},
createCompanyview: function(btn) {
alert('company view clicked');
},
createDepartmentview: function(btn) {
alert('department view clicked');
var departmentCard = this.getDepartmentDetail();
var mainComp = this.getCompanyMain();
mainComp.getLayout().setActiveItem('departmentCard');
},
createDesignationview: function(btn) {
alert('designation view clicked');
},
createGroupview: function(btn) {
alert('group view clicked');
},
createFilemgtview: function(btn) {
alert('FILE MGT WINDOW');
this.getFileUpload().show();
},
createDepartmentnew: function(obj) {
this.getCompanyAdd().show();
}
});
my main view code is given below
Ext.define('rms.view.companymgt.companyMain', {
extend: 'rms.model.desktopmgt.Module',
alias: 'widget.companymain',
requires: ['rms.view.companymgt.companyView','rms.view.companymgt.companyDetail'],
id: 'companymain',
init: function() {
this.launcher = {
text: 'Company Management System',
iconCls: 'project-mini-icon',
handler: this.createWindow,
scope: this
};
},
createWindow: function() {
var desktop = this.app.getDesktop();
var win = desktop.getWindow('companymgt-win');
if(!win){
win = desktop.createWindow({
id: 'companymgt-win',
title: 'Company Management System',
height: 566,
width: 900,
layout: 'border',
constrain: true,
modal: true,
closeAction: 'destroy',
items: [{
region: 'west',
collapsible: true,
//html: 'MAIN VIEW',
xtype: 'companyview',
flext:1
},{
region: 'center',
collapsible: true,
//html: 'DETAIL VIEW',
xtype: 'companydetail',
flex:3
}]
});
}
win.show();
return win.setPosition(100,100);
}
});
when the company button is clicked I get the alert window.
But based on the button click I want to open different detail view to the center layout of the window.
Please suggest me some solution, so I can view different window on the border layout of the window as shown above.

I would go with a card layout. The easiest thing would be to give each component an itemId. Then in your controller you would have:
, refs: [
{
ref: 'mainCardComponent'
, selector: '#mainCardComponent'
},
{
ref: 'companyCard'
, selector: '#companyCard'
},
{
ref: 'departmentCard'
, selector: '#departmentCard'
}...
Then you can reference using get... within the scope of your controller like:
var companyCard = this.getCompanyCard();
To swap out the cards, you would do something like:
var mainComp = this.getMainCardComponent();
mainComp.getLayout().setActiveItem('companyCard');

You have two options:
Make center piece a container and remove old/add new stuff to it when needed.
If you have limited number of content pages make center piece layout 'card' and create all pages at once. Only one will be visible. You can change visibility when user click certain button.

Related

Destroy method in form panel

I am capturing geoposition using Cordova API and then on success, I render the current location on a Google map.
When I first do a get_position using I render a form as follows:
var geo_panel = new Ext.form.Panel({
useCurrentLocation: true,
fullscreen: true,
layout: 'fit',
items: obj
});
Where obj is a toolbar defined as
toolbar = Ext.create('Ext.Toolbar', {
docked: 'top',
alias : 'widget.geolocationToolbar',
ui: 'light',
defaults: {
iconMask: true
},
items: [
{
xtype: 'button',
ui: 'back',
text: 'Back',
// destroy form.Panel overlay and return to tree store view
handler: function() {
geo_panel.destroy();
}
},
{
xtype: 'button',
itemId: 'stopWatch',
text: 'StopWatch',
iconCls: 'arrow_right',
iconMask: true,
handler: function() {
EvaluateIt.utils.UtilityService.clear_watch();
}
},
{
xtype: 'selectfield',
itemId: 'accuracy',
autoSelect: false,
placeHolder: 'accuracy',
options: [
{text: ''},
{text: 'high', value: 5},
{text: 'med high', value: 10},
{text: 'medium', value: 15},
{text: 'med low', value: 20},
{text: 'low', value: 66}
],
listeners: {
change: function(field, value) {
if (value instanceof Ext.data.Model) {
value = value.get(field.getValueField());
}
console.log(value);
// set accuracy as config variable
EvaluateIt.config.accuracy = value;
}
}
},
{
iconCls: 'home',
handler: function() {
google_map.getMap().panTo(position);
}
}
]
});
This renders just fine in my form panel.
My onSuccess method then passes an argument to add a google_map to the geo_panel form panel.
I have tried geo_panel.add(toolbar, google_map), which works, but I then get an issue of when I hit the "Back" button in the toolbar above:
{
xtype: 'button',
ui: 'back',
text: 'Back',
// destroy form.Panel overlay and return to tree store view
handler: function() {
geo_panel.destroy();
}
},
I have to click it twice: the first time destroys the google_map and then the second destroys the toolbar. This is a very undesirable behavior. I've tried destroying each of the items in the geo_panel, but that does other weird things. This is acting like there are multiple instances of geo_panel. Any ideas?
I figured it out: I was creating two instances of my geo_panel. I refactored the code and everything now works as desired.

Constant button linking to a page throughout the app

I have a button at the top right of every page that I want to link to a certain page within my application. Is there a way to give each instance of this button the same behaviour? and if so where would the code sit so that it affects every page? Many thanks in advance.
View:
items: [
{
title: '<span class="logo"></span>',
xtype: 'titlebar',
docked: 'top',
items: [
{
xtype: 'button',
align: 'right',
iconAlign: 'right',
id: 'buytickets',
text: 'Buy Tickets'
}
]
}
]
Controller (specific to one page):
config: {
refs: {
main: 'ListNav'
},
control: {
"button#buytickets": {
tap: 'buytickets'
}
}
},
buytickets: function(button, e, eOpts) {
this.getMain().push({
xtype: 'buyticketspanel'
});
},
You could just put the button at the top of your Viewport, in the app.js file:
Ext.application({
name: 'MyApp',
requires: [],
views: [/*Views*/],
controllers: [/*Controllers*/],
viewport: {
layout: 'vbox'
},
launch: function() {
var me = this;
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
Ext.Viewport.add([
{
title: '<span class="logo"/>',
xtype: 'titlebar',
docked: 'top',
items: [
{
xtype: 'button',
align: 'right',
iconAlign: 'right',
id: 'buytickets',
text: 'Buy Tickets',
handler: me.doBuyTickets
}
]
},
Ext.create('MyApp.view.Main', {flex: 1})
]);
},
doBuyTickets: function() {
//do stuff
}
});
****EDIT****:
However, you won't be able to re-purpose that bar as the title bar for a NestedView. If you need to have that, then you might be best served with a utils file that has a method to add a button to a toolbar, and just reuse that in the init function of any NestedView components.
Utils.js:
Ext.define("MyApp.util.Utils", {
singleton: true,
addBuyButton: function(toolbar)
{
toolbar.add({
text: 'Buy Tickets',
align: 'right',
handler: function() {
//do stuff
}
});
}
});
Controller:
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
config: {
refs: {
nestedList: 'nestedlist'
},
control: {
app-page: {
initialize: 'initAppPage'
}
}
},
initAppPage: function()
{
MyApp.utils.addBuyButton(this.getNestedList().getNavigationBar());
}
});

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.

Listener to Tab Item Click in Sencha

In my application, I'm using a tab panel with 5 items in it. Each item holds around 6 panels added in card layout. When I'm at the last panel inside a tab item, I need to get back to the initial panel by clicking on the bottom tab panel (somewhat similar to a normal tab view controller in iOS). I have came across some solutions I found here, but it seems to work only when I switch between the tabs. In fact I want to listen to the click event on the same tab icon. How can I do this?
I have worked on your problem. I think this is exactly what you want. Hope this helps. If not so, please leave a comment.
1). View (MyTabPanel1.js)
Ext.define('MyApp.view.MyTabPanel1', {
extend: 'Ext.tab.Panel',
config: {
scrollable: 'vertical',
items:
[
{
xtype: 'panel',
id:'cardpanel1',
title: 'Tab1',
layout: 'card',
items: [
{
html: "First Item",
items:
[
{
xtype: 'button',
text: 'Forward',
handler: function() {
Ext.getCmp('cardpanel1').setActiveItem(1);
console.log('Going to Second Item');
}
}
]
},
{
html: "Second Item",
items:
[
{
xtype: 'button',
ui: 'confirm',
text: 'Go back',
handler: function() {
Ext.getCmp('cardpanel1').setActiveItem(0);
console.log('Going to First Item');
}
}
]
}
]
},
{
xtype: 'panel',
title: 'Tab2',
scrollable: true,
items: [
{
xtype: 'button',
margin: 10,
ui: 'action',
text: 'Tab2'
}
]
},
{
xtype: 'panel',
title: 'Tab3',
scrollable: true,
items: [
{
xtype: 'button',
margin: 10,
ui: 'action',
text: 'Tab3'
}
]
}
]
}
});
2). Controller (MainController.js)
Ext.define('MyApp.controller.MainController', {
extend: 'Ext.app.Controller',
config: {
control: {
"tabpanel #ext-tab-1":{ //ext-tab-1 is the id for the 1st tab generated by Sencha
tap: 'ontap'
}
}
},
ontap: function (){
console.log('inside controller');
Ext.getCmp('cardpanel1').setActiveItem(0);
}
});
I would give a much simpler solution
This is my view called Viewport which is a TabPanel:
Ext.define('Sencha.view.iphone.Viewport',{
extend: 'Ext.TabPanel',
xtype: 'newviewport',
alias: 'widget.newTabPanel',
Now in my controller file:
Ext.define('Sencha.controller.iphone.main', {
extend: 'Ext.app.Controller',
config:
{
refs: {
theMainTabPanelTabbarTab: 'newTabPanel > tabbar > tab', //this the tab of the tabpanel, if we listen to it that way we will know of tab panel tap.
},
control: {
theMainTabPanelTabbarTab:{
tap: 'onTapMainTabPanel'
}
}
This is a working code and works fine. Hopefully this will help you.

Add (right) Button to Sencha Navigation View

I want to dynamically add a (right aligned) button to the active navigation view depending on view Im showing. Is there any proper way to do it? I found many half good examples online, but didnt get them to work. Here is what I tried:
Ext.define('Sencha.view.user.Login', {
extend:'Ext.navigation.View',
//fullscreen: true,
xtype: 'loginview',
requires:[
'Ext.form.FieldSet',
'Ext.field.Email',
'Ext.field.Password'
],
config: {
title: 'Log in',
iconCls: 'use',
cls: 'kidsbackground',
scrollable: false,
navigationBar: {
items: [
]
},
items:[
{
xtype: 'loginform'
}
]
},
addRightButton:function(button){
var navigationBar = this.config.navigationBar;
console.log("navigationBar: "+navigationBar);
var rightButton = Ext.Button.create({
xtype: 'button',
ui: 'action',
iconCls: 'action',
iconMask: true,
align: 'right' });
console.log("rightButton: "+rightButton);
//navigationBar.addItem(rightButton);
var oNavigationbar = {
docked: 'top',
backButton : {
margin: 7,
docked: "left",
ui : 'back'
},
items: [
Ext.create("Ext.Button", {
text: "Button1"
}),
Ext.create("Ext.Button", {
text: "Button2",
align: "right"
})
]
};
this.setNavigationBar(oNavigationbar);
/*this.setNavigationBar({
items: [
{
id: 'rightButton',
xtype: 'button',
text: 'yes!'
//placeHolder: 'Search...',
//align: 'right'
}
]
});*/
console.log("wow, no crash, really ?");
}
});
When I run the above code I get strange errors, one of this is this (see attachment):
You can try this code (in Chrome Developer Tools' console) on the Sencha Touch 2 Navigation View example :
Ext.ComponentQuery.query('navigationview')[0].getNavigationBar().add({
xtype:'button',
text:'Right',
align:'right'
});
It basically get the navigationview, then the navigation bar of this view and finally add the button to it.
This is the proper way to add a button to the navigation bar.
Hope this helps
different way
var navigationView = Ext.create('Ext.NavigationView',
{
useTitleForBackButtonText: false,
scrollable: false,
layout:
{
type: 'card',
animation: null
},
navigationBar:
{
items:
[
{
xtype: 'togglefield',
name: 'smsmode',
align: 'right',
value: 0,
disabled: true
},
{
text: '',
iconCls: 'delete',
align: 'right',
ui: 'back',
listeners:
{
tap: function()
{
navigator.app.exitApp();
}
}
}
]
}
});