PDA

View Full Version : Ext.ux.form.TriggerLayer and Ext.ux.form.TriggerTree



willf1976
12 May 2010, 12:09 AM
Hi All

I was having a few problems with the various solutions for putting a tree panel with in a form so I decided to revamp an extension of mine to handle this functionality.

The first extension below is a simple one I made which is a trigger field that creates a new floating layer next to the trigger field and then passes that layer to listeners to do with as they please.

The second extension is a simple implementation of the Ext.ux.form.TriggerLayer where I use it to create a tree in the layer.

Ext.ux.form.TriggerLayer:


/*
addapted from: Ext.ux.form.ClockField by Neon Monk (Found in Thread: http://www.extjs.com/forum/showthread.php?t=56390)
modifying author: Will Ferrer
date: 05/11/10
history:
03/11/10 -- posted to extJs forums
05/11/10 -- fixed a few bugs
*/
/**
* @class Ext.ux.form.TriggerLayer
* @extends Ext.form.TriggerField
* A trigger field that creates a layer floating next to it when activated. Using listeners you may render different elements into the layer allowing you to easly attach any component to a trigger field.
* @constructor
* @param {Object} config The config object
*/
Ext.ns('Ext.ux.form');
Ext.ux.form.TriggerLayer = Ext.extend(Ext.form.TriggerField, {
/**
* @cfg {Object|Null} layerSize
* May contain an object with a height and width property to define the size of the layer to be created. Defaults to null.
*/
layerSize: null,
/**
* @cfg {Object|Null} layerOffset
* Offsets to apply to the layer relative to the trigger field. Defaults to [10, 0].
*/
layerOffset: [10, 0],
/**
* @cfg {Object|Null} layerAlign
* Alignment of the layer relative to the trigger field. Defaults to 'tr'.
*/
layerAlign : 'tr',
/**
* @cfg {Object} layerStyle
* Styles to apply to the css of the layer object. Defaults to {}.
*/
layerStyle : {},
/**
* @cfg {Object} layerConfig
* Config for the layer. Defaults to {}.
*/
layerConfig : {},
// @private
initComponent : function () {
Ext.ux.form.TriggerLayer.superclass.initComponent.call(this);
this.addEvents(
/**
* @event createlayer
* Fires when a layer is created
* @param {Ext.ux.form.TriggerLayer} this
* @param {Ext.Layer} the layer created
*/
'createlayer',
/**
* @event showlayer
* Fires when a layer is displayed via the exand function
* @param {Ext.ux.form.TriggerLayer} this
* @param {Ext.Layer} the layer created
*/
'showlayer',
/**
* @event hidelayer
* Fires when a layer is hidden via the collapse function
* @param {Ext.ux.form.TriggerLayer} this
* @param {Ext.Layer} the layer created
*/
'hidelayer'
);
},
// @private
onTriggerClick: function(){
if (this.disabled) {
return;
}
if (this.isExpanded()) {
this.collapse();
this.el.focus();
} else {
this.onFocus({});
this.el.focus();
this.expand();
}
},
// @private
isExpanded: function(){
return (this.layer.getStyle('visibility') == 'visible' ? true : false);
},
// @private
expand: function(){
if (this.disabled) {
return;
}
var w = this.el.getWidth();
this.layer.alignTo(this.el, this.layerAlign, this.layerOffset);
if (!Ext.isEmpty(this.layerSize)) {
this.layer.setSize(this.layerSize.width, this.layerSize.height);
/*this.layer.setStyle({
'padding-left': (w - this.layerSize.width) / 2 + 'px'
});*/
}
this.layer.setStyle({
'visibility': 'visible',
'display': 'block'
});
this.fireEvent('showlayer', this, this.layer);
},
// @private
disable: function(ct, position){
Ext.ux.form.TriggerLayer.superclass.disable.call(this);
this.collapse();
},
// @private
collapse: function(){
this.layer.setStyle({
'visibility': 'hidden'
});
this.layer.setStyle({
'display': 'none'
});
this.fireEvent('hidelayer', this, this.layer);
},
// @private
onRender: function(ct, position){
Ext.ux.form.TriggerLayer.superclass.onRender.call(this, ct, position);
var style = Ext.apply(this.layerStyle, {
'-moz-user-select': 'none',
'position': 'absolute',
'z-index': 24000
});
this.layer = new Ext.Layer(Ext.apply(this.layerConfig, {
shadow: this.shadow
}));

this.layer.setStyle(style);

this.layer.setStyle({
'position': 'fixed'
});

this.holder = this.el.findParent('div');
this.layer.appendTo(this.holder);
this.on('blur', this.collapse, this);

this.layer.setStyle({
'background-color': this.layerBgColor,
'border': this.layerBorder
});
this.fireEvent('createlayer', this, this.layer);
}
});
Ext.reg('ux-form-triggerlayer', Ext.ux.form.TriggerLayer);




