the singularity of being and nothingness
ExtJS 4.2 Walkthrough — Post-Upgrade Bug
In the last installment, we took a few moments to upgrade our app from ExtJS 4.2.0 to ExtJS 4.2.1. As I pointed out, upgrading is not an insignificant decision, as you will have to test and verify that your app continues to work as expected.
Well, in preparing the next several sections, I came across a bug in 4.2.1 that harms a bit of the functionality I was wanting to implement. While these bugs are a natural (albeit frustrating) part of software evolution, ExtJS is fortunately extensible enough that we can easily create a custom patch (or override) that will allow our code to work as expected WITHOUT modifying the core framework. The benefit of this approach, of course, is that we future-proof our code against new versions. So then, when the new version comes out, we can remove our custom patch and see if the issue is resolved in the core. If it’s not, we can simply re-enable our patch, submit another bug ticket :), and continue on.
Tips for Dealing with Bugs
Before we fix this bug, let me offer a couple suggestions to mentally dealing with bugs in ExtJS:
- Acceptance: The first step to healthily dealing with bugs in ExtJS is to recognize that no matter how much the devs test the framework, THERE WILL BE BUGS. Not only will there be bugs in the core, but there will also be bugs in how you’ve implemented your app on top of the framework. The sooner you accept this, the sooner you’ll have peace.
- Verification: Sometimes “bugs” are really just improper use of the framework (as it’s currently designed), such as bad configuration, missing configuration, etc. Before you rage, post your troubles in the forums. There are tons of bright people constantly helping other ExtJS devs with their issues. If the “bug” is simply misuse, they’ll help you figure out the right way to do what you’re trying to do. And if it is truly a bug, they’ll help confirm it. Getting mad in a vacuum will not help you, nor will it help the framework get better.
- Report: Obviously, the bug can’t be fixed if the ExtJS team doesn’t know about. So once you’ve verified the bug, report it in the forum. Of course, before you do, you should do your due diligence and compile as much relevant information (ExtJS version, test cases, online examples, etc. per the guidelines). Simply posting “there’s a bug in X” is not only obnoxious, but extremely unhelpful. A nice side-benefit of a robust bug report is that you’ll often be rewarded with a suggested patch…bonus!
- Fix: Given the size of the framework, it’s easy to feel hopeless in the face of a bug; after all, there are hundreds and hundreds of files, lots of interconnectedness, etc. While all of this is true, ExtJS is fundamentally JUST JAVASCRIPT. Do not be afraid of the source code. If you spend a few minutes tracing the path of your bug, it’s very likely that you’ll either see the obvious reason for the bug, or you’ll see something related to it that will help with your bug report. And if you do find the exact reason for the bug, you can 1.) patch it yourself for your app (which we’ll do below) and 2.) provide the suggested fix in your bug report. While my evidence is only anecdotal, bugs that are robustly reported AND have suggested fixes submitted with them are probably more likely to make the next release than the vague “this doesn’t work” bug reports.
- Document: IF you have to patch, hopefully it’s a small, single change. However, if you have multiple patches that need to be made, be sure to thoughtfully document your changes for your own sanity. With each new release, the hope is that your patches can be removed; however, if your patches are badly organized, you might forget about where they are, how they’re integrated, etc. and then they’ll hang around forever, potentially introducing more issues down the line.
- Appreciate: There’s no way around it: encountering bugs in the ExtJS sucks, and patching the bugs sucks. If you deal with particularly pernicious ones, it’s extremely easy to allow the experience of fixing the bug sour your perspective of ExtJS, your app, and development in general. However, once you’ve gotten past the momentary pain of this, try to step back from the weeds of debugging and remember the benefits that ExtJS brings to your apps.
The Bug
The bug I found is in Ext.grid.RowEditor and has been classified as EXTJSIV-9957. In a nutshell, the bug is that listeners which were applied to editor fields in 4.2.0 are no longer applied in 4.2.1. So, if you have a “required” editor field, the RowEditor will automatically disable the commit button until the “required” validation for the field is satisfied. However, in 4.2.1, the change event of the field doesn’t fire, so the RowEditor is never informed of the “required” validation being fulfilled.
You can see this bug in action in this fiddle.
The Fix
As a workaround, the easy fix is to simply poach the listener from the 4.2.0 source and re-add it to 4.2.1. But we really don’t want to edit the source, since we don’t want to introduce changes into core that will be bombed in future versions. Therefore, our best bet is to create an override.
If you remember from our initial setup, generating an app with Sencha Cmd automatically created an overrides folder at the root of our app (e.g., cartracker/overrides). This is a perfect place to put our overrides. When creating overrides, I like to maintain, through packages, the path of the class being overridden. Therefore, since we’re overriding Ext.grid.RowEditor, let’s first create a grid folder under override, and then a new file called RowEditor.js.
NOTE: Obviously, this isn’t necessary…you can structure your overrides however you want. However, if you end up having a lot, it’s much easier to find them later on if they mimic the natural class path within ExtJS.
You can also put your overrides in different locations if you’d like. For example, if your override needs to be used across multiple applications that live in different folders, you might want to create a global repository for overrides that all apps can use.
Here’s what our RowEditor override will look like:
/** * Override for {@link Ext.grid.RowEditor}. Fixes lack of change event on editor fields */ Ext.define('overrides.grid.RowEditor', { override: 'Ext.grid.RowEditor', addFieldsForColumn: function(column, initial) { var me = this, i, length, field; if (Ext.isArray(column)) { for (i = 0, length = column.length; i < length; i++) { me.addFieldsForColumn(column[i], initial); } return; } if (column.getEditor) { // Get a default display field if necessary field = column.getEditor(null, { xtype: 'displayfield', // Override Field's implementation so that the default display fields will not return values. This is done because // the display field will pick up column renderers from the grid. getModelData: function() { return null; } }); // BEGIN OVERRIDE me.mon( field, 'change', me.onFieldChange, me ); // END OVERRIDE if (column.align === 'right') { field.fieldStyle = 'text-align:right'; } if (column.xtype === 'actioncolumn') { field.fieldCls += ' ' + Ext.baseCSSPrefix + 'form-action-col-field' } if (me.isVisible() && me.context) { if (field.is('displayfield')) { me.renderColumnData(field, me.context.record, column); } else { field.suspendEvents(); field.setValue(me.context.record.get(column.dataIndex)); field.resumeEvents(); } } if (column.hidden) { me.onColumnHide(column); } else if (column.rendered && !initial) { // Setting after initial render me.onColumnShow(column); } } } });
As you can see, we use Ext.define(…) to create our custom override class, but then use the special override config to let ExtJS know which class we’d like to override. With this set up, all we now have to do is override the method in which the bug is occurring. Pretty simple.
NOTE: You can override multiple methods and even configs. In this case, we only had to override a single method.
Now that we have a custom override, the last thing we need to do is let our app know about it. To do this, let’s open up app.js and modify our requires[] config like so:
requires: [ 'Ext.util.History', ... 'overrides.grid.RowEditor' ],
…and voila, it now works again.
Conclusion
While the introduction of new bugs is an unfortunate side-effect of upgrading, ExtJS is thankfully extensible enough to allow us to easily implement custom patches that will allow our development to move forward without having to wait for a new release to core.
Print article | This entry was posted by existdissolve on May 27, 2013 at 10:03 am, and is filed under ExtJS, ExtJS 4.2. App Walkthrough, Uncategorized. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |
about 11 years ago
Hello i begin develloping with extjs 4.2.1 i want to ask if i must ‘overrides.grid.RowEditor’
Ty
about 11 years ago
Hi karim–
You don’t have to use it, but the reason I did is because there was a bug in the version of the framework that I was using. The override was a fix for it until the resolution is added to the core.
about 10 years ago
Thank you so much for your detailed report and solution! In addition to resolving my RowEditor issue, it taught me about overrides, as I’m just beginning to use ExtJS. Just wanted you to know that the time you spent writing this is still paying off.
about 10 years ago
Awesome, glad it’s helpful! I’m considering re-writing it again for Ext JS 5, so stay tuned!
about 10 years ago
please help, extjs5 finds it difficult to recognise web root in IDE (Integrated Development Environment such as netbeans, eclipse) environment.
about 10 years ago
Hi Mfon–
I’m not sure where to start with your question. Ext JS is simply a JavaScript framework…in terms of configuring it to work on your web server, you have to configure that yourself in terms of where you place the library, virtual directories that you create, etc. Wish I could help more–can you provide more information about your issue?