1.需求:
开发的过程中遇到了根据数据库字段来构造checkbox的需求,在baidu上面搜了很多结果一看都是千篇一律转载过来的,不能直接使用,但是可以借鉴的,由于开发的组件用到了extjs。我也刚开始用,所以弄了两天,还好把这个需求弄出来了。方法也许不好,但是可以使用
2.准备组件:
额外用到了ext的ajax同步请求的组件,因为异步的话checkboxgroup还未构建就调用会报错,当然开始就赋几个item应该不会报错了,我也没时间来验证了,干脆弄了同步的。
同步组件是ext-basex.js网上很多的。csdn上面有下载。
3.开发步骤:
Ext.namespace('My.UI'); My.UI.CheckboxGroup=Ext.extend(Ext.form.CheckboxGroup,{ columns:6, dataUrl:'', //数据地址 labelFiled:'columnChName', valueFiled:'columnName', setValue:function(val){ if(val.split){ val=val.split(','); } this.reset(); for(var i=0;i<val.length;i++){ this.items.each(function(c){ //debugger; if(c.inputValue==val[i]){ c.setValue(true); } }); } }, reset:function(){ this.items.each(function(c){ c.setValue(false); }); }, getValue:function(){ var val=[]; this.items.each(function(c){ if(c.getValue()==true) val.push(c.inputValue); }); return val.join(','); }, onRender:function(ct, position){ var items=[]; //alert(items.length); if(!this.items){ //如果没有指定就从URL获取 Ext.Ajax.request({ url:this.dataUrl, scope:this, async:false, success:function(response){ var data = Ext.util.JSON.decode(response.responseText); data=data.rows||data; var Items2=this.items; if(this.panel) { var columns=this.panel.items; if(columns) { for(var i=0;i<columns.items.length;i++){ column=columns.items[i]; column.removeAll(); } Items2.clear(); } } for(var i=0;i<data.length;i++){ var d=data[i]; var chk = {boxLabel: d[this.labelFiled], name: this.name, inputValue: d[this.valueFiled],tooltip:'sssf'}; //alert(d[this.labelFiled]); items.push(chk); //alert(items.length); } } }); this.items=items; } My.UI.CheckboxGroup.superclass.onRender.call(this, ct, position); } }); Ext.reg('mycheckgroup',My.UI.CheckboxGroup);
其中async:false, 的意思是同步的意思。
接着是调用的代码,这里把我所有代码都拷贝过来了,自己摘抄着看
Ext.onReady(function(){ Ext.QuickTips.init(); // turn on validation errors beside the field globally Ext.form.Field.prototype.msgTarget = 'side'; /*==================================================================== * CheckGroup example *====================================================================*/ var cc=new My.UI.CheckboxGroup({ //fieldLabel: 'Auto Layout', name: 'temCheckedgroup', dataUrl: '${pageContext.request.contextPath}/cashway/DetailSearch_getkdpjnlTableInfo.do' }); var checkGroup = { xtype: 'fieldset', title: '请选择查询条件', autoHeight: true, layout: 'form', //collapsed: true, // initially collapse the group //collapsible: true, items: [cc] }; var sp = new Ext.FormPanel({ url:'${pageContext.request.contextPath}/cashway/DetailSearch_next.do', standardSubmit: true, renderTo:'form-cthid', }); // combine all that into one huge form var fp = new Ext.FormPanel({ frame: true, labelWidth: 10, url:'${pageContext.request.contextPath}/cashway/DetailSearch_next.do', renderTo:'form-ct', bodyStyle: 'padding:0 10px 0;', items: [ checkGroup ], buttons: [{ text: '下一步', handler: function(){ //var fp = this.ownerCt.ownerCt, form = fp.getForm(); sform = sp.getForm(); if (form.isValid()) { // check if there are baseParams and if // hiddent items have been added already if (sp.baseParams && !sp.paramsAdded) { // add hidden items for all baseParams for (i in sp.baseParams) { //alert(i); sp.add({ xtype: 'hidden', name: i, value: fp.baseParams[i] }); } sp.doLayout(); // set a custom flag to prevent re-adding sp.paramsAdded = true; } for(var ik =0;ik<cc.items.length;ik++) { if(cc.items.itemAt(ik).checked) { var stuId = new Ext.form.TextField({ name:'checkeditem', value:cc.items.itemAt(ik).inputValue, readOnly:true }); sp.add(stuId); } } //alert(cc.items.itemAt(0).inputValue); form.submit(); } //if(fp.getForm().isValid()){ // Ext.Msg.alert('Submitted Values', 'The following will be sent to the server: <br />'+ // fp.getForm().getValues(true).replace(/&/g,', ')); //} //showPopupDetailWindow(); } },{ text: '重置', handler: function(){ fp.getForm().reset(); } }] }); });
强调一下sp那个form是没用了,我对struts不是太熟悉,提交的时候我开始想的是构建一个form然后把所有选中的项添加到form中去然后提交,后来发现checkboxgroup是只提交选中的项,所以直接submit原来的那个form就可以了。
后台获取:
注意这个checkboxgroup的name是name: 'temCheckedgroup', 没有i开头是后面action里面的属性如果是i开头的话会出问题(我没研究过,遇到了)。
后台代码:
private String[] temCheckedgroup;
有get set方法即可,这样提交的时候会自动的装配值,因为name都是相同的,所以自动装配成数组形式。
开发.net习惯了,struts还是很不适应 呵呵,弄了两天。ext虽然强大,但是我还没开始喜欢。
///////////////////////////////
注意事项:返回的json数据中要包含checked属性!
给Tree添加了checkBox选中事件,选中父接点能自动选中所有子节点,改变子节点的状态的同时也能根据其兄弟节点的状态来改变父节点的选中状态。
//=========================================代码如下===============
Ext.BLANK_IMAGE_URL="../../Client/Images/s.gif";
/**
* @class Ext.tree.CheckboxTree
* 含有checkbox的树状菜单
* @param {Object} config中的参数
* el 必输入
* dataUrl 必输入
* rootText 必输入
* rootId 默认值为0
*/
Ext.tree.CheckboxTree=function(config){
var myTreeLoader=new Ext.tree.TreeLoader({
dataUrl:config.dataUrl
});
myTreeLoader.on("beforeload", function(treeLoader, node) {
treeLoader.baseParams.check = node.attributes.checked;
treeLoader.baseParams.id=node.id;
}, this);
Ext.tree.CheckboxTree.superclass.constructor.call(this,{
animate:false,
enableDD:false,
autoScroll:true,
useArrows:true,
containerScroll:true,
border:false,
draggable:false,
dropConfig: {appendOnly:true},
//el:config.el,
root:new Ext.tree.AsyncTreeNode({
text:config.rootText,
draggable:false,
checked:config.checked,
id:'00'||config.rootId
}),
loader:myTreeLoader
});
var childbool=true;
new Ext.tree.TreeSorter(this,{folderSort:true});
this.on({
'checkchange':function(node,checked){
var parentNode=node.parentNode;
if(checked){
/**
* 节点为真时,此节点的子节点,判断此节点的父节点时,判断父节点的子节点是否全部为
* 真,如果全部为真,则此父节点为真,如果不为真则不变 全部为真
*/
if(childbool){
var childNodes=node.childNodes;
for(var i=0;i<childNodes.length;i++){
var childNode=childNodes[i];
if(!childNode.attributes.checked){
childNode.ui.toggleCheck();
}
}
}
/**
* 此如果此节点又父节点,则判断此父节点的子节点是否全为真 如果全为真则此父节点也为真
*/
if(parentNode&&!parentNode.attributes.checked){
childbool=false;
parentNode.ui.toggleCheck();
}
else childbool=true;
}else{
/**
* 如果为false时,
*/
//if(parentNode&&parentNode.attributes.checked){
// parentNode.attributes.checked=false;
// parentNode.ui.toggleCheck();
//}
/*
*父节点
*/
ParentState(parentNode);
/*
*子接点
*/
var childNodes=node.childNodes;
for(var i=0;i<childNodes.length;i++){
var childNode=childNodes[i];
if(childNode.attributes.checked){
childNode.ui.toggleCheck();
}
}
}
}
});
}
function ParentState(parentNode)
{
var brothNodes=null;
if(parentNode!=null) //兄弟接点
brothNodes=parentNode.childNodes;
else return false;
var brothflag=0;
for(var i=0;i<brothNodes.length;i++){
var brothNode=brothNodes[i];
if(brothNode.attributes.checked){
break;
}
else brothflag++;
}
if(brothflag==brothNodes.length){ //说明兄弟节点没选种的
if(parentNode.attributes.checked)
parentNode.ui.toggleCheck();
ParentState(parentNode.parentNode);
}
}
Ext.extend(Ext.tree.CheckboxTree, Ext.tree.TreePanel,{
/**
* 展开根节点
* @return 返回根节点
*/
expandRoot:function(){
this.root.expand(true,false); //第一个参数表示是否递归展开,第二个属性表示展开是是否有动画效果
return this.root;
}
});
var treeLeft=new Ext.tree.CheckboxTree({
//el:'tree2',
checked:false,
dataUrl:'../../tree/RightTree.aspx?admin=true&roleName='+encodeURIComponent("系统管理员"),
rootText:'权限菜单',
rootId:"00"
});
//////////////////