switching between views in sencha touch - extjs

I have the following view code in sencha touch 2
Ext.define('WL.view.Categories', {
extend: 'Ext.Container',
requires: [
'Ext.SegmentedButton',
'WL.view.movie.List',
'Ext.form.Panel',
'Ext.plugin.ListPaging',
'Ext.TitleBar',
'WL.view.movie.SortBar',
'WL.view.movie.SearchBar'
],
xtype: 'categories',
config: {
layout: {
type: 'card',
animation: {
type: 'fade'
}
},
items: [
{
docked: 'top',
xtype: 'toolbar',
cls: 'small withBg',
title: 'Merchants',
items: [
/* {
xtype: 'segmentedbutton',
allowDepress: false,
items: [
/*
{
cls: 'movies',
iconCls: 'movies',
pressed: true
},
{
xtype: 'button',
cls: 'friends',
iconCls: 'friends'
}
]
},
*/
{ xtype: 'spacer' },
{
xtype: 'button',
cls: 'searchBtn',
iconCls: 'search',
align: 'right'
},
{
xtype: 'button',
cls: 'backBtn',
id: 'movieBackButton',
align: 'left'
}
/*
{
xtype: 'component',
cls: 'fbProfilePic',
id: 'fbProfilePic',
tpl: '<img src="https://graph.facebook.com/{profileId}/picture?type=square" />' // the img source can be later changed
}
*/
]
},
{
xtype:'list',
store: 'Merchants',
plugins: [
{ xclass: 'Ext.plugin.ListPaging' }
],
itemCls: 'expandedMovie',
itemHeight:114,
items: [
{ xtype: 'movieSortBar' , docked:'top'},
{ xtype: 'movieSearchBar' , docked:'top' , hidden:true},
{
xtype: 'container',
cls: 'promo',
itemId:'promo-container',
docked:'bottom',
html: '<span class="logo"></span>Brought to you by Sencha Touch 2.1 <button>Learn More</button>'
}
],
loadingText: null,
listeners: {
order: 'before',
select: function() {
return false;
},
itemtap: function(dataview, index, target, record, evt) {
var el = Ext.get(evt.target),
fireEvent;
if (el.dom.nodeName == 'B') el = el.parent();
WL.currentMovie = record;
if (el.hasCls('seen')) {
fireEvent = el.hasCls('selected') ? 'unSeen' : 'seen';
el.toggleCls('selected');
} else if (el.hasCls('want')) {
fireEvent = el.hasCls('selected') ? 'unWantToSee' : 'wantToSee';
el.toggleCls('selected');
} else if (el.hasCls('thumb') && el.hasCls('up')) {
fireEvent = el.hasCls('selected') ? 'unLike' : 'like';
el.toggleCls('selected');
} else if (el.hasCls('thumb') && el.hasCls('down')) {
fireEvent = el.hasCls('selected') ? 'unDislike' : 'dislike';
el.toggleCls('selected');
} else {
fireEvent = 'tapMovie';
}
if (fireEvent) {
this.fireEvent(fireEvent, record, el);
}
}
},
itemTpl: Ext.create('Ext.XTemplate',
'<div class="moreArrow"></div>',
'<div class="img"><img src="http://localhost/WL2/assets/rest/{image}" /></div>',
'<div class="meta">',
'<h3>{merchName}</h3>',
'<div class="actions">',
//'<div class="rating"><span>{% if (values.criticRating >= 0) { %}{criticRating}%{% } else { %}?{% } %}</span></div>',
'<button class="seen{[values.seen ? " selected" : ""]}">{action}</button>',
'{% if (values.seen) { %}',
'<button class="thumb up{[values.like ? " selected" : ""]}"><b></b></button>',
'<button class="thumb down{[values.dislike ? " selected" : ""]}"><b></b></button>',
'{% } else { %}',
'<button class="want{[values.wantToSee ? " selected" : ""]}">Want to Go There</button>',
'{% } %}',
'</div>',
'</div>'
)
} // end of the categories list
]
},
initialize: function() {
this.callParent();
// Enable the Tap event on the profile picture in the toolbar, so we can show a logout button
var profilePic = Ext.getCmp('fbProfilePic');
if (profilePic) {
profilePic.element.on('tap', function(e) {
profilePic.fireEvent('tap', profilePic, e);
});
}
}
});
I have defined xtype to my view, so I can reference it in my controller code
this is my controller code
Ext.define('WL.controller.Categories', {
extend: 'Ext.app.Controller',
config: {
refs: {
categories: 'categories',
List: 'list'
},
control: {
list: {
tapMovie: 'onMovieTap' // the function that will be created when a movie is tapped
}
}
},
slideLeftTransition: { type: 'slide', direction: 'left' },
slideRightTransition: { type: 'slide', direction: 'right' },
onMovieTap: function () {
Ext.Viewport.animateActiveItem(this.getCategories(),this.slideRightTransition);
}
});
my main problem is that the get function getCategories() in the controller doesn't work so I can navigate to my view with slide right effect, I think that my problem is in definin the xtype, can you give me a clue on defining the correct xtype, giving that I tried using alias:widget.categories but it didnt work as well.

