I'd like a single event listener that fires whenever any field in a form (i.e., Ext.form.Panel) changes. The Ext.form.Panel class doesn't fire an event for this itself, however.
What's the best way to listen for 'change' events for all fields in a form?
xType defines the type of Ext JS UI component, which is determined during rendering of the component. For example, the element can be a textbox for which we have xType as textField or the element can have a numeric value only for which we have Numeric xType.
The itemid global attribute provides microdata in the form of a unique, global identifier of an item. An itemid attribute can only be specified for an element that has both itemscope and itemtype attributes.
When you use an id for a component, there must be a single instance of this component, If you create another instance that has the same id, you will have problems as the DOM is confused. when you use itemId, it should be unique only within the component's immediate container.
getCmp. will return you an item matching the id you passed it. This will be the fastest method to return an item. All items when created with an id are registered in a single object using their id as a key.
Update: Added a 3rd option based on tip in comments (thanks @innerJL!)
Ok, looks like there are at least two fairly simple ways to do it.
Option 1) Add a 'change' listener to each field that is added to the form:
Ext.define('myapp.MyFormPanel', {
extend: 'Ext.form.Panel',
alias: 'myapp.MyFormPanel',
...
handleFieldChanged: function() {
// Do something
},
listeners: {
add: function(me, component, index) {
if( component.isFormField ) {
component.on('change', me.handleFieldChanged, me);
}
}
}
});
This has at least one big drawback; if you "wrap" some fields in other containers and then add those containers to the form, it won't recognize the nested fields. In other words, it doesn't do a "deep" search through the component to see if it contains form field that need 'change' listeners.
Option 2) Use a component query to listen to all 'change' events fired from fields in a container.
Ext.define('myapp.MyController', {
extend: 'Ext.app.Controller',
...
init: function(application) {
me.control({
'[xtype="myapp.MyFormPanel"] field': {
change: function() {
// Do something
}
}
});
}
});
Option 3) Listen for the 'dirtychange' fired from the form panel's underlying 'basic' form (Ext.form.Basic). Important: You need to make sure you must enable 'trackResetOnLoad' by ensuring that {trackResetOnLoad:true} is passed to your form panel constructor.
Ext.define('myapp.MyFormPanel', {
extend: 'Ext.form.Panel',
alias: 'myapp.MyFormPanel',
constructor: function(config) {
config = config || {};
config.trackResetOnLoad = true;
me.callParent([config]);
me.getForm().on('dirtychange', function(form, isDirty) {
if( isDirty ) {
// Unsaved changes exist
}
else {
// NO unsaved changes exist
}
});
}
});
This approach is the "smartest"; it allows you to know when the form has been modified, but also if the user modifies it back to it's original state. For example, if they change a text field from "Foo" to "Bar", the 'dirtychange' event will fire with 'true' for the isDirty param. But if the user then changes the field back to "Foo", the 'dirtychange' event will fire again and isDirty will be false.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With