expensior
11 Oct 2012, 5:49 AM
Hello,
I am having an issue with the Picker. I extended it to show a treepanel instead of a bound list. On other pages I am using an IconCombo extension that shows a flat hierarchy of the tree with the node icons leading the text.
I would like the input field to look identical but I can't find how to render the value of the picker to include the iconCls of the currently selected node.
This is what I am currently using. I have 3 different types of nodes - system - locations and divisions and they each have a unique iconCls that I would like to see displayed in the input text field before the text.
Modifying fieldSubTpl has gotten me close to what I wanted to accomplish but not quite. What I need would be a renderer on the value to render a div inside or something like that.
Another issue that I fixed only with a dirty workaround yet is that when I set the value to the selected node itself the input field obviously displays "[Object object]". Not sure why the picker does not support displayField like a combobox or the documented Ext.ux.TreePicker in 4.1.X.. That is why I always set the value to node.text and put a reference to the actually node object in "selectedNode" before using setValue for the displayed text.
Ext.define("Ext.ux.TreeCombo", {
extend : "Ext.form.field.Picker",
alias: 'widget.treecombo',
initComponent : function() {
var self = this;
Ext.apply(self, {
fieldLabel : self.fieldLabel,
labelWidth : self.labelWidth
// pickerAlign : "tl"
});
self.addEvents('groupSelected');
self.callParent();
},
editable:false,
selectedNode: {},
createPicker : function() {
var self = this;
self.picker = new Ext.tree.Panel({
maxHeight : 300,
autoScroll : true,
floating : true,
resizable: false,
focusOnToFront : false,
shadow : true,
ownerCt : this.ownerCt,
useArrows : true,
store : self.store,
root: self.root,
rootVisible : true,
animCollapse : false,
animate : false,
listeners:{
scope:this,
select:this.valueSelected
}
});
return self.picker;
},
alignPicker : function() {
// override the original method because otherwise the height of the treepanel would be always 0
var me = this, picker, isAbove, aboveSfx = '-above';
if (this.isExpanded) {
picker = me.getPicker();
if (me.matchFieldWidth) {
// Auto the height (it will be constrained by min and max width) unless there are no records to display.
if (me.bodyEl.getWidth() > this.treeWidth){
picker.setWidth(me.bodyEl.getWidth());
} else picker.setWidth(this.treeWidth);
}
if (picker.isFloating()) {
picker.alignTo(me.inputEl, "", me.pickerOffset);// ""->tl
// add the {openCls}-above class if the picker was aligned above the field due to hitting the bottom of the viewport
isAbove = picker.el.getY() < me.inputEl.getY();
me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls
+ aboveSfx);
picker.el[isAbove ? 'addCls' : 'removeCls'](picker.baseCls
+ aboveSfx);
}
}
},
valueSelected: function(picker,value,options) {
this.selectedNode=value.data;
this.setValue(value.data.text);
this.fireEvent('valueSelected',this,value.data.id);
Ext.Function.defer(function(){
this.collapse();
}, 0, this);
}
});
var treeStore = Ext.create('Ext.data.TreeStore', {
proxy : {
type : 'ajax',
// url: '/ems/service/loadHierarchy.json',
url : context.contextPath + '/service/LoadHierarchy'
},
folderSort : true,
root: {
expanded: true,
iconCls:'showAllIcon',
text: messages.get('ems.common.treecombo.all'),
id:'ems_hierarchy_root'
},
sorters : [ {
property : 'text',
direction : 'ASC'
} ]
});
treeCombo = Ext.create('Ext.ux.TreeCombo',{
width: 260,
treeWidth: 260,
store : treeStore,
listeners: {
change: {
fn: function(field,newVal,oldVal,eOpts){
var id=field.selectedNode.id;
if(id==='ems_hierarchy_root'){
getConfItemBlocks();
}else{
getConfItemBlocksById(field.selectedNode.id);
}
}
}
}
});
treeStore.load( { callback: function(){
treeCombo.suspendEvents();
treeCombo.setValue(treeStore.getRootNode().text);
treeCombo.selectedNode=treeStore.getRootNode();
treeCombo.resumeEvents();
}});
I am having an issue with the Picker. I extended it to show a treepanel instead of a bound list. On other pages I am using an IconCombo extension that shows a flat hierarchy of the tree with the node icons leading the text.
I would like the input field to look identical but I can't find how to render the value of the picker to include the iconCls of the currently selected node.
This is what I am currently using. I have 3 different types of nodes - system - locations and divisions and they each have a unique iconCls that I would like to see displayed in the input text field before the text.
Modifying fieldSubTpl has gotten me close to what I wanted to accomplish but not quite. What I need would be a renderer on the value to render a div inside or something like that.
Another issue that I fixed only with a dirty workaround yet is that when I set the value to the selected node itself the input field obviously displays "[Object object]". Not sure why the picker does not support displayField like a combobox or the documented Ext.ux.TreePicker in 4.1.X.. That is why I always set the value to node.text and put a reference to the actually node object in "selectedNode" before using setValue for the displayed text.
Ext.define("Ext.ux.TreeCombo", {
extend : "Ext.form.field.Picker",
alias: 'widget.treecombo',
initComponent : function() {
var self = this;
Ext.apply(self, {
fieldLabel : self.fieldLabel,
labelWidth : self.labelWidth
// pickerAlign : "tl"
});
self.addEvents('groupSelected');
self.callParent();
},
editable:false,
selectedNode: {},
createPicker : function() {
var self = this;
self.picker = new Ext.tree.Panel({
maxHeight : 300,
autoScroll : true,
floating : true,
resizable: false,
focusOnToFront : false,
shadow : true,
ownerCt : this.ownerCt,
useArrows : true,
store : self.store,
root: self.root,
rootVisible : true,
animCollapse : false,
animate : false,
listeners:{
scope:this,
select:this.valueSelected
}
});
return self.picker;
},
alignPicker : function() {
// override the original method because otherwise the height of the treepanel would be always 0
var me = this, picker, isAbove, aboveSfx = '-above';
if (this.isExpanded) {
picker = me.getPicker();
if (me.matchFieldWidth) {
// Auto the height (it will be constrained by min and max width) unless there are no records to display.
if (me.bodyEl.getWidth() > this.treeWidth){
picker.setWidth(me.bodyEl.getWidth());
} else picker.setWidth(this.treeWidth);
}
if (picker.isFloating()) {
picker.alignTo(me.inputEl, "", me.pickerOffset);// ""->tl
// add the {openCls}-above class if the picker was aligned above the field due to hitting the bottom of the viewport
isAbove = picker.el.getY() < me.inputEl.getY();
me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls
+ aboveSfx);
picker.el[isAbove ? 'addCls' : 'removeCls'](picker.baseCls
+ aboveSfx);
}
}
},
valueSelected: function(picker,value,options) {
this.selectedNode=value.data;
this.setValue(value.data.text);
this.fireEvent('valueSelected',this,value.data.id);
Ext.Function.defer(function(){
this.collapse();
}, 0, this);
}
});
var treeStore = Ext.create('Ext.data.TreeStore', {
proxy : {
type : 'ajax',
// url: '/ems/service/loadHierarchy.json',
url : context.contextPath + '/service/LoadHierarchy'
},
folderSort : true,
root: {
expanded: true,
iconCls:'showAllIcon',
text: messages.get('ems.common.treecombo.all'),
id:'ems_hierarchy_root'
},
sorters : [ {
property : 'text',
direction : 'ASC'
} ]
});
treeCombo = Ext.create('Ext.ux.TreeCombo',{
width: 260,
treeWidth: 260,
store : treeStore,
listeners: {
change: {
fn: function(field,newVal,oldVal,eOpts){
var id=field.selectedNode.id;
if(id==='ems_hierarchy_root'){
getConfItemBlocks();
}else{
getConfItemBlocksById(field.selectedNode.id);
}
}
}
}
});
treeStore.load( { callback: function(){
treeCombo.suspendEvents();
treeCombo.setValue(treeStore.getRootNode().text);
treeCombo.selectedNode=treeStore.getRootNode();
treeCombo.resumeEvents();
}});