can i hide extjs toolbar using action in other controller? - extjs

here is part of toolbar (buttons are not previewed) as usual:
VIEW
Ext.define('TEST.view.desktop.Toolbar', {
extend: 'Ext.panel.Panel',
alias: 'widget.testtoolbarX',
initComponent: function() {
debugger;
var me = this;
Ext.applyIf(me, {
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
action: 'toolbarMouseOut',
iam trying to get action in controller, it works with buttons fine but not with whole toolbar
if i'm coding like this it works (but i dont need it)
CONTROLLER:
init: function() {
var me = this,
app = me.getApplication();
me.control({
'[xtype=testtoolbarX] button[action=toolbarMouseOut]': {
mouseout: me.onHideToolbar
},
I need it so, but iam not sure if toolbar is right name here. i tried everything and it still not going.
init: function() {
debugger;
var me = this,
app = me.getApplication();
me.control({
'[xtype=testtoolbarX] toolbar[action=toolbarMouseOut]': {
mouseout: me.onHideToolbar
},
please help me how can i react on MOUSEOUT in body of whole Toolbar??

As I mentioned in my comment, there's no mouseout event defined for the toolbar object itself. However, you can listen for that event on the el. Declaring it like this works:
{
xtype: 'toolbar',
dock: 'top',
listeners: {
el: {
mouseout: function() {
console.log('Mouseout on toolbar!');
}
}
},
items: []
}

Related

How to determine when a toolbar has been clicked in ExtJS 7.0.0

I want to detect clicks on my toolbar, alternatively focus of toolbar.
The use-case has been extracted from a LiveSearchGrid which has a toolbar, the one seen in the code. The code provided renders fine, but no detect of click, focus, or anything else. Just nothing.
See below:
<div id="toolbar"></div>
<script type="text/javascript">
Ext.create('Ext.toolbar.Toolbar', {
renderTo: 'toolbar',
name: 'searchBar',
focusEl: 'toolbar',
listeners: {
focusenter: function () {
console.log('focusenter')
},
focus: function () {
console.log('focus')
}
},
items: [
{
xtype: 'tbtext',
html: 'Search',
listeners: {
focusenter: function () {
console.log('focusenter')
}
}
},
'Case Sensitive'
]
})
</script>
The following is plain JavaScript which solves my problem.
document.getElementById('toolbar').onclick = function () {
console.log('hello world');
}
What am I doing wrong?
You can set a DOM listener on the underlying Ext.Element using the element property of the listener config
Ext.create('Ext.toolbar.Toolbar', {
renderTo: 'toolbar',
name: 'searchBar',
focusEl: 'toolbar',
listeners: {
click: {
element: 'element', // bind to the underlying element
fn: function() {
console.log('Toolbar element was clicked!');
}
},
focusenter: {
element: 'element', // bind to the underlying element
fn: function() {
console.log('Toolbar element was focused!');
}
}
},
items: []
});
That property can be set to element or bodyElement

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: How bind context menu action in controller?

Fiddle: https://fiddle.sencha.com/#fiddle/q02
Ext.define('EController', {
extend: 'Ext.app.ViewController',
alias: 'controller.test',
control: {
'#myAction': {
click: function() {
alert('My action')
}
}
}
});
var sellAction = Ext.create('Ext.Action', {
text: 'My action',
itemId: 'myAction'
});
var contextMenu = Ext.create('Ext.menu.Menu', {
items: [
sellAction
]
});
var grid = Ext.create('Ext.grid.Panel', {
controller:'test',
...................................
dockedItems: [{
xtype: 'toolbar',
items: [
sellAction
]
}],
Alert fires in toolbar button, but do not work in context menu.
How add same listener for context menu button and toolbar button? (Best way)
You can't. Simply because, unlike the toolbar, the context menu is not a part of the grid — it is just shown by the grid at e.getXY(). Therefore your control directive cannot reach the context menu.
An alternative would be to use action handlers instead of controller's control:
var sellAction = Ext.create('Ext.Action', {
text: 'My action',
itemId: 'myAction',
handler: function() {
alert('My action')
}
});
Fiddle fork: https://fiddle.sencha.com/#fiddle/q0d

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.

Resources