Related
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
Afterrender event not work for my tabpanel component.
code of my tabpanel:
Ext.define('Admin.view.tabs.Tabs', {
extend: 'Ext.tab.Panel',
shadow: true,
cls: 'demo-solid-background',
tabBar: {
layout: {
pack: 'center'
}
},
activeTab: 1,
defaults: {
scrollable: true
},
items: [
{
title: 'Tab 1',
html : 'By default, tabs are aligned to the top of a view.',
cls: 'card'
},
{
title: 'Tab 2',
html : 'A TabPanel can use different animations by setting <code>layout.animation.</code>',
cls: 'card'
}
],
listeners: {
afterrender: function(corpse) {
console.log('afterrender');
}
}});
This tab panel I use in view formpanel that added in main view like this:
doCompose: function (to) {
var me = this,
composer = me.composer,
view = me.getView(),
viewModel = me.getViewModel(),
toField;
me.hideActions();
if (!composer) {
me.composer = composer = view.add(
{
xtype: 'compose',
flex: 1
});
if (to) {
toField = me.lookupReference('toField');
toField.setValue(to);
}
viewModel.set('composing', true);
}
}
Compose it's my formpanel which contain tabpanel.
I try use example from official templates ExtJs Sencha.
View for mobile profile compose email https://github.com/syscobra/extjs-admin-dashboard-template/tree/master/modern/src
As i said Ext-JS 6 modern TabPanel has not afterrender event.Instead you can use painted, heres the
FIDDLE
listeners: {
painted: function () {
//your code
}
}
On HomeView I have a button that navigates to readyContainer view. And on the tabbar I have an item that also goes to readyContainer view. Now on readyContainer I have list of buttons. Please refer to ReadyContent.js above. I'm having issues as to which container do I have to use as reference to push views. If I went to readyContainer from Home, and tap on buttons there, the controller would refer to homeContainer. If I went to readyContainer from the tab bar, should the controller refer to readyContainer? How do I know which view to be set as reference. Any help would be highly appreciated.
refs: {
readyContainer: 'readyContainer'
}
or
refs: {
homeContainer: 'homeContainer'
}
main.js
Ext.define('COSD.view.Main', {
extend: 'Ext.tab.Panel',
requires: [
'Ext.TitleBar',
],
config: {
tabBarPosition: 'bottom',
layout:'card',
items: [
{
xtype:'homeContainer'
},
{
xtype:'readyContainer'
},
{
xtype:'emergencyscreenview'
},
{
xtype:'allnews'
}
]
}
});
homeContainer.js
Ext.define('COSD.view.HomeContainer',{
extend:'Ext.NavigationView',
xtype:'homeContainer',
config:{
title:'Home',
iconCls:'home',
scrollable:true,
styleHtmlContent:true,
styleHTMLCls:'home',
html:[].join(""),
items:[
{
xtype:'newsContent'
}
]
}
})
homeContent.js
Ext.define('COSD.view.HomeContent',{
extend:'Ext.Panel',
xtype:'newsContent',
config:{
title:'San Diego County Emergency ',
iconCls:'home',
cls:'toolbar',
layout:'vbox',
items:[
{
xtype: 'button',
id:'readyButton',
style:'border-radius:0',
cls:'ReadyImageButton',
pressedCls:'ReadyImageButtonSelected',
html:'<div class="mainbutton-container-green"> <div class="mainbutton-thumb"><img src="resources/images/AppHome_ReadyIcon-Default Platform.png" /></div><div class="mainbutton-content"><i> <h3 class="mainbutton-title">ReadySanDiego</h3><p>Plan, Prepare </p></i></div></div>',
},
{
xtype: 'button',
id:'emergencyButton',
style:'border-radius:0',
cls:'EmergencyImageButton',
pressedCls:'EmergencyImageButtonSelected',
html:'<div class="mainbutton-container-red"> <div class="mainbutton-thumb"><img src="resources/images/AppHome_EmergencyIcon-Default Platform.png" /></div><div class="mainbutton-content"><i> <h3 class="mainbutton-title">Emergency</h3><p>News, Maps, Shelters </p></i></div></div>',
},
{
xtype: 'label',
cls:'NewsUpdate',
html: 'News Updates'
},
{
xtype: 'label',
cls:'LatestNews',
//autoEl:{id:'timediv'}
html: '<div id="timediv">Latest News | Refreshed: 8/2/2013 10:36:26 AM</div>'
},
{
xtype:'list',
id:'newslistContent',
loadingText: "loading...",
emptyText: '<div>No notes found.</div>',
store:'HomeStore',
itemTpl:'<div><p>{title}</p><p class="newsItemTitle">{publishedDate}</p></div>',
flex: 1,
plugins: [
{
xclass: 'Ext.plugin.PullRefresh',
pullRefreshText: 'Pull to refresh...',
},
{
xclass: 'Ext.plugin.ListPaging',
autoPaging: true,
}
],
}
]
}
})
ReadyViewContainer.js
Ext.define('COSD.view.ReadyViewContainer',{
extend:'Ext.NavigationView',
xtype:'readyContainer',
config:{
title:'Ready',
iconCls:'home',
scrollable:true,
styleHtmlContent:true,
styleHTMLCls:'home',
html:[].join(""),
items:[
{
xtype:'readyContent'
}
]
}
})
ReadyContent.js
Ext.define('COSD.view.ReadyContent', {
extend:'Ext.Panel',
xtype:'readyContent',
config: {
title:'Ready',
iconCls:'home',
layout:'vbox',
scrollable:true,
styleHtmlContent:true,
styleHTMLCls:'home',
html:[].join(""),
items:[
{
xtype: 'button',
id:'prepareDisaster',
style:'border-radius:0',
cls:'NavButtonListing',
pressedCls:'NavButtonListingSelected',
html:'<div class="ButtonListings-container"> <div class="ButtonListings-thumb"><img src="resources/images/CoSD_PrepareIcon-Default Platform.png" /></div><div class="ButtonListings-content"><h3 class="listbutton-title">Prepare for Disasters</h3></div></div>',
},
]
}
});
ReadyViewController.js
Ext.define('COSD.controller.ReadyViewController', {
extend: 'Ext.app.Controller',
config: {
control: {
'#prepareDisaster': {
tap: 'prepareDisasterTap'
}
},
refs: {
readyContainer: 'readyContainer'
}
},
prepareDisasterTap: function() {
this.getReadyContainer().push({xtype: 'preparedisasterscreenview'})
}
});
Thanks for explaining the usage of id's. Sorry about not being clear about the issue I'm having. I'm having trouble explaining the scenario. I have an option to navigate to ReadyViewContainer using id:'readyButton', on the home screen and from the tab bar at the bottom called xtype:'readyContainer'). I only have one version of this ReadyViewContainer. If the user tap on readyButton, it navigates to ReadyViewContainer but the active tab is the Home tab. If the user selected the 'Ready' icon on tab bar , it will also navigate to ReadyViewContainer and the active tab bar would be 'Ready'. ReadyViewContainer has a button called preparefordisaster. So that means the user could have gotten to this screen from either the Ready tab bar(active tab is 'Ready') or the readyButton on home screen(active tab is 'Home'). When the user selects preparefordisaster which container do I use to push the view because I wouldn't know if the user got to this screen from the button on home view or the Ready tab bar.
I'm not sure I entirely follow your post, but I will try to answer...
First, you shouldn't really use id on your components unless you know 100% that you will only use that component one time, and you will only not use that ID for any other component. If you want to use an ID for a component, use itemId, which provides a relative path to obtain a component based on ID.
{
xtype: 'button',
itemId: 'emergencyButton',
style:'border-radius:0',
//...etc...
},
Using that knowledge, you can combine it with the fact that you can use multiple refs within your controllers, and you can use longer selectors also (e.g. emerButton: 'homeContainer #emergencyButton').
Ext.define('COSD.controller.ReadyViewController', {
extend: 'Ext.app.Controller',
config: {
control: {
'readyContent #prepareDisaster': {
tap: 'doPrepareDisaster'
},
'homeContent #emergencyButton': {
tap: 'doEmergencyButton'
},
},
refs: {
readyContainer: 'readyContainer',
homeContainer: 'homeContainer'
}
},
doPrepareDisaster: function() {
this.getReadyContainer().push({ xtype: 'preparedisasterscreenview' });
},
doEmergencyButton: function() {
this.getHomeContainer().push({ xtype: 'emergency-screen-view' });
}
});
So, when pushing your views, you should push them onto the correct NavigationView, since that is the view that will be active when you tap that button.
I have wizard in extjs, where I place next, back and cancel button.
As per requirement I need to set focus on next button automatically. How to do it.
buildButtons : function() {
return [
{
text:'Back',
id:'backBtn',
hidden:true,
autoHeight:true,
action: 'Back'
},
{
text:'Next',
id:'nextBtn',
autoHeight:true,
hidden:false,
action: 'Next'
},
{
text:'Finish',
id:'finishBtn',
autoHeight:true,
hidden:false, // Comments below line if you want finished button on each panel.
//hidden:true,
action: 'Finish'
},
{
text:'Cancel',
id:'cancelBtn',
autoHeight:true,
hidden:false,
action: 'Cancel'
}
];
}
Assuming you are talking about the latest version (4.1.1)
Get the button reference and call focus
You should do this with the afterrender event of either the button itself or the component that hold the button.
Example that can be executed directly in one of the API code-boxes
Ext.create('Ext.Container', {
renderTo: Ext.getBody(),
defaults: {
xtype: 'button'
},
items : [
{
text: 'Next',
action: 'next'
},
{
text: 'Prev',
action: 'prev'
},
{
text: 'Cancel',
action: 'cancel'
}
],
listeners: {
afterrender: function(b) {
b.down('button[action=next]').focus(false, 100);
}
}
});
Edit to answer to the comment:
Based on the given information I suggest you are using the buttons config property to place your buttons. In your case I would recommend you to use the dockedItems array instead of the convenience buttons array. Try the following:
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
ui: 'footer',
defaults: {minWidth: minButtonWidth},
items: [
{
text:'Back',
id:'backBtn',
hidden:true,
autoHeight:true,
action: 'Back'
},
{
text:'Next',
id:'nextBtn',
autoHeight:true,
hidden:false,
action: 'Next'
},
{
text:'Finish',
id:'finishBtn',
autoHeight:true,
hidden:false, // Comments below line if you want finished button on each panel.
//hidden:true,
action: 'Finish'
},
{
text:'Cancel',
id:'cancelBtn',
autoHeight:true,
hidden:false,
action: 'Cancel'
}
],
listeners: {
afterrender: function(b) {
b.down('button[action=Next]').focus(false, 100);
}
}
}]
Yeah as #sra says, use something like:
Ext.getCmp('IdOfNextButton').focus();
Or better still from your form use one of the up/down methods to find it via a specific class rather than relying on an Id.
A better approach, if you can use it, would be to use the defaultFocus config of Ext.window.Window. From the docs:
defaultFocus : String/Number/Ext.Component
Specifies a Component to receive focus when this Window is focused.
This may be one of:
The index of a footer Button.
The id or Ext.AbstractComponent.itemId of a descendant Component.
A Component.
Available since: 4.0.0
If you were going to take the "Getting Started with Sencha Touch 2" video one step further and add button navigation on the home page to allow you to go to the Blog and Contact pages how would you do it? I have set it all up like the thread Sencha Touch 2 MVC - how to switch views with button
The problem that I am running into is that if I create a button to go to the Blog page in the Home.js page the button will work but then the nested list on the Blog.js page does not work anymore and the TitleBar from Main.js does not appear on Blog.js anymore either. My controller code looks like this
control: {
'blog list': {
itemtap: 'showPost'
},
'button[go]':{
tap: function(){
Ext.Viewport.setActiveItem({
xtype: 'blog'
})
}
}
}
Where showPost is the same function as the GS video. My button on the Home.js file looks like this
items:[
{
xtype: 'button',
text: 'text',
go: 'buttonPage'
}]
}
Everything else is exactly like the GS video. I want the button on the Home.js page to act exactly like the buttons on the TitleBar work in Main.js from the Getting Started video. What am I missing? Thanks in advance.
4/13/12 Update: all the js files. They are all essentially the original GS video code.
view/Main.js
Ext.define("GS.view.Main", {
extend: 'Ext.tab.Panel',
requires: ['Ext.TitleBar'],
config: {
xtype: 'bottombar',
tabBarPosition: 'bottom',
items:[{xtype: 'homepanel'},
{xtype: 'blog'}]}
});
view/Home.js
Ext.define('GS.view.Home', {
extend: 'Ext.Panel',
xtype: 'homepanel',
config: {
title: 'Home',
iconCls: 'home',
items:[{
xtype: 'button',
text: 'text',
go: 'buttonPage'}]
}
})
view/Blog.js
Ext.define('GS.view.Blog',{
extend: 'Ext.navigation.View',
xtype: 'blog',
requires: ['Ext.dataview.List', 'Ext.data.proxy.JsonP', 'Ext.data.Store'],
config: {
title: 'Blog',
iconCls: 'star',
items: [{
xtype: 'list',
itemTpl: '{title}',
title: 'Recent Posts',
store:{
autoLoad: true,
fields: ['title', 'author', 'content'],
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://data.9msn.com.au/Services/Service.axd/feeds/rss/news/headlines',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
}
}
}]
}
})
controller/Main.js
Ext.define('GS.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
blog: 'blog'
},
control: {
'blog list': {
itemtap: 'showPost'
},
'button[go]':{
tap: function(){
Ext.Viewport.setActiveItem({
xtype: 'blog'
})
}
}
}
},
showPost: function(list, index, element, record){
this.getBlog().push({
xtype: 'panel',
title: record.get('title'),
html: record.get('content'),
scrollable: true,
styleHtmlContent: true,
})
}
});
app.js
Ext.application({
name: 'GS',
requires: ['Ext.MessageBox'],
controllers: ['Main'],
views: ['Main', 'Home', 'Blog'],
launch: function() {
Ext.Viewport.add(Ext.create('GS.view.Main'));
},
});
Since using Ext.Viewport.setActiveItem({xtype: 'blog'}) doesn't reuse the xtypes that you have created it gets confused when trying to use the blog list. I use some of what Roberto said and a little bit of my own code to end up with the controller 'button[go]' function looking like this:
'button[go]':{
tap: function(btn){
if(Ext.ComponentQuery.query(btn.go) == '')
{
Ext.Viewport.setActiveItem({
xtype: btn.go
})
}
else
target = Ext.ComponentQuery.query(btn.go);
Ext.Viewport.setActiveItem(target[0])
}
}
And that created the xtype the first time and then reused it every subsequent time so the navigation in the nexted list worked as well as the navigation on the homepage
you can easily switch views by button tap if you are using navigationView.
take your main view as navigationView .
put the button into the navigationView .
write the following code into tap-listener of your button
this.up('your navigationView xtype').push({
xtype: 'xtype of the view at which you wanna go by button tap'
});
2 Steps You have to follow
in View
{
xtype: "button",
//text: "Book Bus Ticket",
ui: 'action',
action:"book" , // button Action
},
{
xtype: "button",
text: "Get Ticket Details",
ui: 'action',
action:"getticket" , // button Action
},
Note the Button Action
2.in Controller
first specify the particular view xtype as a ref in that controller
Ext.define('jetbus.controller.BookticketController', {
extend: 'Ext.app.Controller',
refs: {
'busdetails':"busDetailsList", // object:xtype
},
control: {
'busdetails button[action=book]': { // button action
tap: 'book'
},
' button[action=getticket]': { // button action
tap: 'getticket'
},
}
book: function(){
var mn=Ext.create('abc.view.Main'); // Functionname the page you want to redirect
Ext.Viewport.add(mn);
Ext.Viewport.setActiveItem(mn);
},