UX - CTemplate

Skirtle.CTemplate is an extension of Ext.XTemplate that allows ExtJS components to be used as template values. Originally written as a support class for Component Column it has been generalized far beyond the requirements of that particular use-case.

Download

VersionDate
1.228-Oct-2020Download
1.107-May-2013Download
1.022-Sep-2011Download

View release notes.

Examples

A simple example that just renders a button and some text.

            var template = Ext.create('Skirtle.CTemplate',
                '<div>',
                    '{label} {button}',
                '</div>'
            );

            template.overwrite(Ext.fly(...), {
                label: 'Thomas',

                button: Ext.create('Ext.button.Button', {
                    text: 'Edit'
                })
            });
        

This example is a little more complicated. It renders a multi-select combobox into the header of a grid to act as a local filter.

            var store = Ext.create('Ext.data.ArrayStore', {
                fields: ['name', 'shape', 'age'],

                data: [
                    ['Tom', 'Triangle', 1],
                    ...
                ]
            });

            var combo = Ext.create('Ext.form.field.ComboBox', {
                ...
                multiSelect: true,

                listeners: {
                    change: function(combo, value) {
                        store.clearFilter();

                        if (value.length) {
                            store.filterBy(function(record) {
                                return Ext.Array.contains(value, record.get('shape'));
                            }, value);
                        }
                    }
                }
            });

            Ext.create('Ext.grid.Panel', {
                ...
                store: store,

                columns: [
                    {...},
                    {
                        ...
                        dataIndex: 'shape',
                        menuText: 'Shape',
                        renderTpl: Ext.create('Skirtle.CTemplate', Ext.grid.column.Column.prototype.renderTpl),
                        text: combo,

                        listeners: {
                            destroy: function() {
                                combo.destroy();
                            },

                            resize: function(col, width) {
                                combo.setWidth(width - 14);
                            }
                        }
                    },
                    {...}
                ]
            });
        

Compatibility

Version 1.2 of CTemplate is very similar to version 1.1 and should be compatible with any version of ExtJS from version 4 onwards. The most recent version of ExtJS tested is 7.3.0.

Version 1.1 was tested against ExtJS versions:

  • 4.0.7
  • 4.1.1
  • 4.2.0

Browsers tested (version 1.1):

  • Internet Explorer 6
  • Internet Explorer 7
  • Internet Explorer 8
  • Internet Explorer 9
  • Internet Explorer 10 (using ExtJS 4.2.0)
  • Firefox 20
  • Safari 6.0.1
  • Chrome 26
  • Opera 12.15

How It Works

XTemplates are fundamentally an HTML templating mechanism. As an ExtJS component is much more than just its HTML it isn't possible to inject an ExtJS component directly into a template.

Instead, CTemplates pull a sleight-of-hand on the values passed to the template to substitute all of the components with some placeholder HTML. The HTML returned by the apply method will contain this placeholder rather than the actual component.

At some point the CTemplate needs to pull the reverse switch, removing the placeholder from the DOM and rendering the component in its place. This poses a problem as it could happen some time later or may never happen at all. A number of techniques are used to try to overcome this.

  • XTemplate methods such as overwrite and insertFirst add the HTML to an existing element. These methods are overridden so that if that element is already in the DOM then the component substitution is performed immediately.
  • The method injectComponents can be called manually to perform the substitution. This needs the code using the template to be CTemplate-aware, which may not be an option if it is already written such as the code in the ExtJS library itself.
  • Internally the CTemplate will poll on a timer to try to perform the switch. In most cases the HTML returned by a template is used immediately so the substitution will occur on the first poll. However in some cases this may already be too late and sizing issues may occur.

To be able to perform the substitutions the template must keep track of the components it has seen. Only the id of each component is stored and it is discarded if the component is successfully injected or destroyed. The list of ids can be emptied manually by calling reset.

CTemplate must be passed instantiated components, it will not create a component if it is passed a config object with an xtype. Nor does it manage component destruction. Components must be instantiated and destroyed externally.

Bugs

Feedback, bugs and feature requests should be submitted via GitHub issues at https://github.com/skirtles-code/extjs-component-column.

For discussion of older issues see the relevant forum page.

License

MIT.

Prior to version 1.2, this project used a bespoke license. You may continue using that license if you prefer.