GXT 2 did support widgets in Grids, but it came at a very high performance cost, and based in part on that cost (and in part on the GWT Cell API) we decided to remove that feature when we created GXT 3.
The map is probably the right way forward - invoking that attach code will ensure that you get all the wiring you need to get events, as you noted. You'll want to be sure to invoke that detach in all browsers - while I haven't read all of your code, I do note that this apparently will only work in IE9+. In those browsers, the memory leak being avoided is less of an issue, so this might mean that your app will leak in earlier browsers.
The idea of a Cell is that it is a faster API for building objects (via String manipulations and setting the innerHTML property directly instead of element maneuvering), and minimizes the number of event handlers that need to be wired up. Starting with your getElement().toString() (be very sure this works in all browsers! I think it may be broken in either Chrome or Firefox, at least in GWT 2.4), you do become more expensive in drawing, but if you can handle the events without attaching the code, it may still be worth it. My basic idea there would be to just keep a single instance of the widget to make drawing easy, then modify and toString() it for each row in the grid.
Then, in onBrowserEvent, figure out what event had happened in what part of the current field, and respond. Without knowing your specific case, I couldn't go into much more depth on events though - but again you might be able to use the same instance over and over, invoking highlight methods programatically, etc.
One more thought on memory leaks and detach - consider just a detach handler on the whole grid, and detach all widgets at the same time. Similiarly, detach any element with an item is removed from the store, etc. But unless you foresee the need to use this generalized approach many times, I'd strongly encourage you to solve it more specifically with specialized cells.
I agree, the code i put up is for IE9+ browsers only based on the detach event used, which is a requirement i'm lucky enough to have. However, I like the idea of basing the detachment on the grid itself better.. that is a lot cleaner.
Even better though, the idea of never attaching the widget sounds like the best approach, and could really clean up this class. For my purposes, i need to display the widget in the cell but i only need to react to events on the cell itself after that (like 'click'). But for actual widget events, passing any events through via the cell's onBrowserEvent is a better idea (https://developers.google.com/web-to...onBrowserEvent)
Nice post - though your syntax highligher seems to have gone a bit crazy though in the render method.
I'd add further cautions to the post/javadocs that this does *not* respect the widget lifecycle - no attach/detach, and manipulating dom elements (say in a Timer like AutoProgressBar does) will have zero effect. Note that this doesn't mean it is impossible to achieve such an effect - AutoProgressBarCell is able to do its thing without wrapping a widget.
One last remark, having only read the code briefly - it appears you are setting the ID of some elements to the context.getKey(). This key is *only* guaranteed to be unique across all cases where that particular cell is rendered in that particular cell widget - if you make two of these cells in the same Grid, for example, you will end up with two elements with each ID in each row, and they may not behave correctly as a result. The DOM is only allowed to have one element per ID, so consider prefixing those keys with something widget/column specific, or using autogenerated IDs from XDOM.getUniqueID(). Or, set class names instead, and use your querySelector call to find based on class instead.
I double-checked the element ID comment you mentioned in my implementation, and I believe it is handled because:
The ID of the placeholder elements are not set to context.getObject(), they are set to a unique value that is in a static field and incremented each time it is used. The XDOM call you mention would be a better value though, so i'll incorporate that.
There is one instance of the WidgetCell per column, and the cache maps are local to that instance -- so using context.getObject() in those local cache maps (as the key) always will correctly reference the intended row relative to that column only.
The context.getObject() is used as the key for storing the reusable fields and placeholder Ids in cache maps local to a column's instance of the WidgetCell.
I am using that exact situation where i have two widgetCells per row, so i took a second look to confirm this. Thank's for catching that possibility.
Also, i updated the post per your other comments. no idea what's up with my syntax highlighter..