Nov 12 2008

extjs ComboBox remote XML

Category: Rubyetd @ 1:33 am

The new release of dradis is going to use the ExtJS library for the web interface. ExtJS provides lots of JavaScript widgets useful to create complex GUI for web applications.

This is the first of a series of posts with small tips and tricks of ExtJS that will also address its integration with Ruby on Rails.

In this release we are going to create a ComboBox that loads its items from a remote location (potentially a rails REST endpoint).

I wanted to create this series when I started using ExtJS so it could be used as a step-by-step howto of ExtJS and rails, but as sometimes happens, I got carried away with the coding side of things leaving the post writing abandoned :( . That is the main reason why some core concepts of ExtJS development are not included here. The project site, documentation and samples can help with that. Here we are dealing with the real stuff, so lets get it on.

First the code: extjs-comboxml.tar.bz2. I have a local apache for debuging purposes and I uncompressed the ExtJS package in /var/www/ext-2.2/, then I created a test folder inside it. This code should work fine if you uncompress its contents in the test folder. If you have a different environment, adjust the locations of the script tags in the header of combo.html.

This is how it should look like:

So with ExtJS there are two ways of loading combo items from a remote location, it is a bit confusing because these two are called local and remote modes. The difference is that in local mode, the combo is relying on someone else to grab the information and in remote mode the combo itself will make the Ajax call.

No matter what mode we choose, we will need a data store for our items. Here is the code used in the example:

var categories = new Ext.data.Store({
        url: 'categories.xml',
        autoLoad: true, // required for the combo that does not use Ajax
        reader: new Ext.data.XmlReader(
                { record: 'category', id: 'id'},
                [ { name: 'name', type: 'string' } ]
              ),
        listeners: {
          load: function(records, options) {
            console.log( 'loaded ' + records.totalLength + ' records');
          },
          loadexception: function(proxy, options, response, error) {
            console.log('error loading records from server:');
            console.log("\tfile: "+error.fileName);
            console.log("\tline: "+error.lineNumber);
          }
        }
      });

The listeners in the code above are just for debuging purposes and can be removed safely. The only interesting bit is the autoLoad option, but we will come back to that later. For now it is enough to say that the Store above will read an XML document with this structure:

<?xml version="1.0" encoding="UTF-8"?>
<categories type="array">
<category>
<id type="integer">1</id>
<name>default category</name>
</category>
<category>
<id type="integer">2</id>
<name>security risk</name>
</category>
</categories>

The autoLoad config options determines if the data store will try to load the values from the provided url upon creation or if it will be necessary to call the load(). This is useful when we are working in local mode, let’s see the code for the first combo:

var comboLocal = new Ext.form.ComboBox({
  fieldLabel: 'Select a category',
  store: categories,
  mode: 'local',
  displayField: 'name',
  selectOnFocus: true,
  emptyText: 'No Ajax in the combo...'
});

Above we specified local this means that options for this combo will be loaded from the categories store. The data store is expected to be populated already, this can be done either by specifying the autoLoad option as described above or by calling the load().

If you rather have you combo performing the Ajax request, then the code you need to use is:

var comboRemote = new Ext.form.ComboBox({
  fieldLabel: 'Select a category',
  store: categories,
  displayField: 'name',
  triggerAction: 'all',
  selectOnFocus: true,
  emptyText: 'Options loaded using Ajax...'
});

There is no need to include mode: 'remote' because is the default behaviour, here the trick is to include the triggerAction: 'all', otherwise the Ajax request will never be executed.

So that was it, short and simple, stay tuned for the next one ;)

Popularity: 41% [?]

Share and Enjoy:
  • Digg
  • del.icio.us
  • Slashdot
  • Technorati

2 Responses to “extjs ComboBox remote XML”

  1. Games says:

    Thanks for sharing. I’m always interested in learning more about extjs, getting more and more into it.

  2. vin says:

    Thanks a lot. I really need it. I found another way at http://blog.taragana.com/index.php/archive/extjs-hack-dynamic-combobox-remote-on-demand-loading-with-local-filtering/, but your way is more clean ;)

Leave a Reply