Your config should look like this:
config: {
refs : {
categories : {
autoCreate: true,
selector: '#categories_itemId',
xtype: 'categories'
},
List : {
// do the same thing for 'List'
}
},
control: {
...
},
...
},
...
Notice that the selector is the itemIdof your view so give your categories view an itemId (you can see I just made one up).

Related

Routing Extjs deeper navigation

I'm writing a Extjs app in the 6.2.0 version, I’ve got a routing situation.
My problem is when we enter on the NavigateDeep if I enter the Url ok it catches but it doesn’t render.
I define the routes on the main Controller like:
Ext.define('App.view.main.MainController', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',
listen : {
controller : {
'*' : {
unmatchedroute : 'onRouteChange1',
changeroute: 'changeRoute'
}
}
},
routes: {
':node': 'onNavigate',
':node/:id' : 'onNavigateDeep',
':node/:id/:tabid' : 'onNavigateDeepTab'
},
lastView: null,
onRouteChange1: function(){
console.log("hier unmatched route");
},
setCurrentView: function(hashTag) {
hashTag = (hashTag || '').toLowerCase();
console.log("hash:" + hashTag);
var me = this,
refs = me.getReferences(),
mainCard = refs.mainCardPanel,
mainLayout = mainCard.getLayout(),
navigationList = refs.navigationTreeList,
store = navigationList.getStore(),
node = store.findNode('routeId', hashTag) ||
store.findNode('viewType', hashTag),
view = (node && node.get('viewType')) || 'page404',
lastView = me.lastView,
existingItem = mainCard.child('component[routeId=' + hashTag + ']'),
newView;
// Kill any previously routed window
if (lastView && lastView.isWindow) {
lastView.destroy();
}
lastView = mainLayout.getActiveItem();
if (!existingItem) {
newView = Ext.create({
xtype: view,
routeId: hashTag, // for existingItem search later
hideMode: 'offsets'
});
}
if (!newView || !newView.isWindow) {
// !newView means we have an existing view, but if the newView isWindow
// we don't add it to the card layout.
if (existingItem) {
// We don't have a newView, so activate the existing view.
if (existingItem !== lastView) {
mainLayout.setActiveItem(existingItem);
}
newView = existingItem;
}
else {
// newView is set (did not exist already), so add it and make it the
// activeItem.
Ext.suspendLayouts();
mainLayout.setActiveItem(mainCard.add(newView));
Ext.resumeLayouts(true);
}
}
navigationList.setSelection(node);
if (newView.isFocusable(true)) {
newView.focus();
}
me.lastView = newView;
},
onNavigationTreeSelectionChange: function (tree, node) {
var to = node && (node.get('routeId') || node.get('viewType'));
if (to) {
console.log("to;:" + to);
this.redirectTo(to);
}
},
onToggleNavigationSize: function () {
var me = this,
refs = me.getReferences(),
navigationList = refs.navigationTreeList,
wrapContainer = refs.mainContainerWrap,
collapsing = !navigationList.getMicro(),
new_width = collapsing ? 64 : 250;
if (Ext.isIE9m || !Ext.os.is.Desktop) {
Ext.suspendLayouts();
refs.logo.setWidth(new_width);
navigationList.setWidth(new_width);
navigationList.setMicro(collapsing);
Ext.resumeLayouts(); // do not flush the layout here...
// No animation for IE9 or lower...
wrapContainer.layout.animatePolicy = wrapContainer.layout.animate = null;
wrapContainer.updateLayout(); // ... since this will flush them
}
else {
if (!collapsing) {
// If we are leaving micro mode (expanding), we do that first so that the
// text of the items in the navlist will be revealed by the animation.
navigationList.setMicro(false);
}
// Start this layout first since it does not require a layout
refs.logo.animate({dynamic: true, to: {width: new_width}});
// Directly adjust the width config and then run the main wrap container layout
// as the root layout (it and its chidren). This will cause the adjusted size to
// be flushed to the element and animate to that new size.
navigationList.width = new_width;
wrapContainer.updateLayout({isRoot: true});
navigationList.el.addCls('nav-tree-animating');
// We need to switch to micro mode on the navlist *after* the animation (this
// allows the "sweep" to leave the item text in place until it is no longer
// visible.
if (collapsing) {
navigationList.on({
afterlayoutanimation: function () {
navigationList.setMicro(true);
navigationList.el.removeCls('nav-tree-animating');
},
single: true
});
}
}
},
onMainViewRender:function() {
if (!window.location.hash) {
this.redirectTo("dashboard");
}
},
changeRoute: function(controller,route){
this.redirectTo(route,true);
console.log("change route fired");
},
onClickLogoutButton: function () {
// Remove the localStorage key/value
localStorage.removeItem('LoggedIn');
// Remove Main View
this.getView().destroy();
// Add the Login Window
Ext.create({
xtype: 'login'
});
},
onClickShareButton: function(){
var text = window.location;
window.prompt("Copy to clipboard:", text);
},
onNavigate:function(node){
console.log("on route change");
this.setCurrentView(node);
},
onNavigateDeep: function (node, id) {
console.log("Tab");
console.log(node + '/' + id);
var route = node+'/'+id;
this.setCurrentView(route);
},
onNavigateDeepTab: function (node, id, tabid) {
console.log("navigate Tab");
}
});
My main view is:
Ext.define('App.view.main.Main', {
extend: 'Ext.container.Viewport',
xtype: 'app-main',
requires: [
'App.view.Dashboard',
'App.view.immo.List',
'App.view.settings.Settings',
'App.view.news.News',
'App.view.help.Help'
],
controller: 'main',
viewModel: 'main',
cls: 'sencha-dash-viewport',
itemId: 'mainView',
layout: {
type: 'vbox',
align: 'stretch'
},
listeners: {
render: 'onMainViewRender'
},
items: [{
xtype: 'toolbar',
cls: 'dash-dash-headerbar shadow',
height: 64,
itemId: 'headerBar',
items: [{
xtype: 'component',
reference: 'logo',
cls: 'logo',
html: '<div class="main-logo"><img src="resources/images/logo.png">App</div>',
width: 250
}, {
margin: '0 0 0 8',
ui: 'header',
iconCls:'x-fa fa-navicon',
id: 'main-navigation-btn',
handler: 'onToggleNavigationSize',
tooltip: 'Navigation umschalten'
},
'->',
{
xtype: 'button',
ui: 'header',
iconCls: 'x-fa fa-share-alt',
handler: 'onClickShareButton',
tooltip: 'Share'
},
{
iconCls:'x-fa fa-question',
ui: 'header',
href: '#help',
hrefTarget: '_self',
tooltip: 'Hilfe'
}, {
iconCls:'x-fa fa-th-large',
ui: 'header',
href: '#Dashboard',
hrefTarget: '_self',
tooltip: 'Zum Dashboard'
}, {
xtype: 'button',
ui: 'header',
iconCls: 'x-fa fa-power-off',
handler: 'onClickLogoutButton',
tooltip: 'Logout'
}]
}, {
xtype: 'maincontainerwrap',
id: 'main-view-detail-wrap',
reference: 'mainContainerWrap',
flex: 1,
items: [{
xtype: 'treelist',
reference: 'navigationTreeList',
itemId: 'navigationTreeList',
ui: 'navigation',
store: 'NavigationTree',
width: 250,
expanderFirst: false,
expanderOnly: false,
listeners: {
selectionchange: 'onNavigationTreeSelectionChange'
}
}, {
xtype: 'container',
flex: 1,
reference: 'mainCardPanel',
cls: 'sencha-dash-right-main-container',
itemId: 'contentPanel',
layout: {
type: 'card',
anchor: '100%'
}
}]
}]
});
When we click on the tree I change the container but one of them has the route if the :id where I have a Tab:
Ext.define('App.view.settings.Settings',{
extend: 'Ext.tab.Panel',
xtype: 'settings',
itemId:'settings',
requires: [
'App.view.settings.SettingsController',
'App.view.settings.SettingsModel',
'App.view.settings.property.Property',
'App.view.settings.user.User'
],
controller: 'settings-settings',
viewModel: {
type: 'settings-settings'
},
reference: 'tab',
tabPosition: 'left',
tabBar:{
flex: 1,
tabRotation: 0,
tabStretchMax: true,
cls: 'immoNavi'
},
layout: 'Container',
defaults: {
padding: 0,
textAlign: 'left'
},
listeners: {
tabchange: 'onTabChange'
},
items: [{
xtype: 'component',
tabConfig:{
hidden: true
}
},{
title: 'Property',
itemId: 'property',
xtype: 'property',
cls: 'container'
},{
title: 'User',
itemId: 'user',
xtype: 'user'
}]
});
I went through the documentation but didn't find any tip that might help me with it. What am I missing here? Should I take care the rendering on the tab controller? Or How?
Thanks in advance for the help

