ExtJS’s Grid Clipboard plugin is borked by design

I’ve been meaning to write this for nearly a year, but I held off hoping things would change with the next release. They didn’t, so I’m writing this: the Clipboard plugin for the Ext.grid.Panel class – which provides cut-and-paste support for the enhanced table widget – is borked by design. It does stupid things, and Sencha says it should do the stupid things. In this post I share what these things are, and how I’ve overriden the default behaviour to do something hopefully less stupid. Warning: this is a rant.

Continue reading “ExtJS’s Grid Clipboard plugin is borked by design”

Upgrading to ExtJS 6.2

Sencha recently announced the general availability of ExtJS 6.2. People who regularly read my posts (hi, to all three of you. 😉 will be aware that I’ve been working with the ExtJS library for a number of years now, while building a suite of apps of some not inconsiderable size1. It’s probably not the largest ExtJS app in the world, but it’s up there. And when you work on an application for a number of years, you’ll need to upgrade its framework from time to time.

Every time I’ve done this, the process has been a bit different. This time, it’s different in a good way – it was easy.

Continue reading “Upgrading to ExtJS 6.2”

Logarithmic Axes for ExtJS Charts

ExtJS includes a number of nice charting options. I mean, it’s no HighCharts or D3, but it’s not bad. But – it can’t do a logarithmic axis.

A logarithmic axis is useful for displaying data with a large range of values. Sometimes these values are already on a log scale – e.g. the Richter scale is a log scale, as is decibels. You can plot this on a normal linear numeric axis. But sometimes your values can’t be easily converted to a log scale. Maybe you’re plotting wealth distribution. Or, in my case, particle size distributions, where the sizes can range from metres down to microns. When dealing with something like this, you need a log axis.

Continue reading “Logarithmic Axes for ExtJS Charts”

Fashionable ExtJS and Web Services

ExtJS 6 was released at the end of June, and one of the nicest new features in it is a change to their CSS tooling – they’ve replaced Compass with a JavaScript-based implementation of SASS called Fashion. One of the neatest features is “Live Update” – this takes the traditional ‘watch’ approach one step further, and instead of just rebuilding your CSS when you change a SCSS source file, it updates the CSS inside the running browser, without needing a page refresh! This is just awesome, and not something I’ve seen before in my (admittedly limited) experience with web development tools.

But there’s just one problem… you have to use the embedded web server started with the sencha app watch command. Which is fine if all you’ve got is a webpage, but if you’re dealing with web services (as so many web apps do), it’s a bit restricting – at least if you don’t want to configure your app or server to allow cross-site scripting.

But Live Update is too awesome to forego! What to do?

Continue reading “Fashionable ExtJS and Web Services”

Upgrading ExtJS – issues with templates

Quick _aide-mémoire_ so that I don’t forget. When upgrading from ExtJS 4 to ExtJS 5, if you’ve got any components that use a custom template, and expect `childEls` to be configured correctly, you need to add a `data-ref` to the generated HTML.

Quick aide-mémoire so that I don’t forget. When upgrading from ExtJS 4 to ExtJS 5, if you’ve got any components that use a custom template, and expect childEls to be configured correctly, you need to add a data-ref to the generated HTML.

Continue reading “Upgrading ExtJS – issues with templates”

Giving the ‘hasOne’ association some love

One of the really nice features of ExtJS, to my mind anyway, is the rich model architecture, and how models can be associated with each other. However, the quality can be a bit erratic – certainly, it appears that the HasOne association (which allows a one-to-one relationship) could use some loving, as it isn’t as well developed as the more commonly-used HasMany

Continue reading “Giving the ‘hasOne’ association some love”

Reading Associative Arrays with ExtJS Models

Wow, it’s been a while since I posted something…

I’ve been working a lot with ExtJs recently, as the basis for a web application which talks to a lot of JSON-based web services. And I got to say that I am enjoying it – it’s a nice, powerful framework that makes working with JavaScript quite bearable.

ExtJs includes a sub-framework for turning JSON (or XML) data into ‘models’, including nested data. It does this by providing ‘reader‘ classes that understand JSON (or XML). However, it only understands nested arrays. Sometimes what you have is a nested object – e.g. when you serialize a HashMap from Java into JSON. Fortunately, it’s possible to extend ExtJS and provide a new Reader – one that understands nested objects (aka ‘maps’, or ‘hashes’, or ‘associative arrays’).


/**
* A variant of the JSON reader. Instead of reading arrays, where each record in the array field
* has an 'id' property, it reads objects – aka associative arrays. The key of the entry will be the
* array.
*
* So where the JSON reader would like data like this:
* [ { id: '1', property: 'foo' }, { id: '2', property: 'bar' } ]
*
* the associative reader likes data like this:
* { '1': { property: 'foo' }, '2': { property: 'bar' } }
*/
Ext.define('Twasink.data.AssociativeReader', {
extend: 'Ext.data.reader.Json',
alias: 'reader.associative',
readRecords: function(data) {
// convert the associative array into a normal array.
var idProperty = 'id'; // should be a config value?
var arrayData = []
Ext.Object.each(data, function(key, value) {
var arrayEntry = {};
Ext.Object.merge(arrayEntry, value);
arrayEntry[idProperty] = key;
arrayData.push(arrayEntry);
});
return this.callParent( [ arrayData ]);
}
})


Ext.define('Twasink.model.Bar', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [ 'baz', 'bux']
})

view raw

Bar.js

hosted with ❤ by GitHub


[
{ "id": "foo_1", "baz": "baz_1", "bux": "bux_1", "bar": {
"bar_1": { "baz": "bar_baz_1", "bux": "bar_bux_1" },
"bar_2": { "baz": "bar_baz_2", "bux": "bar_bux_2" }
}
},
{ "id": "foo_2", "baz": "baz_2", "bux": "bux_2", "bar": {
"bar_1": { "baz": "bar_baz_3", "bux": "bar_bux_3" },
"bar_2": { "baz": "bar_baz_4", "bux": "bar_bux_4" }
}
}
]


Ext.define('Twasink.model.Foo', {
extend: 'Ext.data.Model',
requires: [ 'Twasink.data.AssociativeReader', 'Twasink.model.Bar' ],
idProperty: 'id',
fields: [ 'baz', 'bux'],
hasMany: [ { model: 'Twasink.model.Bar', name: 'bars', associationKey: 'bar', reader: 'associative' }]
})

view raw

Foo.js

hosted with ❤ by GitHub

If you’re using ExtJS, I hope you find this useful.

%d bloggers like this: