Nested card layout panels fire unexpected activate events. [ExtJS] - 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.

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

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

ExtJS6 Launch Modal Window fron ViewController

I am attempting to launch a modal window from within a viewcontroller. Consider the following code (also located at https://fiddle.sencha.com/#fiddle/1335):
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.define('Window1',{
extend: 'Ext.window.Window',
controller: 'winctrl',
xtype: 'window1',
initComponent: function(){
Ext.apply(this,{
title:'Window 1',
width: 400,
height: 400,
layout: {type:'hbox',pack:'center',align:'middle'},
items:[{
xtype: 'button',
text: 'Click Me!',
handler: 'btnClickMeClick'
}]
});
this.callParent(arguments);
}
});
Ext.define('Window2',{
extend: 'Ext.window.Window',
xtype: 'window2',
initComponent: function(){
Ext.apply(this,{
title: 'Window 2',
width: 200,
height: 200,
modal: true,
//renderTo: Ext.getBody(),
layout: {type:'hbox',pack:'center',align:'middle'},
items:[{
html: 'Modal Looks Odd',
listeners:{
afterrender: 'htmlRender'
}
}]
});
this.callParent(arguments);
}
});
Ext.define('WinCtrl',{
extend: 'Ext.app.ViewController',
alias:'controller.winctrl',
btnClickMeClick: function(){
this.dialog = this.getView().add({xtype:'window2'});
this.dialog.show();
},
htmlRender: function(){
console.log(this.dialog);
}
});
Ext.widget('window1').show();
}
});
The problem I am running into is that when window 2 is launched it is modal only to the view that launched it and I need the window to be modal to the entire document. If run as is, the htmlRender function will log the window 2 object correctly. I attempted to set the renderTo: Ext.getBody() on window 2; however, I am unable to access it's object when it is rendered. In this case, htmlRender logs an "undefined" for the window 2 object.
I need some help allowing window 2 to be rendered as a modal to the document while allowing me to reference its object. Thanks for any help.
Don't add the window to that view, replace:
this.dialog = this.getView().add({xtype:'window2'})
With:
this.dialog = Ext.widget('window2');
Working example: https://fiddle.sencha.com/#fiddle/1338
I was able to work around this issue by setting the renderConfig:Ext.getBody() on window, removing the listener on the html item and adding a listener for the show event on window2: https://fiddle.sencha.com/#fiddle/133j

Extjs 4.1 - Listerning in CellEditing plugin not working at second time

i define a treeGrid with plugin CellEditing like
Ext.define('MyExample', {
extend: 'Ext.tree.Panel',
id: 'example',
alias: 'example',
....
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1,
listeners: {
beforeedit: function(plugin, edit){
alert('don't run second time');
}
}
})
],
...
And i have a button when i click this button will call below window (this window has treeGrid above)
Ext.create('Ext.window.Window', {
title: 'Phân xử lý',
modal:true,
height: 500
width: 500
layout: 'border',
...
item[
{
title: 'example',
region: 'center',
xtype: 'example', // that here
layout: 'fit'
}
]
Everything working at first time but when i close the window at first time and click button to call window again then CellEditting still working but listeners not working ?
How to fix that thanks
EDIT
Please see my example code in http://jsfiddle.net/E6Uss/
In first time when i click button. Everything working well like
But when i close Example window and open it again I try click to blocked cell again i get a bug like
How to fix this bug? thanks
The problem here is that you are using Ext.create inside the plugins array for the tree grid. This have the effect of creating it once and attaching the result adhoc to your defined class.
If you close the window, all the resources within the window are destroyed. The second time you instantiate the tree panel, the plugin is not there. Take a look at this fiddle : I see what your issue is. Take a look at http://jsfiddle.net/jdflores/E6Uss/1/
{
ptype : 'cellediting',
clicksToEdit: 1,
listeners: {
beforeedit: function(plugin, edit){
console.log('EDITOR');
if (edit.record.get('block')) {
alert('this cell have been blocked');
return false;
}
}
}
}
You're recreating the window on every click of the button. This recreation may be messing with your configuration objects or destroying associations or references within them, or something similar. Try to reuse the window everytime by replacing your button code with something like:
Ext.create('Ext.Button', {
text: 'Click me',
visible: false,
renderTo: Ext.getBody(),
handler: function(button) {
if(!button.myWindow)
{
button.myWindow = Ext.create('Ext.window.Window', {
title: 'Example',
height : 300,
width : 500,
layout: 'border',
closeAction: 'hide',
items: [{
region: 'center',
floatable:false,
layout:'fit',
xtype: 'example',
margins:'1 1 1 1'
}
]
});
}
button.myWindow.show();
}
});
Maybe it needed complete the editing cell, try finish it:
...
beforeedit: function(plugin, edit){
alert('don't run second time');
plugin.completeEdit();
}
Sencha: CompleteEdit
I put together a working example here: http://jsfiddle.net/jdflores/6vJZf/1/
I think the problem with your column is that it's dataIndex is expecting that the editor value be a boolean type (because 'block' was set as datIndex instead of 'date'). I assume you are using the 'block' field just to identify which are blocked to be edited. I modified the fidle provided here: http://jsfiddle.net/jdflores/6vJZf/1/
{
text: 'Block Date',
dataIndex: 'date',
xtype: 'datecolumn',
format: 'd/m/Y',
editor: {
xtype: 'datefield',
allowBlank: true,
format: 'd/m/Y'
}
}

EXTJS OnClick Tab Event

Is there a way to attach an OnClick event to a tab switch in EXTJS?
I make the grid like this:
var simple = new Ext.FormPanel({
labelWidth: '100%',
border:false,
width: '100%',
style:
{
height: '291px'
},
items: {
xtype: 'tabpanel',
activeTab: 0,
//labelWidth: 75, // label settings here cascade unless overridden
items:[{
url:'save-form.php',
title: 'Tab 1',
...
Thanks!
I added in a listener after the tabs were defined like this:
//define all tabs, and after the ] from the tab panel JSON:
listeners: {
'tabchange': function(tabPanel, tab) {
alert("tab changed");
}
}
This just alerts when the tab changed, which is sufficient for my purposes. I'm not sure though how to find out which tab is the current tab.
Hope this helps someone in the future.
There is a tabchange event that fires when the active tab changes: http://www.sencha.com/learn/Ext_FAQ_TabPanel
There is no event for tab click in TabPanel, however you can bind into click event on each tab. You can add custom event.
Following example help to you.
{
xtype : 'tabpanel',
items : [{
xtype : 'panel',
title: 'ABC'
},{
xtype : 'panel',
title : 'XYZ'
}],
listeners: {
render: function() {
this.items.each(function(panel){
// Added tabclick event for tabpanel
panel.tab.on('click', function(){
panel.addEvents('tabclick'); // addded event to panel
panel.fireEvent('tabclick', panel);
});
});
}
}
}

Resources