Controller SlideMenu on Sencha

Help me :(
I've been researching on how to reference methods of a button using MVC on Sencha Touch, but none of the articles has worked fine for me since I declare all my controls on the constructor of my views.
View :
extend: 'Ext.Container',
xtype: 'main',
requires: [
'Ext.Menu',
'Ext.Img',
'Ext.Toolbar',
'Ext.Container'
],
config: {
scrollable: true,
type: 'card',
fullscreen : true,
html: [
'<img max width="100%" height="auto" src="resources/image/Head.png" />',
'<h1>STMIK Akakom Yogyakarta</h1>',
'<h1><img max width="40%" height="auto" src="resources/image/Logo.png"/> </h1>'
],
items: [
{
xtype: 'toolbar',
docked: 'top',
title: 'Selamat Datang',
items: [
{
xtype: 'button',
iconCls: 'list',
ui: 'plain',
action : 'slideMenu'
}
]
},
{
xtype: 'toolbar',
docked:'bottom'
}
],
},
Controller :
config: {
views: [
'Main',
'MenuNav',
'HalamanUtama'
],
refs: {
main: {
selector:'main',
xtype:'main',
autoCreate: true
},
menunav:{
selector:'menunav',
xtype: 'menunav',
autoCreate: true
},
halamanutama: {
selector: 'halamanutama',
xtype: 'halamanutama',
autoCreate: true
}
},
controll: {
'button[ui=plain]':{
tap: 'slideMenu'
},
'button=action[MenuNavOption]': {
tap: 'handleNavigation'
}
}
},
initialize: function(){
var menuNav = this.getNav();
Ext.Viewport.setMenu(menuNav,{
side: 'left',
reveal: true
});
},
slideMenu: function(){
if(Ext.Viewport.getMenus().left.isHidden())
{
Ext.Viewport.showMenu('left');
}
else
{
Ext.Viewport.hideMenu('left');
}
},
handleNavigation: function(button){
switch(button.getText()){
case 'HalamanUtama' :
var halamanutamaView = Ext.Viewport.child('halamanutama');
if (!halamanutamaView) {
halamanutamaView = this.getHalamanutama();
Ext.Viewport.add(halamanutamaView);
}
Ext.Viewport.setActiveItem(halamanutamaView);
break;
default :
var mainView = Ext.Viewport.child('main');
if(!mainView){
mainView = this.getMain();
Ext.Viewport.add(mainView);
}
Ext.Viewport.setActiveItem(mainView);
}
this.hideNav();
}
}
but still my slide menu did not show up :( please can you show me the way. Any help would be appreciated. Thank you.

Sencha Touch detailed page view into items with buttons

1.Could please anybody help me with this issue?
1.After clicking on data detail I need see something as bellow (NotesApp.view.NoteEditor):
1.button_1
1.html + {title} + html
1.button_2
1.html + {narrative} + html
app.js
Ext.application({
name: "NotesApp",
models: ["Note"],
stores: ["Notes"],
controllers: ["Notes"],
views: ["NotesList", "NoteEditor"],
launch: function () {
var notesListView = {
xtype: "noteslistview"
};
var noteEditorView = {
xtype: "noteeditorview"
};
Ext.Viewport.add([notesListView, noteEditorView]);
}
});
NotesApp.model.Note
Ext.define("NotesApp.model.Note", {
extend: "Ext.data.Model",
config: {
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
{ name: 'title', type: 'string' },
{ name: 'narrative', type: 'string' }
]
}
});
NotesApp.store.Notes
Ext.define("NotesApp.store.Notes", {
extend: "Ext.data.Store",
config: {
model: "NotesApp.model.Note",
data: [
{ title: "Ibuprofen STDATA 200", narrative: "LIEK"},
{ title: "Ibuprofen STDATA 450", narrative: "LIEK"},
{ title: "IbuprofANIN", narrative: "LATKA"}
]
}
});
NotesApp.controller.Notes
Ext.define("NotesApp.controller.Notes", {
extend: "Ext.app.Controller",
config: {
refs: {
notesListView: "noteslistview",
noteEditorView: "noteeditorview",
notesList: "#notesList"
},
control: {
notesListView: {
editNoteCommand: "onEditNoteCommand"
},
noteEditorView: {
backToHomeCommand: "onBackToHomeCommand"
}
}
},
slideLeftTransition: { type: 'slide', direction: 'left' },
slideRightTransition: { type: 'slide', direction: 'right' },
activateNoteEditor: function (record) {
var noteEditorView = this.getNoteEditorView();
noteEditorView.setRecord(record);
Ext.Viewport.animateActiveItem(noteEditorView, this.slideLeftTransition);
},
activateNotesList: function () {
Ext.Viewport.animateActiveItem(this.getNotesListView(), this.slideRightTransition);
},
onEditNoteCommand: function (list, record) {
this.activateNoteEditor(record);
},
launch: function () {
this.callParent(arguments);
var notesStore = Ext.getStore("Notes");
notesStore.load();
},
init: function () {
this.callParent(arguments);
}
});
NotesApp.view.NotesList
Ext.define("NotesApp.view.NotesList", {
extend: "Ext.Container",
requires:"Ext.dataview.List",
alias: "widget.noteslistview",
config: {
layout: {
type: 'fit'
},
items: [{
xtype: "toolbar",
title: "Liek",
docked: "top",
}, {
xtype: "list",
store: "Notes",
itemId:"notesList",
onItemDisclosure: true,
itemTpl: "<div>{title}</div><div>{narrative}</div>"
}],
listeners: [ {
delegate: "#notesList",
event: "disclose",
fn: "onNotesListDisclose"
}]
},
onNotesListDisclose: function (list, record, target, index, evt, options) {
console.log("editNoteCommand");
this.fireEvent('editNoteCommand', this, record);
}
});
NotesApp.view.NoteEditor
Ext.define("NotesApp.view.NoteEditor", {
extend: "Ext.Container",
requires:"Ext.dataview.List",
alias: "widget.noteeditorview",
initialize: function () {
this.callParent(arguments);
},
config: {
// this is working !!!
// tpl: [
// '<div><p>Info about: {title} </p></div>'
// ],
items: [
{
xtype: "button",
text: '<div style="text-align:left;">button 1<div>',
ui: "action",
id:"button_1"
},
{
xtype: 'list',
itemTpl: [
'<div>title: {title} </div>' // working not !!!
]
},
{
xtype: "button",
text: '<div style="text-align:left;">button 2<div>',
ui: "action",
id:"button_2"
},
{
xtype: 'list',
itemTpl: [
'<div>title: {narrative} </div>' // working not !!!
]
}
]
},
});
in your controller, you attach the onEditNoteCommand handler to the editNoteCommand. This is not a valid event (and is never triggered) of the Ext.dataview.List object as you can see in the Sencha documentation.
You have to attach the handler to an existing event, in this case to the itemtap one:
control: {
notesListView: {
itemtap: "onEditNoteCommand"
},
...
Problem
You created NotesApp.view.NoteEditor as list, within that list you have two separate list for title and narrative and But in controller you setting data only for NoteEditor list, not for two list within NoteEditor, so that two list will not show any data because they didn't get data.
Can do like this
In view
Give itemId for that two list.
{
xtype: 'list',
itemId : 'title',
itemTpl: [
'<div>title: {title} </div>' // working not !!!
]
},
{
xtype: "button",
text: '<div style="text-align:left;">button 2<div>',
ui: "action",
id:"button_2"
},
{
xtype: 'list',
itemId : 'narrative',
itemTpl: [
'<div>title: {narrative} </div>' // working not !!!
]
}
In controller
activateNoteEditor: function (record) {
var noteEditorView = this.getNoteEditorView();
noteEditorView.getComponent('title').setData(record.getData().title);
noteEditorView.getComponent('narrative').setData(record.getData().narrative);
Ext.Viewport.animateActiveItem(noteEditorView, this.slideLeftTransition);
},
What you trying to do ?
First of all NotesApp.view.NoteEditor is to edit note with two fields for title and narrative.
Why you have two list for title and narrative ?
What is the purpose of that list in edit screen ?

Sencha Touch Ext.TabPanel handler

I did a lot of reading but i can't figure this out.
This app uses Sencha Touch 2.0
My 'app' has a segmented button
xtype: 'segmentedbutton'
With this item
{
text: 'Blog',
scope: this,
handler: this.makeYqlRequest
}
This is what it does
blog: {
query: "select * from rss where url='http://feeds.feedburner.com/extblog' limit 5",
tpl: Ext.create('Ext.XTemplate', [
'<tpl if="item">',
'<tpl for="item">',
'<div class="blog-post">',
'<h3>{title}</h3>',
'<p>{description}</p>',
'</div>',
'</tpl>',
'</tpl>'
])
}
This works wel but now i want to use the Ext.TabPanel
And i have this item
{
title: 'Blog',
iconCls: 'home',
html: 'Blog Screen'
}
How can i get the handler from the segmented button to work with the Ext.TabPanel?
I played a little with a listener but i can't get it to work.
Can someone explain this a little more to me?
Thank you!
You will need to get a reference to your TabPanel and call the [setActiveItem](http://docs.sencha.com/touch/2-0/#!/api/Ext.Container-method-setActiveItem), passing the view you want to make active, or the index of that view.
Simple example (viewable here):
Ext.setup({
onReady: function() {
var tabPanel = Ext.create('Ext.tab.Panel', {
fullscreen: true,
items: [
{
title: 'Home',
items: [
{
xtype: 'toolbar',
items: [
{
xtype: 'segmentedbutton',
items: [
{
text: 'home'
},
{
text: 'blog',
handler: function() {
// Using an index
tabPanel.setActiveItem(1);
}
},
{
text: 'about',
handler: function() {
// Using a reference
var about = tabPanel.down('#about');
tabPanel.setActiveItem(about);
}
}
]
}
]
},
{
html: 'tap one of the above buttons to change the active tab.'
}
]
},
{
title: 'Blog',
html: 'blog'
},
{
title: 'About',
itemId: 'about',
items: [
{
xtype: 'toolbar',
docked: 'top',
items: [
{
text: 'Go to home',
handler: function() {
// using the index
tabPanel.setActiveItem(0);
}
}
]
}
]
}
]
});
}
});

show window in tabpanel

I am working on extjs4, my case is:
Extjs mvc is used to build my application, viewport is the toppest container of my application, west region is a tree, center region is a tabpage container, when click the tree item, a new page with certain content will be created. then in this page, I popup a model window, this model window just mask the page, not the whole viewport, so that I can still click the tree item to open another new page.
I have achieved this, but there is a problem, if I have already open a model window in a tab, and I switch to a another tab then return back, the model window is hidden, but I still want that window to show if I haven't closed it. Can anyone help me, is there a better way except using ifram in tabpage?
app.js:
Ext.application({
name: 'SysOpv',
appFolder: '/Js/AppSysOpv/app',
autoCreateViewport: true,
controllers: [
'Category',
'Band'
]
});
Viewport:
Ext.define('SysOpv.view.Viewport', {
extend: 'Ext.container.Viewport',
layout: 'fit',
initComponent: function() {
this.items = {
dockedItems: [{
dock: 'top',
xtype: 'toolbar',
height: 80,
items: [
{ xtype: 'component', html: 'setup' }
]
}],
layout: {
type: 'hbox',
align: 'stretch'
},
items: [{
width: 250,
xtype: 'categorytree'
}, {
id: 'maintabpanel',
flex: 1,
xtype: 'tabpanel'
}]
};
this.callParent(arguments);
}
});
Tree View:
Ext.define('SysOpv.view.category.Tree', {
extend: 'Ext.tree.Panel',
alias: 'widget.categorytree',
title: 'setup',
rootVisible: false,
useArrows: true,
hideHeaders: true,
columns: [{
flex: 1,
xtype: 'treecolumn',
text: 'Name',
dataIndex: 'name'
}],
store: 'Category',
initComponent: function() {
this.callParent(arguments);
}
});
Window View:
Ext.define('SysOpv.view.edit.Band', {
extend: 'Ext.window.Window',
alias: 'widget.editband',
title: 'Setup',
layout: 'fit',
constrain: true,
modal: true,
initComponent: function() {
this.items = [{
xtype: 'form',
bodyPadding: 10,
items: [{
xtype: 'textfield',
name: 'name',
fieldLabel: 'Name'
}]
}];
this.buttons = [{
text: 'Save',
action: 'save'
}, {
text: 'Cancel',
scope: this,
handler: this.close
}];
this.callParent(arguments);
}
});
Tree Controller:
Ext.define('SysOpv.controller.Category', {
extend: 'Ext.app.Controller',
models: [ 'Category' ],
stores: [ 'Category' ],
views: [ 'category.Tree' ],
init: function() {
this.control({
'categorytree': {
itemdblclick: this.onTreeItemdblclick
}
});
},
onTreeItemdblclick: function (tree, record, item, index, e, eOpts) {
var mainTabs = Ext.getCmp('maintabpanel');
var tabId = record.get('id');
if (mainTabs) {
var checkTab = mainTabs.getComponent(tabId);
if (checkTab) {
mainTabs.setActiveTab(checkTab);
} else {
var controller;
var list;
switch (tabId) {
case '0101':
list = Ext.widget('listband');
break;
}
if (list)
{
var tabPage = mainTabs.add({
id: record.get('id'),
title: record.get('name'),
closable: true,
layout: 'fit',
items: [ list ]
});
mainTabs.setActiveTab(tabPage);
}
}
}
}
});
Module Controller:
Ext.define('SysOpv.controller.Band', {
extend: 'Ext.app.Controller',
models: [ 'Band' ],
stores: [ 'Band' ],
views: [ 'list.Band', 'edit.Band' ],
init: function() {
this.control({
'listband button[action=edit]': {
click: this.onEdit
}
});
},
onEdit: function(button, e, eOpts) {
var edit = Ext.widget('editband');
var list = button.up('gridpanel');
if (list.getSelectionModel().hasSelection()) {
var record = list.getSelectionModel().getLastSelected();
// I use renderTo here but have no effect,
// so I search in the google find a way to show the window in tab,
// and not mask all the viewport.
button.up('#0101').add(edit);
edit.down('form').loadRecord(record);
edit.show();
} else {
console.log('Not selected');
}
}
});
Below is example solution:
Ext.create('Ext.TabPanel', {
renderTo: 'container',
items: [
{
title: 'Tab 1',
itemId: 'tab1',
items: [
{ xtype: 'button', text: 'Show window', handler: function(){
var tab = this.up('#tab1'); // Find tab
var win = Ext.widget('editband'); // Find window
this.up('tabpanel').showWindow(tab, win);
} }
]
},
],
showWindow: function(tab, w){
tab.add(w);
tab.popup = w;
w.on('close', function() { // clean up after window close
delete this.popup;
}, tab, { single: true });
w.show();
},
listeners: {
tabchange: function(panel, tab) {
if (tab.popup !== undefined) { // show window after tab change
tab.popup.show();
}
}
}
});
Basically I've created event handler for tabchange event in which I re-show window.
Working sample: http://jsfiddle.net/aCxYU/1/

Resources