Ext.ux.form.TriggerTree:

/*
author: Will Ferrer
date: 05/11/10
history:
05/11/10 -- posted to extJs forums
11/16/10 -- added new features
*/
/**
* @class Ext.ux.form.TriggerTree
* @extends Ext.ux.form.TriggerLayer
* A trigger field that creates a layer floating next to it when activated and fills it with a tree. Also gets the value of the tree node clicked on and puts it in the trigger field.
* @constructor
* @param {Object} config The config object
*/
Ext.ns('Ext.ux.form');
Ext.ux.form.TriggerTree = Ext.extend(Ext.ux.form.TriggerLayer, {
/**
* @cfg {Object} treeConfig
* config for tree to generate. Defaults to {}.
*/
treeConfig: {
width : 200,
height : 200,
rootVisible : false,
autoScroll: true
},
/**
* @cfg {Object} rootConfig
* config for tree root. Defaults to {}.
*/
rootConfig : {
text: 'root',
draggable: false,
id: 'root',
expanded: true
},
/**
* @cfg {Object} loaderConfig
* config for tree loader. Defaults to {}.
*/
loaderConfig: {},
/**
* @cfg {Boolean} createOnce
* Whether or not to generate the tree only once (when layer is first created). Defaults to false.
*/
createOnce: false,
/**
* @cfg {String} valueAttribute
* Attribute to use from the clicked tree node in the value. Defaults to 'text'.
*/
valueAttribute: 'text',
/**
* @cfg {String} valueAttribute
* Attribute to use from the clicked tree node in the display. Defaults to 'text'.
*/
displayAttribute: 'text',
/**
* @cfg {Object} valueField
* the field to store the value from the valueAttribute in. Defaults to null.
*/
valueField: null,
/**
* @cfg {Boolean} ignoreBranches
* Attribute to use from the clicked tree node. Defaults to true.
*/
ignoreBranches: true,
//Overrides to parent classes default configurations:
layerOffset: [0, -200],
layerAlign : 'tl',
//Private Functions:
// @private
initComponent : function () {
Ext.ux.form.TriggerTree.superclass.initComponent.call(this);
if (this.createOnce) {
this.on('createlayer', this.createTree, this);
} else {
this.on('showlayer', this.createTree, this);
this.on('hidelayer', this.destroyTree, this);
}
},
// @private
createTree : function (target, layer) {
var config = this.treeConfig;
config.loader = new Ext.tree.TreeLoader(this.loaderConfig);
config.root = new Ext.tree.TreeLoader(this.rootConfig);
config.renderTo = layer;
var tree = new Ext.tree.TreePanel(config);
tree.on('click', this.onTreeNodeClick, this);
this.tree = tree;
},
// @private
destroyTree : function () {
if (!Ext.isEmpty(this.tree)) {
this.tree.destroy();
}
},
// @private
onTreeNodeClick : function (node, e) {
if (!this.ignoreBranches || node.leaf) {
var valueAttribute = node.attributes[this.valueAttribute],
displayAttribute = node.attributes[this.displayAttribute];
this.setValue(displayAttribute);
if (!Ext.isEmpty(this.valueField)) {
this.valueField.setValue(valueAttribute);
}
this.collapse();
}
}
});
Ext.reg('ux-form-triggertree', Ext.ux.form.TriggerTree);


Best regards

Will Ferrer

Stju
12 May 2010, 10:34 AM
Sounds interesting..
Any Demo?