OK so a lot of messing about later I have found a way to extend the user form with whatever I like, so thought I'd post it in case anyone stumbled on this question.
Using a plugin that fires on "OnUserFormPrerender" you can add a js file (with $modx->regClientStartupScript($src)) that grabs the user form tabs object and then extends it:
Ext.onReady(function() {
var usertabs = Ext.getCmp('modx-user-tabs');
usertabs.add({
title: 'My Tab ' + (usertabs.items.length + 1),
defaults: { labelWidth: 180 },
layout: 'form',
autoScroll: true,
autoHeight: false,
labelAlign: "left",
labelWidth: 180,
width: 800,
height: 500,
cls: 'main-wrapper',
items: [
{
xtype: 'combo-boolean'
,name: 'mybooleanfield'
,fieldLabel: 'Set a value for my boolean field or use a lexicon string'
,value: 1
,allowBlank: false
}
,{
html: '<p>Some instructions for the field below</p>'
,border: false
, bodyCssClass: 'panel-desc'
}
,{
xtype: 'xdatetime'
,fieldLabel: 'Renewal date'
,name: 'renewal_date'
,allowBlank: true
}
,{
fieldLabel: 'Whoa! a super select box!',
id: 'licences-superbox-primarylicenses',
name: 'primarylicences[]',
xtype: 'modx-superbox-primarylicences',
resizable: true
}
]
});
});
If you're interested the superboxselect xtype "modx-superbox-primarylicences" used as one of the items above can be defined like this (I've just added mine in the same file as the tabs extension above, but if it's reuseable code then it should probably be in a separate file):
/**
* PrimaryLicences SuperBoxSelect
*
* @class MODx.combo.PrimaryLicences
* @extends Ext.ux.form.SuperBoxSelect
* @xtype modx-superbox-primarylicences
*/
MODx.combo.PrimaryLicences = function (config) {
config = config || {};
Ext.applyIf(config, {
xtype:'superboxselect'
,triggerAction: 'all'
,mode: 'remote'
,valueField: "id"
,displayField: "fullname"
,typeAhead: true
,typeAheadDelay:75
,width: 400
,pageSize: 20
,store: new Ext.data.JsonStore({
id:'id',
autoLoad: true,
root:'results',
dir: 'ASC',
fields: ['fullname', 'id'],
url: MODx.config.connectors_url+'security/user.php',
baseParams:{
action: 'getList'
,usergroup: 2
,sort: 'fullname'
,dir: 'ASC'
}
})
});
MODx.combo.PrimaryLicences.superclass.constructor.call(this, config);
};
Ext.extend(MODx.combo.PrimaryLicences, Ext.ux.form.SuperBoxSelect);
Ext.reg('modx-superbox-primarylicences', MODx.combo.PrimaryLicences );
Again for reference, one of the tab items I included above is a datetime field. On the User form the datetime.js utility file is already loaded, but if you're using this technique to extend a form that doesn't already load it, or on a CMP page, you need to explicitly add the datetime file before you can add an xdatetime xtype. e.g. in a CMP controller file add
$this->addJavascript(MODX_MANAGER_URL.'assets/modext/util/datetime.js');
to your loadCustomCssJs method. If you're using it in a plugin you can probably use regClientStartupScript to add the file. Then you can add a datetime element to your panel with something like
items: [{
xtype: 'xdatetime',
name: 'renewal_date',
//other properties
},
{
//...other items
}
]
Obviously you can add whatever other form elements you like under the "items" property of the new tab (the datetime and superboxselect elements shown above were just examples of doing something fancy that made me smile). On save the fields will be submitted along with the rest of the form, so your same plugin can capture the event OnUserFormSave in order to process your fields.
In my case, I have extended the modUser object and this is how I'm managing the extended object's values.