Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / XHTML

Simple Component Inheritance in ExtJS

2.33/5 (2 votes)
20 May 2008CPOL3 min read 1   223  
How to create an ExtJS component to render arbitrary HTML.

demo.gif

Introduction

ExtJS is a really cool JavaScript library that contains great form building components. But, like all things, you start using it in anger, and it isn't long before you find something it can't do out-of-the-box and you want to extend it.

I had a form made up of standard Ext.form components, but then I wanted to output a couple of DIVs amongst the other form elements so that I could render some special content to them. Specifically, I had a report that is broken into sections and each can have files attached to it. I wanted to display a button to bring up a file upload dialog and a list of uploaded files. For interest, the file upload dialog I used can be found here - it is seriously good!

So, it was that I needed to develop an extension to the Ext.component class that could render out my divs. This is quite simple, but it took a fair bit of investigation and hunting through the source to find out what was required, so I thought I should create a little demo component and put an article here to save others some time.

If you are looking to specialise an existing component, there is a great example here.

Using the code

Basically, you need three things to make it work (you may even need less, but I implemented these three and then I was happy): initComponent, onRender, and afterRender. Basically, I started from the Ext.Button class and figured out how it worked, and then applied the chainsaw.

Note the first line that registers a namespace and the last line that registers the control with a unique xtype that can be used to identify it with ExtJS.

All the good stuff happens in onRender(). I create a template that is used to render HTML containing the configuration strings text1 and text2. Then, render this content using the insertBefore() or append() function (depending on whether a position for the element has been supplied). These functions perform the replacements in the template string from the argument targs.

JavaScript
Ext.namespace('Ext.ensigma');

Ext.ensigma.DemoComponent = Ext.extend(Ext.Component, {
    initComponent : function(){
        Ext.ensigma.DemoComponent.superclass.initComponent.call(this);
    },

    // private
    onRender : function(ct, position){
        if(!this.template){
            if(!Ext.ensigma.DemoComponent.filesetTemplate){
                Ext.ensigma.DemoComponent.filesetTemplate = new Ext.Template(
                    '<div><div>{0}</div><div>{1}</div></div>'
        );
            }
            this.template = Ext.ensigma.DemoComponent.filesetTemplate;
        }
        var fs, targs = [this.text1 || '&#160;', this.text2 || '&#160;'];

        if(position){
            fs = this.template.insertBefore(position, targs, true);
        }else{
            fs = this.template.append(ct, targs, true);
        }
        this.el = fs;
     }

    // private
    afterRender : function(){
        Ext.ensigma.DemoComponent.superclass.afterRender.call(this);
    }
});
Ext.reg('fileset', Ext.ensigma.DemoComponent);

Here is the example code that uses the component:

JavaScript
Ext.onReady(function(){
    Ext.QuickTips.init();

    var simple = new Ext.FormPanel({
        labelWidth: 75, 
        frame:true,
        title: 'Fileset Form',
        bodyStyle:'padding:5px 5px 0',
        width: 350,
        defaults: {width: 230},
        defaultType: 'textfield',

        items: [new Ext.form.TextField ({
                fieldLabel: 'First Name',
                name: 'first',
                allowBlank:false
        }), new Ext.ensigma.DemoComponent ({
        text1: 'hello world',
        text2: 'goodbye cruel world',
        autoWidth: true
    })
        ]
    });

    simple.render(document.body);
});

Tips

Care should be taken never to have trailing commas at the end of lists; for example, [1,2,3] should never be coded like [1,2,3,]. In Firefox (as in C), the [1,2,3,] is a three item list; in IE, it is a four item list where the final item is undefined. The extra list item results in errors in IE, and sometimes even shows a blank document with no error message. Depending on where you have the trailing comma, any of the following messages may be displayed:

  • Error: 'events' is null or not an object
  • Error: Expected identifier string or number
  • Error: 'undefined' is null or not an object

History

  • 12-May-2008
    • Added the this.el = fs line to onRender(...). This is required in some instances to keep IE happy and/or when the component is included in a container.
    • Added note on trailing commas and resulting error messages.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)