ExtJS 4 - how to hide context menu when left clicking the Ext.panel.Panel? - extjs

I have context menu on a panel (geoext 2 map panel)
This is how I init it :
var ctxMenu;
Ext.get("mapPanel-body").on("contextmenu", function (event, element) {
event.stopEvent();
if (!ctxMenu) {
ctxMenu = Ext.create('Ext.menu.Menu', {
width:100,
height:100,
margin: '0 0 10 0',
items: [{ text: 'test', action: 'test'}]
});
}
ctxMenu.showAt(event.getXY());
return false;
});
What happens is that right click on the map opens the context menu ... but it stays open till I choose an item from the menu (left click outside it doesnt close it)
I'm using ExtJS 4.2.1
Why it behaves like this ?

May be the reason is , panel doesnot contain a default contextMenu event.
But you are defining a contextMenu by using the on on the panel.
For this issue you can define a click event for the panel by using the same on config and check whether the object contextMenu is present or not.
If it is present , then hide the contextMenu by using contextMenuObject.hide().

Related

How to create ExtJS5 draggable window?

I need to create a window that will be always visible unless it is made hidden by clicking on an icon. Clicking on that icon a second time will make the window re-appear. The icon needs to be stuck at the top left corner of the window and outside of the window. I am planning to create a window without title and with two items 1: Button to hide/show and 2: the actual panel. The fiddle can be found at: https://fiddle.sencha.com/#fiddle/bi7 I need to make the portion behind the button transparent. Is there a way to do that?
You would do this manually, ideally with CSS classes. The following is crude, using inline styling, but works. Add the following listeners attribute to your button
{
xtype: 'button',
...
listeners: {
click: function(){
var panel = Ext.getCmp("togglePanel");
if (panel.el.dom.style.display == "none") {
panel.el.dom.style.display = "block";
} else {
panel.el.dom.style.display = "none";
}
}
}
}
and include the id 'togglePanel to your green panel containing the slider
id: "togglePanel",
Clicking the button will show/hide your panel

How to Scroll to Bottom of Grid using ExtJs

I'm using ExtJs. I want my scroll still in the bottom (last row) when i click 'add' button on my grid. I do some code like this:
xtype: 'button',
text: 'Add',
iconCls: "icon-grid-add",
id: 'ReqAddBtn',
handler: ReqWinAdd,
listeners: {
'click': function () {
var records = Ext.getCmp('prGrid').getStore().data.length + 1;
Ext.getCmp('prGrid').getView().focusRow(records);
}
}
i created event click like that. It works when the first click. But when the next click, the scroll is moving up.
What should i do to make scroll always still in the bottom of grid?
The preferred way is to get the grid view and scroll it:
grid.getView().scrollBy(0, 999999);
or
grid.getView().scrollBy(0, 999999, true);
if you want to animate the scroll
Finally i've got the answer.
I change my event to:
var scrollPosition = 100;
YourGrid.getEl().down('.x-grid-view').scroll('bottom', scrollPosition, true);
it makes the scroll still in the bottom of the grid. Thanks people.

ExtJS: keyboard focus specific context menu item

Currently I'm opening a context menu following the strike of a keyboard shortcut.
How do I focus on (and select/highlight) a particular menu item of the context menu? So that then the item's handler can be executed by hitting the return key. I'm running ExtJS 4.1.
This what I'm currently doing:
myMenu.showBy(divElement); // divElement is a DOM object
myMenu.items.items[2].focus(); // focus on 3rd menu item
myMenu.doConstrain(); // move floating component into a constrain region
Still, focus is maintained on the menu element itself.
A look into the source reveals that this is done using the setActiveItem() method:
var the_menu = Ext.create('Ext.menu.Menu', {
items: [
{
itemId: 'foo',
text: 'Foo'
},
{
itemId: 'bar',
text: 'Bar'
}
]
}).showBy(document.getElementById('some_div'));
the_menu.setActiveItem(the_menu.down('#bar'));
Note that this method is private, however canActivateItem(item) and deactivateActiveItem(andBlurFocusedItem) are public, so it's probably just an oversight.

Context menu within a menu item in ExtJS

I have a Menu that contains a TreePanel. The users need to be able to interact with a the TreePanel's nodes using a context menu. I'm showing the context menu from a function attached to the TreePanel's contextmenu event.
This works except:
Without allowOtherMenus: true, showing the context menu causes the main menu, and therefore the TreePanel, to disappear ;
With allowOtherMenus: true on either menu, the context menu doesn't disappear when the users clicks a blank area of the TreePanel.
I'm looking for a way to have the context menu to work as if the TreePanel were not an item within a menu.
Mockup :
I found this that seems to work on FF3/IE8/Chrome, although it could have side effects that have not shown up yet.
var hide_context_menu = function () { context_menu.hide() };
var context_menu = new Ext.menu.Menu({
allowOtherMenus: true,
items: [...],
listeners: {
show: function () {
Ext.getDoc().on('mouseup', hide_context_menu);
},
hide: function () {
Ext.getDoc().un('mouseup', hide_context_menu);
}
}
});
allowOtherMenus: true prevents the hiding of the main menu by the MenuMgr when the context menu pops up. Hiding the handler to the mouseup event allows for click events to be processed.

