Ext js button in a toolbar - extjs

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

Related

I cannot get component from controller in ExtJS

I have defined a window like this:
Ext.define(), { 'MyApp.view.MyCustomWindow'
extends: 'Ext.window.Window',
alias: 'widget.mywindow',
...
items: [{
xtype: 'form',
items: [{
xtype: 'fieldset',
...
items: [{
xtype: 'combobox',
...
itemId: 'comboFilter'
}]
}]
}],
dockedItems: [{
xtype: 'toolbar',
items:[{
xtype: 'button',
itemId: 'okBtn'
}]
}]
}
Then I would like to get the component from my controller:
init: function(application) {
var me = this;
this.control({
"mywindow combobox#comboFilter": {
keypress: me.onClickCombo // removed <'>, still not working
},
"mywindow button#okBtn": {
click: me.onButtonOk // works!!!
}
});
}
But onClickCombo is never beeing called. What is wrong with mywindow combobox#comboFilter?
EDIT: Added an "OK button" that works!!! Look at my edit of the code above.
Your selector is not the problem.
Add enableKeyEvents: true to your combobox if you'd like the keypress event to be fired.
See the keypress event documentation:
This event only fires if enableKeyEvents is set to true.
Try this.
"mywindow combobox#comboFilter": {
keypress: me.onClickCombo // without <'>
}
If it isn't the solution, change:
"mywindow combobox[itemId=comboFilter]":{
keypress: me.onClickCombo // without <'>
}
UPDATE:
Add this config to the component.
Sencha api - Combobox Events
Keypress input field event. This event only fires if enableKeyEvents is set to true.

ExtJS button handler not working

My ExtJS button's handler is not invoked after clicking. Now the code looks like this.
Ext.define('EDS.view.selector.Container', {
extend: 'Ext.form.Panel',
alias : 'widget.selectorcontainer',
title: 'Selector_V2',
renderTo: 'input-div',
layout: 'fit',
height: '100%',
items: [
{
xtype: 'tabpanel',
defaults: {
bodyPadding: 10
},
}
],
buttons: [
{
text: 'Reset',
handler: function(){
console.log("Reset");
this.up('form').getForm().reset();
}
},
{
text: 'Add to constrain',
handler: this.addConstrain,
}
],
/*
* Logic for button "Add to constrain"
*
* Adds an entry into the constrain list describing a person, cost center or an application
*/
addConstrain: function(button, event){
console.log('Add_to_constrain clicked');
}
});
Originally this 'selectorcontainer' was put diretly in my app.js. But I extracted it into a stand-alone view. Before the extraction, it works perfect but now it is not working.
BTW, I've two buttons and the first "reset" works fine. So I'm wondering if there's anything wrong with "this.addConstrain" related to scoping.
You're right, it is a scoping issue - this is not the class you're defining; it's the scope at the time the Ext.define function is called (likely window). There are a few ways to handle this. The easiest (in my opinion) is to change your handler to work similarly to your reset handler:
{
text: 'Add to constrain',
handler: function(btn, e) {
//'this' is now the button
this.up('selectorcontainer').addConstrain(btn, e);
}
}
You could also add the buttons as part of the initComponent function instead of defining them as part of the Ext.define config.
initComponent: function() {
//'this' is now the selector container
this.buttons = [{
text: 'Reset',
handler: function(){
console.log("Reset");
this.up('form').getForm().reset();
}
}, {
text: 'Add to constrain',
handler: this.addConstrain
}];
this.callParent();
}
The proper way to design your class is like this. You apply your config settings to the object before you do the callParent.
Ext.define('EDS.view.selector.Container', {
extend: 'Ext.form.Panel',
alias : 'widget.selectorcontainer',
title: 'Selector_V2',
renderTo: 'input-div',
layout: 'fit',
height: '100%',
initComponent: function() {
Ext.applyIf(this, {
items: [
{
xtype: 'tabpanel',
defaults: {
bodyPadding: 10
}
}
],
buttons: [
{
text: 'Reset',
scope: this, // <--- scope to form panel
handler: function(){
console.log("Reset");
this.getForm().reset();
}
},
{
text: 'Add to constrain',
scope : this, // <--- scope to form panel
handler: this.addConstrain
}
]
});
this.callParent(arguments);
}
/*
* Logic for button "Add to constrain"
*
* Adds an entry into the constrain list describing a person, cost center or an application
*/
addConstrain: function(button, event){
console.log('Add_to_constrain clicked');
}
});

How To Get Reference to base component in Viewport from pop up window in ExtJS 4

I'm struggling with getting references and not using Ext.getCmp(..). I understand why it is best not to use Ext.getCmp in production apps, primarily because of potential confusion around duplicated DOM id's. I've create a basic sample below that I've put some comments in that I'm hoping, if I can find answers to will help me better understand how to get references.
I'm also looking for some really good explanations, tutorials, etc on this topic. I gather that learning how to do ComponentQuery's would be best but I'm not even sure if that is the case. So without further words, here the code. Please take a look at button event in pop up window for what I'm hoping to figure out.
Ext.define('MyApp.view.MyViewport', {
extend: 'Ext.container.Viewport',
layout: {
type: 'border'
},
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'panel',
flex: 2,
region: 'center',
title: 'My Panel',
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'button',
text: 'MyButton',
listeners: {
click: {
fn: me.onButtonClick,
scope: me
}
}
}]
}],
items: [{
xtype: 'component',
html: '<b>my component</b>'
}]
}]
});
me.callParent(arguments);
},
onButtonClick: function (button, e, eOpts) {
Ext.define('MyApp.view.MyWindow', {
extend: 'Ext.window.Window',
height: 250,
width: 400,
title: 'My Window',
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'button',
text: 'Want to get link to my component in window that opened this',
listeners: {
click: {
fn: me.onButtonClick,
scope: me
}
}
}]
});
me.callParent(arguments);
},
onButtonClick: function (button, e, eOpts) {
// I would like to set the html property of the
// component in the window below
// I would like to do this efficintly
// user itemId?
// use componentquery?
// use up/down/etc.
//
// Need help with componentquery, extjs help is not helpful for me
// I need more basics I think.
this.up('panel').up('panel').down('component').html = '<i>set from button</i>';
console.log(this.up('panel').up('panel').down('component'));
}
});
var win = Ext.create('MyApp1.view.MyWindow', {});
win.show();
}
});
Windows are floating so you cant use up to get back to your viewport. Likewise, you can't use down in your viewport to find any components in windows. Your outer onButtonClick method is called in the scope of the viewport. If you save off a reference to this at that point, you can use it with down to grab your component.
onButtonClick: function() {
var viewport = this;
Ext.define('YourWindow', {
// setup everything
onButtonClick: function() {
// this may not return what you want since everything
// else inside the viewport is technically also a component
// You'd be better off adding an itemId to the component
// you wish to grab and using that in the call to down.
console.log(viewport.down('component'));
}
});
// show window
}
On a side note, I'm not sure that you want to be defining your window class on button click. Unless you can guaranty that the button will only ever be clicked once, you should define your class elsewhere and just create the window in the click handler. That complicates getting a reference to the viewport, but you could easily set it as a property on the window when you create it, or just add the onButtonClick method in the window's configuration object.

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

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