how to distinguish the target back button in ST2? - extjs

I have a little problem here with Sencha Touch 2:
My App has 2 views/lists: news and events. Both have detail views.
On the news list Iam showing an filter and sort button and on the events list Iam want to show only the filter button.
When I click on an item, the nav controller automatically adds an back button.
What I do atm is:
- when the user clicks an item in the list: hide all buttons
- when the user clicks the back button: show all buttons
And thats the problem... I cannot see if it was the back button on the news detail view or the events detail view.
In my controller I have:
"mainnav[id=mainNav]": {
back: 'showButtons',
},
when I try:
"panel[id=newsDetail]": {
back: 'showButtons',
},
the event gets not triggered.
So how can I know is it was the news or events back button?
Thanks!
Edit: Its not easy to explain... here is some more information:
The "mainNav" is a navigation view and the back button gets added to its toolbar.
Ext.define('MyApp.view.MainNav', {
extend: 'Ext.navigation.View',
alias: 'widget.mainnav',
config: {
id: 'mainNav',
maxWidth: '350px',
items: [
{
xtype: 'tabpanel',
layout : {
type : 'card'
},
...
items: [
{
xtype: 'list',
title: 'News',
id: 'newsList',
store: 'newsStore',
grouped: true,
onItemDisclosure: true,
...
{
xtype: 'list',
title: 'Events',
iconCls: 'team',
id: 'eventList',
store: 'eventStore',
onItemDisclosure: true,
...
tabBar: {
docked: 'bottom'
}
...
and the navigation bar with its buttons:
navigationBar: {
minWidth: '',
width: '',
id: 'navBar',
layout: {
align: 'center',
type: 'hbox'
},
items: [
{
xtype: 'button',
id: 'settingsButton',
align: 'left',
iconCls: 'settings6',
iconMask: true
},
{
xtype: 'button',
id: 'filterbutton',
align: 'right',
iconCls: 'list',
iconMask: true
}
]
},
What iam trying to do now:
"mainnav[id=mainNav]": {
back: 'showButtons',
},
get triggered when the user hits the back button (doesnt matter if he id in newsDetail or eventsDetail) but I want to know which view the user sees after he taps the back button.
If he sees the news list then I want to show both buttons (filter and seetings) but is he sees the events list I only want to show one button.
I need something like:
showButtons: function(component, options) {
if(Ext.getCmp(backButton).down().getId() == 'newsList'){
//show 2 buttons
}else{
//show one button
}
}
Sorry if the answer is confusing... I dont know how I could explain it better.
Anyway, I would appreciate any help/idea!

A panel doesn't have a back event. So it will never get fired.
mainnav is a custom xtype you defined right? Else that selector is wrong as well.

Got a solution:
var activePanel = Ext.getCmp('MainTabPanel').getActiveItem();
var activeItem = activePanel.getItemId();
if(activeItem == 'newsList'){
this.filterNewsStore();
Ext.getCmp('showSettingsButton').show();
Ext.getCmp('filterButton').show();
}
if(activeItem == 'eventList'){
this.filterEventsStore();
Ext.getCmp('showSettingsButton').hide();
Ext.getCmp('filterButton').show();
}
I call this code when the back button gets fired.

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

Extjs : Confirmation message to save changes before closing a window

I have a editable window. When the user tries to close the window, I need to check if any changes are made in the window. If there are no changes, the window should close. If there any changes I need to prompt the user if the changes needs to be saved. If the user says yes, the changes will be saved and window closes else the window closes without the changes. For this I wrote my code in the controller layer of my code. When the user clicks on the close button in the window, everything is working fine as expected. But the problem comes only when the user tries to close the window by clicking the default [X] in the upper right corner of the window. I am trying to call my method when user clicks on this but due to the async nature of extjs the window closes initially and then the method gets called. I tried using the beforeclose event but of no use.
Here is my piece of code in the view layer.
Ext.define('MyApp.view.MyWindow', {
extend: 'Ext.window.Window',
xtype: 'myDetail',
itemId: 'myDetail',
requires: [
'ABC.controller.myDetail.myDetailController'
],
cls:'windowPopup myDetail',
title : 'ABC Detail',
layout: 'fit',
minimizable: true,
maximizable: true,
width: 1000,
height: 650,
constrain: true,
controller: null,
initComponent: function() {
this.items = [
---------------------
]
this.setTitle('ABC Detail - ' + this.config.myDetail.referenceNum);
var userNotification = '';
var bodyStyle = 'color: #000000;'
this.dockedItems = [{
xtype: 'toolbar',
dock: 'bottom',
ui: 'footer',
items: [
{
xtype: 'panel',
html: userNotification,
bodyStyle: bodyStyle
}, '->',
{
iconCls: 'icon-save',
cls:'blackButton',
itemId: 'updateAndClose',
text: 'Update & Close',
action: 'updateClose'
},{
iconCls: 'icon-reset',
cls:'blackButton',
text: 'Update',
action: 'update',
itemId: 'update'
},{
iconCls: 'icon-reset',
cls:'blackButton',
itemId: 'composeEmail',
text: 'Compose Email',
action: 'composeEmail'
},{
iconCls: 'icon-reset',
cls:'blackButton',
text: 'Refresh',
action: 'refresh',
itemId: 'refresh'
},{
iconCls: 'icon-reset',
text: 'Close',
cls:'blackButton',
scope: this,
itemId: 'closeBtn'
}
]
}];
this.callParent(arguments);
this.controller = Ext.create(XYZ.controller.mydetail.myDetailController', {view:this, identifier:this.identifier});
}
});
I am handling the buttons in the contoller layer, so if a user clicks on the close button then the contoller will check if any changes are made and then acts accordingly.
In the contoller, I am using the
this.on('closeBtn', 'click', this.confirmSaveBeforeClose, this);
this.on(null, 'close', this.confirmSaveBeforeClose, this);
Here the colseBtn event works fine but the problem comes only with the default windows close option.
Can someone give me an idea of how I can point to the method in the contoller when the user clicks on the [x] button as well.
Thanks..
Listen to the beforeclose event on the window and return false; to cancel it. Store some variable that you've already prevented the close, so the next time you hit it, clear the parameter. Something like:
listeners: {
beforeclose: function(w) {
if (!w.pendingClose) {
w.pendingClose = true;
Ext.Msg.confirm('Foo', 'Bar', function(btn) {
if (btn === 'yes') {
w.close();
} else {
delete w.pendingClose;
}
});
return false;
}
delete window.pendingClose;
}
}

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!

Set auto focus on next 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

Sencha Touch: Back button toggle visibility based on User Agent?

I am new to sencha touch and I am trying to use the back button in my toolbar. I wish to toggle its visibility based on the User Agent detected. By default it is visible but if the user agent is detected as desktop I want to set hidden : true.
I cannot understand,
How to detect the UserAgent
How to toggle the visibility
Here is the code
myapp.views.SubSettings = Ext.extend(Ext.Panel, {
layout: 'fit',
dockedItems: [{
xtype: 'toolbar',
items: [ {
ui: 'back',
id: 'backButton',
text: 'Back',
handler : function () {
// this function should detect the User Agent and set visibility to false for back button
}
}
]
}]
For detecting the user-agent there is the Ext.is class
http://dev.sencha.com/deploy/touch/docs/?class=Ext.is
Example to set the visibility of a back button on Android with the hidden property:
myapp.views.SubSettings = Ext.extend(Ext.Panel, {
layout: 'fit',
dockedItems: [{
xtype: 'toolbar',
items: [{
ui: 'back',
id: 'backButton',
text: 'Back',
hidden: Ext.is.Android
}]
}];
Example if you want to check for the user-agent and set visibility inside the function
handler: function () {
if(Ext.is.Android) {
this.hide();
}
}

Resources