Set auto focus on next button - extjs

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

Related

Ext js button in a toolbar

I would like to ask if there is a possibility to only show a button in the toolbar whenever a if statement is true.
for my case i have a snippet here
{
xtype: 'toolbar',
dock: 'bottom',
items: [
{
xtype: 'button',
text: 'Pay!',
handler: function() {
console.log('haha');
}
}
]
}
a toolbar that has a button
but i only want to show the button pay whenever the grid is not empty(I also have a grid)
how is this possible.
THANKS!
You have to bind to all events that indicate changes of the row count. Most of them are store events:
xtype:'grid',
tbar:[{
xtype:'button',
itemId:'Test'
}],
buttonchange:function() {
this.down('button[itemId=Test]').setVisible(this.getStore().getCount()>0);
},
listeners:{
viewready:function(gridview) {
var grid = gridview.ownerCt;
grid.buttonchange();
store.on({
load: grid.buttonchange(),
add: grid.buttonchange(),
remove: grid.buttonchange(),
clear: grid.buttonchange(),
filterchange: grid.buttonchange(),
scope: grid
});
}
}
Since your grid data handled by a store you have to add store load event listener.
I create working fiddle for you.
If you are using ExtJs5/6+ you might be able to bind the visibility of your button to the store count.
Something like:
{
xtype: 'toolbar',
dock: 'bottom',
items: [
{
xtype: 'button',
text: 'Pay!',
bind: {
hidden: '{!storeCount}'
}
handler: function() {
console.log('haha');
}
}
]
}
And you need to set the storeCount yourself as the property is not accessible directly (see https://www.sencha.com/forum/showthread.php?286770-unable-to-bind-view-to-store-size)
Assuming you have yourStore declared in your ViewModel, in the ViewController you should be able to do
initViewModel: function(viewModel) {
viewModel.bind('{yourStore}', function(store) {
if(store) {
store.on('datachanged', function () {
this.set('storeCount', this.getCount()) // this is the viewModel as I set the scope of the function
});
}
}, viewModel);
}

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;
}
}

adjusting position of button added to panel header?

I can add my own button to the built-in tools "Help" etc on the panel header:
tools:[
{
type:'help',
tooltip: 'Get Help',
handler: function(event, toolEl, panel){
// show help here
}
}],
header: {
layout: {
type: 'hbox',
align: 'right'
},
items: [{
xtype: 'button',
text: 'test'
}]
} ...
but button 'test' appears far left before the panel title ... header layout hbox right obviously not the way to do it :-). Button 'test' just a placeholder - I want to eventually add a menu button - so another css tool would not work - is there a simple way of doing this or do I need to use dom element positiong etc? tia.
If you're using ExtJS 4.2, you can use the titlePosition property to accomplish this. See http://jsfiddle.net/U8MSd/
tools: [{
type: 'help',
tooltip: 'Get Help',
handler: function (event, toolEl, panel) {
// show help here
}
}],
header: {
titlePosition: 0,
items: [{
xtype: 'button',
text: 'test'
}]
}

how to distinguish the target back button in ST2?

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.

ExtJS Toolbar button highlite

Iam design menu in ExtJs using Ext.Toolbar,
var ToolBar = new Ext.Toolbar({
id: 'ToolBar',
renderTo: 'divtoolbar',
items: [
{ xtype: 'spacer', width: 50 },
{ xtype: 'tbbutton', text: 'Home', handler: function () { window.location = '#Url.Content("~/Home/Home/")'; } },
{ xtype: 'tbseparator' },
{ xtype: 'tbbutton', text: 'Calendar', handler: function () { window.location = '#Url.Content("~/calendar/eventCalendar/")'; } },
{ xtype: 'tbseparator' },
{ xtype: 'tbbutton', text: 'Locations' }
]
............
how to change or highlite clicked tbbutton
thanks in advance
You need to make use of the addClass method available with the button. Create a CSS style for the visited button and call addClass method in handler. Here is an example:
handler: function(b,e) {
this.addClass('className');
}
But in your case, I see that you are navigating away from the page. In such cases you will have to store the visited buttons in a cookie or use HTML5 storage.
I wonder why you are making a multipage ExtJS application and not following the single page approach?

Resources