I saw in some source code (few days ago) that a program had a dblclick event or something like that on the panel.
If you look a the docs
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.panel.Panel
under events, there are no events for clicking.
I think I saw something like
ondblclick
and then
fn: function(){...}
Why it's not in documentation and how can I fire the dblclick event on the panel?
In addition to #sra answer I would say that it is possible to assign handlers to Component's dom using element option when assigning listener:
var panel = Ext.create('Ext.panel.Panel', {
// ...
listeners: {
dblclick: function() {
// handle event
},
element: 'body'
}
});
demo
The following example will work. The double click event will get fired by the Ext.Element which can be fetched after rendering from the body param of the panel. In the example I override the afterRender method cause there is no need to register a event for that. There I register a listener to the Ext.Element of the current panel.
Ext.define('Ext.ux.panel.DCPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.dcpanel',
initComponent: function() {
this.callParent(arguments);
},
afterRender: function() {
var me = this;
me.body.on('dblclick', function() { alert('hit'); }, me);
me.callParent();
}
});
Ext.create('Ext.ux.panel.DCPanel', {
width: 300,
height: 300,
title: 'Demo',
html: 'this is my data',
renderTo: Ext.getBody()
});
Related
I have a field that is stateful, and I also have it hooked up to the change event... when its value changes, I want to perform some operation. However, because it's a stateful field, the change event fires when I go back to this view, and unfortunately, the change event fires before the ViewController's init method, which means I will not be able to access my reference lookup.
In the following example, run it, change the date, and then re-run the application... you'll see a console.log that appears for the change, and then for the init. I realize I could set up the handler in the init method, but that just seems silly. I also realize I could create myField as a private var and access it that way, but that also seems silly. And yes, I could change to the select event, but that's not what I want to do. Anyone have any thoughts? Here's an example:
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myView',
init: function() {
console.log('init fired', this.lookupReference('myField'))
},
onChange: function(value) {
console.log('onChange fired', this.lookupReference('myField'));
}
});
Ext.define('MyView', {
extend: 'Ext.container.Container',
controller: 'myView',
renderTo: Ext.getBody(),
items: [{
xtype: 'datefield',
value: new Date(),
stateful: true,
stateId: 'blahblah',
listeners:{
change: 'onChange'
}
}, {
xtype: 'datefield',
value: new Date(),
reference: 'myField'
}]
});
Ext.create('MyView');
}
});
This is because the state mixin is initialized before the controller, this is code taken directly from Ext.Component's constructor:
me.mixins.state.constructor.call(me);
me.addStateEvents('resize');
controller = me.getController();
if (controller) {
controller.init(me);
}
There is no config to change this behavior. Honestly, I've never seen someone make a form field's value stateful.
You can use the buffer config to delay event firing.
This has an advantage of setting up the event after the controller is initialised.
The solution:
listeners: {
change: {
buffer: 300,
fn: 'onChange'
}
}
An Alternative is to handle 'beforestaterestore` event of the stateful field and apply the state value only after controller is initialised.
listeners: {
beforestaterestore: function (field, state){
var controller = field.up().getController();
Ext.Function.interceptAfter(controller, 'init', function(){
field.setValue(state.value); // update
},this);
return false;
}
}
I'm in the need to listen to a enable/disable event on a container and I've noticed that there's no such event. I tried to listen to it in case it wasn't mentioned in the docs but it definitely doesn't exist.
I google'd around a little and found this..
Ext.define('My.Custom.Container',{
extend:'Ext.Container',
onEnable:function(){
console.log("it's listening");
}
});
It looked promising but it didn't work at all.
Is there any way to listen to these events? I don't want to get jQuery mixed in here as it would be an overkill.
The container xtype from which many components inherit methods does have an event which fires on changing of it's disabled state. This event is called disabledchange and fires every time the container is either enabled/disabled.
In the below code we can see this in action working on a button purely as it gives a visually better demo (since you can immediately see the state) but it inherits the exact same method and event from Container.
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.Viewport.add({
xtype: 'container',
padding: 10,
items: [{
xtype: 'button',
text: 'Button To be disabled/enabled',
listeners: {
disabledchange: function(button, value, oldValue, eOpts) {
console.log('changing my disabled state to ' + value);
}
}
}, {
xtype: 'button',
text: 'click to disable/enable above button',
listeners: {
tap: function() {
var isButtonDisabled = Ext.Viewport.query('button')[0].getDisabled();
Ext.Viewport.query('button')[0].setDisabled(!isButtonDisabled);
}
}
}]
});
}
});
Demo: https://fiddle.sencha.com/#fiddle/g46
Ok, I just found an answer to my question.
Ext.define('My.custom.Container',{
extend:'Ext.Container',
config:{
....config....
},
enable: function(){
this.callParent(arguments);
// do something else;
},
disable: function(){
this.callParent(arguments);
// do something else;
}
});
I'm still curious if there's another way around this though. So answers are still welcome.
I'm trying to create a dialog window in ExtJS to perform a save function, but I'm getting problems loading the page.
A (reduced) example of the code window definition is:
Ext.define('MyRequest.SaveDraftOrTemplateWindow', {
extend: 'Ext.window.Window',
alias: 'widget.saveDraftOrTemplateWindow',
requires: ['Ext.toolbar.Toolbar'],
modal: true,
initComponent: function() {
this.items = [ saveDraftOrTemplateForm ];
Ext.apply(this, {
dockedItems: [{
xtype: 'toolbar',
items: [
{
iconCls: 'saveas-draft',
text: '<b>Save</b>',
id: 'saveDraftTemplate',
handler: saveAsDraftRequest(textFieldDraftOrTemplateName.getValue(), checkBoxSaveAsTemplate.getValue()),
scope: this
}
]
}]
});
this.callParent();
}
});
function saveAsDraftRequest(draftName, isTemplate) {
Ext.getBody().mask('Saving draft request...'); // Errors actually occurs on this line
}
// This line is the start of the stack causing the problem...
var saveDraftOrTemplateWindowInstance = Ext.create('MyRequest.SaveDraftOrTemplateWindow', {
Id: 'saveDraftOrTemplateWindow',
xtype: 'saveDraftOrTemplateWindow',
width: 400,
height: 180,
bodyPadding: 0
});
The problem is that is seems to be 'calling' the saveAsDraftRequest() function when the page initially loads which gives the Javascript error "Uncaught TypeError: Cannot read property 'mask' of null", and prevents the page loading. I don't really understand why the function is getting called at this point, as the handler presumably shouldn't be called until the button is actually clicked.
I assume that if the page were already correctly loaded then Ext.getBody() would correctly return a result instead of null, but why is this getting called during the initial page load?
You are invoking saveAsDraftRequest function in initComponent in line:
handler: saveAsDraftRequest(textFieldDraftOrTemplateName.getValue(), checkBoxSaveAsTemplate.getValue())
You should change it to
handler: saveAsDraftRequest
Then you need resolve draftName and isTemplate in handler. You can for example assign them to button:
handler: saveAsDraftRequest,
draftName: textFieldDraftOrTemplateName.getValue(),
isTemplate: checkBoxSaveAsTemplate.getValue()
Then you can access them in handler like so:
function saveAsDraftRequest(sender) {
console.log(sender.draftName);
console.log(sender.isTemplate);
}
Ah, #Lolo has given me the hint I need - I see now that the initialisation code was invoking the function to get the handler to use - what I could have done is:
handler: function() {
saveAsDraftRequest(textFieldDraftOrTemplateName.getValue(), checkBoxSaveAsTemplate.getValue());
},
... if I wanted to invoke it there.
I have this piece of code :
listeners:
{
beforerender: function()
{
if (importButton == true)
{
this.menu.add(
{
text: 'Import',
iconCls: 'importIcon',
listeners:
{
click: new ifAuthorizing('import')
}
})
}
this.menu.add(
{
text: 'Consultation',
iconCls: 'searchIcon',
listeners:
{
click: menuConsultation
}
})
}
}
that is supposed to add items to a menu when some conditions are OK.
It's working, the button are well added if the conditions matches.
The problem is coming from the
listeners:
{
click: new ifAuthorizing('import')
}
This listener is supposed to be appended to the menu item, but it is triggered during the beforerender event of its parent.
function ifAuthorizing(arg) {
console.log('import')
}
The 'import' is displayed in the console logs during the beforerender event, and then if I click on the menu item that is supposed to have a click method, nothing happens.
I would like to know why.
new ifAuthorizing('import')
Here operator new tries to create an object and interpretes ifAuthorizing as a constructor. The constructor is called immediately, that's why it fires on beforeRender event. As a result you get some object which is not a copy of function ifAuthorizing, so it can't be called on menu item's event with the desired result.
I have trivial window:
this.window = Ext.widget('window', {
title: 'Find',
closeAction: 'hide',
width: 300,
layout: 'fit',
items: form
});
with trivial form in it
var form = Ext.widget('form', {
layout: {
type: 'vbox',
align: 'stretch'
},
border: false,
bodyPadding: 10,
items: [
this.findInput,
]
});
which only has one item
this.findInput = Ext.widget('textfield', {
name: 'find'
});
The issue is: how to set focus right after window is shown? I tried to call .focus() method of this.findInput in almost every window event handler with no luck.
Seems like even afterrender is called synchronously before DOM has created all the elements completely.
What have I missed? What event should I bind to to have all the elements rendered and able to accept the focus?
PS: if I call the same .focus() after small interval like 10ms - I get it focused, but it's not a solution
Check out activeItem property - http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.Panel-cfg-activeItem
or you can also use defaultFocus: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.window.Window-cfg-defaultFocus