我想编写一个ComboBox,让用户输入一个查询,同时让他从树中选择一个值。我尝试过编写树选择,但是如果我将代码更改为继承自dijit.form.ComboBox
而不是dijit.form.Select
,则代码会中断。
这是我选择树的树:
dojo.declare('TreeSelect',dijit.form.Select,{
constructor: function(widgetArgs){
this.tree = widgetArgs.tree || new FC_Tree();
this.initTree = widgetArgs.initTree;
if(dojo.isFunction(this.initTree))
this.initTree();
},
postCreate: function(){
this.inherited(arguments);
this.option = {label: '', value: 'NoValue'};
this.tree.option = this.option;
this.addOption(this.option);
dojo.connect(this.tree,'onClick',this,'closeDropDown');
dojo.connect(this.tree,'itemSelected',this,'selectOption');
},
selectOption: function(opt){
this.option.label = opt.label || opt;
this.option.value = opt.value || opt;
this.option.id = opt.id || opt;
this.set('value',this.option);
},
_getMenuItemForOption: function (option){
return this.tree;
},
openDropDown: function(){
this.tree.refresh();
this.inherited(arguments);
},
clear: function(){
this.tree.clear();
this.tree.option.value = '';
this.tree.option.label = '';
this.tree.option.id = '';
this.set('value',this.tree.option);
},
initializeTree: function(treeData) {
// Init the tree only if needed
dojo.forEach(treeData, function(field) {
var store = this.tree.model.store;
store.newItem(field);
}, this);
},
setOpenCallback: function(callback){
this.tree.setOpenCallback(callback);
},
resetTree: function() {
var store = this.tree.model.store;
store.fetch( { query: { id: "*" },
onItem: function(item) {
store.deleteItem(item);
}
});
}
});
我曾尝试用这样替换组合框的代码:
dojo.declare('TreeSelect',dijit.form.ComboBox,{
请帮我纠正。 提前谢谢!
添加FC_Tree的代码:
dojo.declare('FC_Tree',dijit.Tree,{
showRoot: false,
openOnClick: true,
noIconForNode: true,
noMarginForNode: true,
persist: false,
openCallback: null,
constructor: function(){
if(dojo.isUndefined(arguments[0]) || dojo.isUndefined(arguments[0].model))
{
var forest_store = new FC_DataStore({id: 'id', label: 'label'});
this._storeloaded = false;
dojo.connect(forest_store,'loaded',this,function(){this._storeloaded = true;})
this.model = new dijit.tree.ForestStoreModel({store:forest_store});
}
},
setOpenCallback: function(callback){
this.openCallback = callback;
},
option: {},
itemSelected: function(item){
},
onClick: function(item, node, evt){
var store = this.model.store;
get = function(){
return store.getValue(item, "isDir");
};
// on folder click mark it unselectable
if(get("isDir"))
{
this.isExpanded = true;
this.isExpandable = true;
}
else
{ //In case the item has 'onClick' delegate execute it and assign the output to 'selItem'
var selItem = (item.onClick && item.onClick[0])? item.onClick[0](this.model.store,item.parentID[0]):item.id[0];
this.option.id = item.id;
this.option.value = item.value;
this.option.label = item.label;
this.itemSelected(this.option);
}
},
onOpen: function(item, node){
if(this.rootNode.item == item){
return this.inherited(arguments);
}
var data = (this.openCallback != null) ? this.openCallback(item, node) : {};
if(!data.length){
return this.inherited(arguments);
}
FC_Comm.when(data,{
onCmdSuccess: dojo.hitch(this,function(data){
var store = this.model.store;
var children = store.getValues(item, 'children');
dojo.forEach(children, function(child) {
// don't delete child if doNotDelete flag is true
if(!store.getValue(child, "doNotDelete"))
store.deleteItem(child);
});
if (data) {
var store = this.model.store;
if (store) {
dojo.forEach(data, function(child) {
store.newItem(child, {parent : item, attribute: 'children'});
});
}
}
})
});
},
refresh: function(){
if(this._storeloaded){
// Close the store (So that the store will do a new fetch()).
this.model.store.clearOnClose = true;
this.model.store.close();
// Completely delete every node from the dijit.Tree
this._itemNodesMap = {};
this.rootNode.state = "UNCHECKED";
this.model.root.children = null;
// Destroy the widget
this.rootNode.destroyRecursive();
// Recreate the model, (with the model again)
this.model.constructor(this.model)
// Rebuild the tree
this.postMixInProperties();
this._load();
this._storeloaded = false;
}
},
clear: function(){
this.model.store.load([]);
}
});
答案 0 :(得分:1)
您可能会在this fiddle
中找到灵感/答案recursiveHunt和selectTreeNodeById functions是通过其id找出项目路径的逻辑。它相当过分,你可能会找到一个更好的解决方案(不知道100%你的json是什么数据)..
基本上,使用FilteringSelect并引用此对象中的树。同样对于Tree,引用select。 然后为你的树,钩入加载函数(也称为刷新afaik),然后依次选择,使用onBlur启动选择treenode。
var combo = new dijit.form.FilteringSelect({
onBlur: function() {
// called when filter-select is 'left'
if (this.validate()) {
// only act if the value holds an actual item reference
var id = this.get("value");
var name = this.get("displayedValue");
this.tree.selectNode(id);
}
}
});
var tree = new dijit.Tree( { ....
onLoad: function() {
combostore.setData(this.model.store._arrayOfAllItems);
},
onClick: function(item) {
// uses 'this.combo', must be present
// also, we must have the same 'base store' for both combo and model
var _name = this.model.store.getValue(item, this.combo.searchAttr);
this.combo.set("item", item, false, _name);
},
selectNode: function(lookfor) {
selectTreeNodeById(this, lookfor);
},
combo: combo // <<<<<<
});
combo.tree = tree // <<<<<<
确保模型具有rootId,并且您的select.searchAttr与tree.model.labelAttr匹配。请参阅小提琴上的工作样本