Skip to content
Harmen Janssen edited this page Jan 20, 2016 · 2 revisions

Random ExtJS notes.

Extended model file intro

Basically, in the model files you are dealing with part configuration, part compiled form widgets. In the init function, everything's just a big array of form configuration.
In the loaddata event you can manipulate the actual form widgets.

Skeleton of a model file:

Garp.dataTypes.MyModel.on('init', function() {
	this.addListener('loaddata', function(rec, formPanel) {
	});
});

Grabbing a field

In the configuration stage, do:

this.getField('column'); 

// Immediately manipulate its properties:
this.getField('column').fieldLabel = 'foo bar';

When compiled:

var field = formPanel.getForm().findField('column');

Make field required

this.getField('image_id').allowBlank = false;

When dealing with a relation field, the following needs to be added:

var ref = '../../../ImagePreview_' + this.getField('image_id').name;
Ext.each(this.formConfig[0].items[0].items, function(item){
	if (item.ref === ref) {
		item.allowBlank = false;
		return false;
	}
});

Insert a field at runtime at a specific position

this.insertField(3, {
  xtype: 'blabla'
});

Choose image as column (for columnModel)

You can just spawn this:

{
  "listFields": ["image_id", "name"]
}

Disable a field

this.getField('show_on_page').disabled = true;

Or after compilation:

formPanel.getForm().findField('name').setDisabled(true); // or .disable()

Change a field's height

this.getField('column').height = 400;

Add something to the form at runtime

this.formConfig[0].items[0].items.unshift({
    xtype: 'box',
    ref: '../../../document_url_text',
    hideMode: 'display',
    html: '',
    fieldLabel: ' ',
    hidden: true
});

Element with a ref property register themselves as a property of a parent.
In this case the element will become a property of the formPanel. You can access it thry formPanel.document_url_text.

Note: We use unshift here but of course you can do all your usual array manipulation:

this.formConfig[0].items[0].items.splice(8, 0, {
    xtype: 'box',
    ref: '../../../contact_header',
    html: '<h2>' + __('school contact header') + '</h2>',
    fieldLabel: ' '
});

How to read record data

this.addListener('loaddata', function(rec, formPanel) {
    // rec is the record. Data is in rec.data
    
    if (rec.data.filename) {
        var docUrl = DOCUMENTS_CDN + rec.data.filename;
        formPanel.document_url_text.update('De URL naar dit document is: <a target="_blank" href="' + docUrl + '">' + docUrl + '</a>');
        formPanel.document_url_text.show();
    }
});

Adding filters

function addQuery(key, val) {
    var store = Garp.gridPanel.getStore();
    store.baseParams.query = {};
    store.baseParams.query[key] = val;
    store.reload();
}

this.filterMenu = [{
    text: __('Future'),
    group: 'filter',
    handler: function(){
        addQuery('start >=', new Date().format('Y-m-d'));
    }
}

These filters manipulate the list at the left of the form. An admin can select them with the button beneath the list.

Query a model

Need to arbitrarily fetch some model data from the server?

// Discipline is the model name in this case
Garp.Discipline.fetch({}, function(result) {
    if (!result.rows || !result.rows.length) {
        return;
    }
    Ext.each(result.rows, function(row) {
        // ...
    });
});

Add a button to the form toolbar

var tb = formpanel.formcontent.getTopToolbar();
tb.addButton({
    text: __("Do something"),
    iconCls: 'icon-something',
    ref: 'abc',
    handler: function() {
        // ...
    }
});
tb.doLayout();

Access the top toolbar

It's Garp.toolbar.
From there you can access all the buttons e.g. Garp.toolbar.newButton.

Count items in GridPanel

Garp.gridPanel.getStore().getCount()

Make sure an HTML field is not rendered in the gridPanel

this.getColumn('code').renderer = Garp.renderers.htmlRenderer;

Make form labels wider

this.formConfig[0].items[0].labelWidth = 200;

Remove a relationPanel

this.removeRelationPanel('Event');

Access a relationPanel at compilation stage

In the configuration stage, you can browse the this.formConfig collection and find the config for the relationPanels.
Getting to the actual rendered panels in the compilation stage can be done like this:

var tabs = formpanel.items.items[0];
// "Event" relation is the third tab
var eventTab = tabs.items.items[2];
// The relateePanel (the right one) will be here:
var eventRelateePanel = eventTab.items.items[1].items.items[0];

(it's not really clear what to actually do with the panel at the time of writing, but surely you can do all kinds of stuff to it at runtime)

Change the title of a relationPanel

var eventRelPanel = this.getRelationPanel('Event');
eventRelPanel.title = eventRelPanel.tabTip = 'Related events';

Add a virtual column

Your backend could return an unknown column that is for instance an expression.
Something like a count, or concatenated value. In the extended model, just add a column with a matching dataIndex to include the value in the gridPanel.

this.insertColumn(0, {
  dataIndex: 'donation_count',
  visible: true,
  sortable: true,
  searchable: false,
  header: __('Aantal donaties')
});

Interesting files

garp.datatype.js Contains blueprint for all datatypes. getField(), getRelationPanel() – all those functions are there if you want to refactor or inspect them.

garp.relationpanel.js Class for relationPanels

garp.createrelatewindow.js Class for quick-creating records (From relationPanels and relationFields).

Clone this wiki locally