I cannot get component from controller in ExtJS - 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.

Related

Nested card layout panels fire unexpected activate events. [ExtJS]

Following code
Ext.define('Fiddle.Panel', {
extend: 'Ext.Container',
layout: 'card',
items: [{
html: 'Check the console. Panel 2.1 fires activate event desipte the panel 1 being active',
xtype: 'panel',
listeners: {
activate: function (){
console.log('1 active');
}
}
},{
xtype: 'panel',
layout: 'card',
items: [{
xtype: 'panel',
// items: [... fieldpanel, fields here]
listeners: {
activate: function (){
console.log('2.1 active');
}
}
},{
xtype: 'panel',
listeners: {
activate: function (){
console.log('2.2 active');
}
}
}
}],
listeners: {
activate: function (){
console.log('2 active');
}
}
}]
});
Will immediately output.
1 active
2.1 active
I would like to focus a text field in the panel 2.1 on activation, but the event is fired even the field respectively whole 2.1 panel is not rendered yet as it is a child of inactive panel 2. Is this a feature or bug ? Should I use different approach ? Thank you for help.
Sencha Fiddle
https://fiddle.sencha.com/fiddle/39vc
Your two card layout panels (containers) will have an active item. So that is why they are both firing the activate event.
I would do the focus on the activeitemchange event and init. Here is a fiddle:
Fiddle
I had to do a defer in the init to be sure the field was rendered. there may be a better way to do this. See the buttons at the bottom to switch between the two panels.

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

Listener events not being triggered

I have been playing around with the documentation whilst learning ExtJS. But when testing listener events nothing will happen.
I have generated a modern app using sencha CMD. I deleted all the code that wasn't needed and then added my own based on the documentation. However the listener events just don't seem to work at all. I have tried with several examples and no luck.
What could be the problem?
One example is -
Main
Ext.define('ListenerTesting.view.main.Main', {
extend: 'Ext.panel.Panel',
xtype: 'app-main',
requires: [
'Ext.MessageBox',
'Ext.layout.Fit'
],
controller: 'main',
viewModel: 'main',
tabBarPosition: 'left',
items: [{
xtype: 'button',
text: 'click me',
listeners: {
afterrender: function() {
Ext.Msg.alert("Success", "Message");
}
}
}]
});

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

Sencha touch NestedList: How to stop audio player when closing detailsCard

I have an Ext.Audio component inside the detailsCard of a NestedList in my Sencha touch 2.1 app.
I can't understand how to stop the audio stream when tapping the back button in the detailsCard. I also don't understand how to listen to the "back button tap event" only for the back button of the detailsCard. Here's my code:
Ext.define('App.view.Lead', {
extend: 'Ext.NestedList',
xtype: 'lead',
config: {
title: 'Lead',
iconCls:'lead',
store: 'LeadStore',
displayField: 'title',
detailCard: { html: 'details' }
},
getDetailCard: function(node) {
if (node) {
return {
xtype: 'container',
layout: 'fit',
items: [
{
xtype: 'panel',
layout:'fit',
html: node.get('text')
},
{
xtype: 'audio',
docked: 'bottom',
url : node.get('audio'),
autoPause: true,
},
]
}
}
}
});
Thanks in advance
You can give your audio an id config for reference:
{
xtype: 'audio',
docked: 'bottom',
url : node.get('audio'),
autoPause: true,
id: 'audio'
}
To handle back button you can use back event of your nested list along with stop method to stop your audio:
back: function() {
Ext.getCmp('audio').stop();
}
You'l be safe if you use itemId.
itemId: audio
Then you can make use of Ext.ComponentQuery to retrieve it:
Ext.ComponentQuery.query('#audio')[0].stop();

Resources