Why doesn't a simple click: function()... work in ExtJS?

When the user clicks on this element, I want it to show an alert.
However, when I click on the DIV that this Panel generates, nothing happens.
How can I make an alert execute when the user clicks on the following panel?
var content = new Ext.Panel({
region:'center',
margins:'5 0 5 5',
cls:'empty',
bodyStyle:'background:ivory; font-size: 13pt',
html:'<p id="test123">This is where the content goes for each selection.</p>',
click: function() {
alert('was clicked');
}
});
You haven't accepted an answer, so I'll assume you're still unclear on this. Here are a few pointers...
First, as coded your Panel will render as a plain square. If you're expecting it to look like a Panel, you should give it a title (so the title bar will render).
Second, as mentioned, click is not a Panel event (it's an Element event). So you have several ways of getting to the behavior you want. You can manually attach a listener to the underlying DOM element after the Panel is rendered:
Ext.get('txest123').on('click', function(){
alert('foo');
});
You could also do as I mentioned in the comments of another answer to generically handle any body click:
// .body is a Panel property for the body element
content.body.on('click', function(){
alert('foo');
});
If you really want to restrict the click to only the child p you could add a check:
// e is the event object, t is the target DOM node
content.body.on('click', function(e,t){
if(t.id == 'txest123'){
alert('clicked the p');
}
});
If I was coding this, I'd probably do something more like this:
var content = new Ext.Panel({
region:'center',
renderTo: document.body,
margins:'5 0 5 5',
cls:'empty',
title: 'My Panel',
id: 'txest123',
bodyStyle:'background:ivory; font-size: 13pt',
html:'This is where the content goes for each selection.',
listeners: {
'render': {
fn: function() {
this.body.on('click', this.handleClick, this);
},
scope: content,
single: true
}
},
handleClick: function(e, t){
alert(this.id); // the panel
alert(t.innerHTML); // the clicked el
}
});
Now the id is on the Panel (where it should be) and you can use Panel and/or Element methods to access child elements as needed. It's best to keep id's at the highest level possible. You'll notice too that the callback function is executed in the scope of the Panel (scope:this) so that inside handleClick you can treat this as the Panel itself and access any of its properties or methods.
So, without knowing exactly what you're trying to achieve, I can't provide you with the exact code you need. However, this should hopefully give you some ideas.
EDIT: I meant to say this originally... in your code (as posted) you are not actually rendering the Panel. As I mentioned in my answer to your related question, if you are adding the Panel as an item to a container that is lazy-rendered, the Panel's DOM won't be available for selection until after the container has rendered it. In my code above I added renderTo so that I don't have this issue, but if you're not doing that you'll have to wait until the Panel is rendered at some time later to access it.
The Panel Component does not expose a click event, so the one you're passing into the config never gets fired.
Try putting an id on your Ext.Panel object and then getting its element using Ext.get(). Then add a click event through on():
var content = new Ext.Panel({
id: 'myPanel',
region:'center',
margins:'5 0 5 5',
cls:'empty',
bodyStyle:'background:ivory; font-size: 13pt',
html:'<p id="txest123">This is where the content goes for each selection.</p>'
});
Ext.get('myPanel').on('click', function() {alert('You clicked me');});
The following sample is a bit rough but it works for me. It is a panel with a box component, which is showing a thumbnail. When clicking on the thumbnail, it is showing a lightbox with slimbox2. Not pretty, but very effective. The hardcoded images are just for test here.
var panel = new Ext.Panel({
title : 'Image',
header : false,
frame : true,
border : false,
bodyStyle : 'padding : 5px',
width : 125,
items : [{
xtype : 'box',
height : 115,
width : 115,
listeners : {
'render': function() {
var id = Ext.id(this);
Ext.fly(id).addListener('click', function () {
jQuery.slimbox('thisisnotanimage', 'CBX');
});
}
},
autoEl: {
tag : 'div',
html : 'somehtmltagstuff'
}
}
]
});
According to the API, click is not a valid event for Panels... However, you should still be able to add the click event to the underlying DIV element.
Ext.fly(e.id).addListener('click', Ext.getCmp(e.id) , this);
I believe you need something like:
var content = new Ext.Panel({
region:'center',
margins:'5 0 5 5',
cls:'empty',
bodyStyle:'background:ivory; font-size: 13pt',
html:'<p id="test123">This is where the content goes for each selection.</p>',
listeners: {
click: function() {
alert('was clicked');
}
}
});

Resources