开发者博客:www.developsearch.com
流向地区:
<!-- 区域树 -->
<ext:panel var="treePanel" region="west" layout="border" frame="false" width="260">
<ext:items>
<ext:panel region="north" layout="column" frame="true" autoHeight="true" >
<ext:items>
<ext:button text="${app:i18n_menu('button.expand')}" var="btnExpandAll" handler="onExpandAll" />
<ext:button text="${app:i18n_menu('button.collapse')}" var="btnCollapseAll" handler="onCollapseAll" />
<ext:textField var="query_areaName" name="query_areaName" emptyText="${app:i18n('newRebateArea.blank.inputNodeName')}" allowBlank="true" maxLength="200" />
<ext:button cls="x-btn-icon" icon="${images}/search.gif" var="btnSearch" handler="onFindByKeyWordFiler" />
</ext:items>
</ext:panel>
<ext:treePanel var="areaTreePanel" region="center" autoScroll="true" rootVisible="false">
<ext:treeLoader var="areaLoader" url="findAreas.action" textField="areaName" idField="areaId" clsField="areaId" handler="onNoteClick"/>
<ext:asyncTreeNode text="${app:i18n('newRebateArea.text.allArea')}" var="areaRoot" id="0" />
</ext:treePanel>
</ext:items>
</ext:panel>
// 存放选中的当前节点
var currentNode;
// 单击树根节点事件
function onRootNoteClick(node,event)
{
currentNode = node;
editForm.getForm().reset();
}
// 单击树节点事件
function onNoteClick(node,event) {
Ext.Ajax.request({
params: {areaId: node.attributes.id},
url: "findNewRebateAreaById.action",
success: function(response) {
var resp = Ext.util.JSON.decode(response.responseText);
view_areaId.setValue(resp.areaId);
view_parentId.setValue(resp.parentId);
view_areaCode.setValue(resp.areaCode);
view_areaName.setValue(resp.areaName);
view_areaDesc.setValue(resp.areaDesc);
view_parentName.setValue(node.parentNode.text);
if(resp.isDistrict=='1'){
btnEdit.hide();
btnAdd.hide();
}else{
btnEdit.show();
btnAdd.show();
}
}
});
currentNode = node;
}
// 查询树节点
function onFindByKeyWordFiler() {
var text = query_areaName.getValue();// 获取输入框的值
clearTimeout(timeOutId);// 清除timeOutId
areaTreePanel.expandAll();// 展开树节点
// 为了避免重复的访问后台,给服务器造成的压力,采用timeOutId进行控制,如果采用treeFilter也可以造成重复的keyup
timeOutId = setTimeout(function() {
// 根据输入制作一个正则表达式,'i'代表不区分大小写
var re = new RegExp(Ext.escapeRe(text), 'i');
// 先要显示上次隐藏掉的节点
Ext.each(hiddenPkgs, function(n) {
n.ui.show();
});
hiddenPkgs = [];
if (text != "") {
treeFilter.filterBy(function(n) {
// 只过滤叶子节点,这样省去枝干被过滤的时候,底下的叶子都无法显示
return !n.isLeaf() || re.test(n.text);
});
// 如果这个节点不是叶子,而且下面没有子节点,就应该隐藏掉
areaTreePanel.root.cascade(function(n) {
if(n.id!='0'){
if(!n.isLeaf() &&judge(n,re)==false&& !re.test(n.text)){
hiddenPkgs.push(n);
n.ui.hide();
}
}
});
} else {
treeFilter.clear();
return;
}
}, 500);
}
// 过滤不匹配的非叶子节点或者是叶子节点
var judge =function(n,re){
var str=false;
n.cascade(function(n1){
if(n1.isLeaf()){
if(re.test(n1.text)){ str=true;return; }
} else {
if(re.test(n1.text)){ str=true;return; }
}
});
return str;
};
// 展开所有节点
function onExpandAll(){
areaTreePanel.expandAll();
}
// 收缩所有节点
function onCollapseAll(){
areaTreePanel.collapseAll();
}
// 刷新当前节点
function onRefresh() {
currentNode.reload();
}
// 增加右键点击事件
if(areaTreePanel){
areaTreePanel.on('contextmenu',function(node,e){//声明菜单类型
e.preventDefault();//阻止浏览器默认右键菜单
node.select();//是该节点被选中状态
rightClick.showAt(e.getXY());//获得鼠标的坐标
currentNode = node;
});
}
var rightClick = new Ext.menu.Menu({
id :'rightClickCont',
items : [{
id:'btnAdd',
text : '新增普通区域',
handler:function (){
onAdd();
}
},{
id:'btnAddDistrict',
text : '新增行政区域',
handler:function (){
onAddDistrict();
}
}, {
id:'btnDelete',
text : '删除',
handler:function (){
onDelete();
}
}, {
id:'btnRefresh',
text : '刷新',
handler:function (){
onRefresh();
}
}]
});
//删除操作
function onDelete() {
Ext.MessageBox.confirm('${app:i18n('prompt')}','${app:i18n('confirmDeleteData')}', deleteRecord);
}
function deleteRecord(result){
if (result == 'yes') {
Ext.Ajax.request({
url: 'deleteNewRebateArea.action?areaId='+currentNode.id,
waitMsg: "${app:i18n('saving')}",
success: function(response) {
var resp = Ext.util.JSON.decode(response.responseText);
if(resp.success==true){
currentNode.parentNode.reload();
editForm.getForm().reset();
Ext.MessageBox.alert('${app:i18n('prompt')}','${app:i18n('deleteSuccess')}');
}else{
if(resp.status==0){
Ext.MessageBox.alert('${app:i18n('prompt')}','${app:i18n('prompt.connection.exception')}');
} else {
Ext.MessageBox.alert('${app:i18n('prompt')}',resp.status);
}
}
}
});
}
}
折扣组合:
树上加checkbox需要在返回的实体中加上
// 显示checkbox
private boolean checked = false;
// 判断树节点是否是叶子
private boolean leaf;
public boolean isLeaf() {
if (this.isDistrict == 1) {
leaf = true;
} else {
leaf = false;
}
return leaf;
}
<ext:ui scripts="${scripts}/MapUtil.js">
<ext:formPanel var="queryView" region="north" autoHeight="true" frame="true">
<ext:items>
<ext:fieldSet layout="column" title="${app:i18n('queryCondition')}">
<ext:items>
<ext:panel width="235" layout="form">
<ext:items>
<!-- 原寄地 -->
<ext:panel var="query_srcAreaPanel" height="200" width="220" title="${app:i18n('newRebateSet.srcArea')}" region="center" frame="true" >
<ext:items>
<ext:treePanel var="query_srcAreaTreePanel" region="center" listeners="{checkchange:query_srcAreaTreeCheckChange,load:afterload}" frame="true" width="208" height="162" autoScroll="true" animate="true" rootVisible="false" checkModel="cascade" onlyLeafCheckable="false">
<ext:treeLoader var="query_srcAreaTreeLoader" url="findDistricts.action" textField="distName" idField="distId" clsField="0" baseAttrs="{uiProvider:Ext.tree.TreeCheckNodeUI}"/>
<ext:asyncTreeNode text="" var="query_srcAreaTreeRoot" id="0" checked="false" />
</ext:treePanel>
</ext:items>
</ext:panel>
</ext:items>
</ext:panel>
<ext:panel layout="form" width="235">
<ext:items>
<!-- 目的地 -->
<ext:panel var="query_distAreaPanel" height="200" width="220" title="${app:i18n('newRebateSet.distArea')}" region="center" frame="true" >
<ext:items>
<ext:treePanel var="query_distAreaTreePanel" region="center" listeners="{checkchange:query_distAreaTreeCheckChange,load:afterload}" frame="true" width="208" height="162" autoScroll="true" animate="true" rootVisible="false" checkModel="cascade" onlyLeafCheckable="false">
<ext:treeLoader var="query_distAreaTreeLoader" url="findDistricts.action" textField="distName" idField="distId" clsField="areaId" />
<ext:asyncTreeNode text="" var="query_distAreaTreeRoot" id="0" checked="false" />
</ext:treePanel>
</ext:items>
</ext:panel>
</ext:items>
</ext:panel>
<ext:panel layout="form" width="50" buttonAlign="center" height="200" >
<ext:items>
<ext:panel layout="form" width="50" buttonAlign="center" height="40" ><ext:items></ext:items></ext:panel>
<ext:panel layout="form" width="50" buttonAlign="center" height="60" ><ext:items>
<ext:button text="${app:i18n_menu('button.addTo')}" var="query_btnSaveTo" handler="query_onAddArea"/>
</ext:items></ext:panel>
<ext:panel layout="form" width="50" buttonAlign="center" height="60" ><ext:items>
<ext:button text="${app:i18n_menu('button.delete')}" var="query_btnDeleteTo" handler="query_onDeleteArea"/>
</ext:items></ext:panel>
<ext:panel layout="form" width="50" buttonAlign="center" height="40" ><ext:items></ext:items></ext:panel>
</ext:items>
</ext:panel>
<ext:panel layout="form" width="260">
<ext:items>
<!-- 流向结果 -->
<ext:gridPanel var="query_dirResultView" region="center" height="200" width="250" frame="true">
<ext:store var="query_dirResultStore" url="findAvailableLeaves.action">
<ext:jsonReader>
<ext:fields type="com.sf.module.cdhrebate.domain.NewRebateSetDir"/>
</ext:jsonReader>
</ext:store>
<ext:checkboxSelectionModel/>
<ext:columnModel>
<ext:propertyColumnModel dataIndex="srcAreaId" id="dirResultGrid_srcAreaId" hidden="true"/>
<ext:propertyColumnModel dataIndex="distAreaId" id="dirResultGrid_distAreaId" hidden="true"/>
<ext:propertyColumnModel dataIndex="srcAreaName" id="dirResultGrid_srcAreaName" width="98" header="${app:i18n('newRebateSet.srcArea')}"/>
<ext:propertyColumnModel dataIndex="distAreaName" id="dirResultGrid_distAreaName" width="98" header="${app:i18n('newRebateSet.distArea')}"/>
</ext:columnModel>
</ext:gridPanel>
</ext:items>
</ext:panel>
<ext:panel width="250" layout="form" >
<ext:store var="regionStore2" url="findAvailableLeaves.action?dimensionType=1" remoteSort="true">
<ext:jsonReader totalProperty="totalSize" root="rbtDimensionItems">
<ext:fields type="com.sf.module.cdhprotocol.domain.IRbtDimensionItem"/>
</ext:jsonReader>
</ext:store>
<ext:items>
<ext:hidden name="query.areaIdsJSONStr" var="query_areaIdsJSONStr"/>
<ext:textField name="query.name" var="query_name" fieldLabel="${app:i18n('newRebateSet.name')}" width="125"/>
<ext:textField name="query.alias" var="query_alias" fieldLabel="${app:i18n('newRebateSet.alias')}" width="125"/>
<ext:comboBox name="query.regionType" var="query_regionType" fieldLabel="${app:i18n('newRebateSet.regionType')}<font color=red>*</font>"
valueField="itemCode" displayField="itemName" hiddenName="query.regionType" triggerAction="all" editable="false" mode="remote" store="regionStore2" width="125" />
</ext:items>
</ext:panel>
</ext:items>
</ext:fieldSet>
</ext:items>
</ext:formPanel>
var query_srcMap = new MapUtil();
var query_distMap = new MapUtil();
// 单击原寄地树节点checkbox事件
function query_srcAreaTreeCheckChange(node,checked) {
if(checked){
query_srcMap.put(node.attributes.id,node.attributes.text);
disableTreeNoteForEach(node);
}else{
query_srcMap.removeByKey(node.attributes.id);
enableTreeNoteForEach(node);
}
}
// 单击目的地树节点checkbox事件
function query_distAreaTreeCheckChange(node,checked) {
if(checked){
query_distMap.put(node.attributes.id,node.attributes.text);
disableTreeNoteForEach(node);
}else{
query_distMap.removeByKey(node.attributes.id);
enableTreeNoteForEach(node);
}
}
//将当前节点下的所有子节点变为不可选
function disableTreeNoteForEach(currentNote){
if (currentNote.hasChildNodes()) {
currentNote.eachChild(function(child) {
child.disable();
if(child.attributes.checked==true){
child.attributes.checked = false;
}
disableTreeNoteForEach(child);
});
}
}
//将当前节点下的所有子节点变为可选
function enableTreeNoteForEach(currentNote){
if (currentNote.hasChildNodes()) {
currentNote.eachChild(function(child) {
child.enable();
enableTreeNoteForEach(child);
});
}
}
//点击树节点加载子节点后触发的事件
function afterload(node){
if(node.attributes.checked || node.disabled == true){
disableTreeNoteForEach(node);
}else{
enableTreeNoteForEach(node);
}
}
// 添加流向
function query_onAddArea(){
for (i = 0; i < query_srcMap.elements.length; i++)
{
var srcAreaId = query_srcMap.elements[i].key;
var srcAreaName = query_srcMap.elements[i].value;
for (j = 0; j < query_distMap.elements.length; j++)
{
var distAreaId = query_distMap.elements[j].key;
var distAreaName = query_distMap.elements[j].value;
var record = new Ext.data.Record({
srcAreaId:srcAreaId,
srcAreaName:srcAreaName,
distAreaId:distAreaId,
distAreaName:distAreaName
});
//判断结果表中是否存在
if(query_isResultExist(srcAreaId,distAreaId))
{
query_dirResultStore.insert(query_dirResultStore.getCount(),record);//store.getCount()表示插入到最后一行
}
}
}
}
/**
*判断结果表中是否存在
*false表示已存在,不插入
*true表示不存在,允许插入
*/
function query_isResultExist(srcAreaId,distAreaId){
var newRecd = query_dirResultStore.getRange();
var findResult = query_dirResultStore.findBy(function(newRecd, id) {
var isExist = false;
if((newRecd.get('srcAreaId') == srcAreaId) && (newRecd.get('distAreaId') == distAreaId)){
isExist = true;
}
return isExist;
}) == -1;
return findResult;
}
//删除流向
function query_onDeleteArea(){
var recs = query_dirResultView.getSelectionModel().getSelections();
for(var i = recs.length -1; i >= 0; i--){
query_dirResultStore.remove(recs[i]);
}
}
// 将已选择的流向记录封装成json
function query_setAreaStoreData(){
var areaIds = [];
for(var i=0; i< query_dirResultStore.getCount(); i++){
var obj = {};
obj.srcAreaId = query_dirResultStore.getAt(i).data.srcAreaId;
obj.distAreaId = query_dirResultStore.getAt(i).data.distAreaId;
areaIds.push(obj);
}
query_areaIdsJSONStr.setValue(Ext.util.JSON.encode(areaIds));
}
//重新加载树
srcAreaTreePanel.root.reload();
多个root的写法
原理:ExtJs 的树并不支持多个根节点,但它提供了一个隐藏根节点的属性.
其实就是相当于新建一个虚拟的根节点,然后把多个节点挂到该节点上,然后再把虚拟的根节点隐藏.
我们看到所有二级节点都变成了根节点,变相实现了多个根节点的功能.
<script type="text/javascript">
Ext.onReady(function(){
// shorthand
var Tree = Ext.tree;
var tree = new Tree.TreePanel({
el:'tree-div',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
rootVisible : false,
containerScroll: true,
loader: new Tree.TreeLoader({
dataUrl:'../../examples/tree/get-nodes.php'
})
});
var root = new Ext.tree.TreeNode({
text : 'extjs.org.cn',
draggable : false,
id : 'extjs.org.cn'
});
tree.setRootNode(root);
// set the root node
var root1 = new Tree.AsyncTreeNode({
text: 'Ext JS',
draggable:false,
id:'source'
});
root.appendChild(root1);
// set the root node
var root2 = new Tree.AsyncTreeNode({
text: 'Ext Plugins',
draggable:false,
id:'plugins'
});
root.appendChild(root2);
// render the tree
tree.render();
root.expand();
});
</script>
禁用/启用树(兼容IE)
function EnableTree(ctl)
{
if(ctl.value=="enable"){
tree.maskDisabled = true;
tree.enable();
}else{
tree.disable();
tree.maskDisabled = false;
tree.enable();
}
}
<input type="radio" name="radio" id="enable" value="enable" οnclick="EnableTree(this);" checked> 启用
<input type="radio" name="radio" id="disable" value="disable" οnclick="EnableTree(this);"> 禁用