`

平台新的双向选择组件

    博客分类:
  • js
阅读更多
1.index.jsp
<%@ page contentType="text/html; charset=GBK" %>

<!-- 定义组件按钮样式 -->
<style>
.button {
width: 50px;
height: 22px;
font-size: 10px;
color: #000000;
border: #6B698C 1px solid;
cursor: hand;
vertical-align: middle;
}
</style>

<script type="text/javascript" src="scripts\selectlist.js"></script>

<script language="javascript">

function checkMenu(mid){
  //判断是否选中,组件需要调用
  var menus = [23,25];
  for(var i = 0; i < menus.length; i++){
    if(mid == menus[i]){
      return true;
    }
  }
  return false;
}

//准备组件数据
//数据项分别是:选中时的值(内码),显示名,是否选中,排序码(外码),级次
var items =
[
  [ "21", "测试管理", checkMenu(21), "200", 1],
  [ "22", "测试单表", checkMenu(22), "200001", 2],
  [ "23", "系统管理", checkMenu(23), "800", 1],
  [ "24", "组织管理", checkMenu(24), "800800", 2],
  [ "25", "基本机构信息", checkMenu(25), "800800700", 3],
  [ "26", "组织机构维护", checkMenu(26), "800800800", 3],
  [ "27", "职务管理", checkMenu(27), "800800900", 3],
  [ "28", "用户管理", checkMenu(28), "800900", 2],
  [ "29", "增加用户信息", checkMenu(28), "800900700", 3],
  [ "30", "用户信息维护", checkMenu(30), "800900800", 3]
];

//实例化对象,参数分别是:要显示的列表数据,选择框的显示大小,是否以树状形式显示,是否显示层次码
var gbp_sl = new GBPSelectList("org", items, 10, 1, 1, "button");
var gbp_sl_my = new GBPSelectList("myorg", items, 10, 1, 0, "button");
var gbp_sl_list = new GBPSelectList("listorg", items, 10, 0, 0, "button");

</script>

<html>
  <head>
    <title>报告编制</title>
  </head>
  <body>
    <form name="frmMain">
      <table width="600px">
        <tr bgcolor=#AAAA00>
          <td>
      <script>gbp_sl.make();</script>
          </td>
        </tr>
        <tr bgcolor=#AAAA00>
          <td>
      <script>gbp_sl_my.make();</script>
          </td>
        </tr>
        <tr bgcolor=#AAAA00>
          <td>
      <script>gbp_sl_list.make();</script>
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>
2.select.js
/*
-------------------------------------------------------------------------------
文件名称:select.js
说    明:JavaScript脚本,用于网页中涉及到选择时的控制,
版    本:1.0
修改纪录:
---------------------------------------------------------------------------
时间 修改人 说明
2004-8-11 zxl 创建
-------------------------------------------------------------------------------
*/

/*
用途:菜单配置页面中一级菜单被点击
输入: form对象
1.选中和单项选择一样,变颜色
2.没选中时则下级都不能选中
add by zbk
*/
 
function CA(CB){
if(CB.checked){

}else{
var frm=document.forms[0];
  for (var i=0;i<frm.elements.length;i++)
  {
    var e=frm.elements[i];
    if (  (e.type=='checkbox')&&
    (CB.id.indexOf(e.id.substring(0,3))==0)&&e.disabled==false)
    {
      e.checked=false;
     
    }
  }
  }

}
/*
用途:菜单配置页面中底级菜单项被点击
输入: form对象
1.对象选中则上级被选中,变颜色
2.对象没被选中则下级取消,变颜色
add by zbk
*/

function CCA(CB){//菜单配置页面中子菜单项被点击
  if (CB==null) return; 
  var frm=document.forms[0];
 
  if (CB.checked){
    for (var i=0;i<frm.elements.length;i++)
    {
      var e=frm.elements[i];
      if((e.type=='checkbox')&&(e.name=='menucheckbox')&&(CB.id.indexOf(e.id)==0)&&e.disabled==false)
      {
        e.checked=true;
       
      }
    }
  }
  else{
 
   for (var i=0;i<frm.elements.length;i++)
  {
    var e=frm.elements[i];
    if ( (e.type=='checkbox')&&
    (e.id.indexOf(CB.id)==0)&&e.disabled==false)
    {
      e.checked=false;

    }
  }
 
  }
}

/*
用途:如果只有一个选择框得到他的值
输入: chekname选择框对象名称
add by zbk
*/

function getselectedValue(chekname){
if (chekname==null) return ''; 
  var length =0;
    var i=0;
    var count =0;
var frm=document.forms[0];
    eles = frm.elements;
for (var i=0;i<frm.elements.length;i++)
    {
obj= eles.item(i);
      type = obj.attributes.item("type").nodeValue;
      if(type == "checkbox" && obj.disabled==false &&obj.id!="selectAll" && obj.id==chekname && obj.checked){
  return obj.value;
  }
    }

}

// 返回true表示选择,返回false表示没有选择
function selectedRadio(form){
    var length =0;
    var i=0;   
    eles = form.elements;
   
    while( i<eles.length){
      obj= eles.item(i);
      type = obj.attributes.item("type").nodeValue;
      if(type == "radio"){
        if(obj.checked){
       
          return true;
        }
      }
      i++;
    }
    return false;
  }    
3.selectlist.js
/**
组件名称:
  左右双向选择组件。

主要功能:
  1> 提供两种风格-普通列表和树状列表。
  2> 目前提供三个扩展函数
    getSelectedValues:  获得选中的值,返回的是个包含节点编号的数组
    getRows:            查看所有记录的详细信息,返回的是个包含节点对象的二维数组
    getSelectedRows:    查看选中记录的详细信息,返回的是个包含节点对象的二维数组

备注说明:
  树状风格时,选择上级会自动级联处理下级;选择下级则上级默认半选中;如果所有下级都选中,则上级选中。
  一个页面只能使用一个组件(需要修改)

修改记录
  2007-06-22
  杨文彦
  整理代码,添加注释,增加按钮样式
*/

/*==================== 组件对象代码 ====================*/
/*
1、构造方法
2、数据检查过滤方法
3、组件生成方法
4、选中/取消方法
5、全部选中/取消方法
6、页面数据显示方法*/

//构造函数
function GBPSelectList(nameSpace, items, size, isTreeStyle, isShowCode, ctrlStyle) {
    this.multiple            = true;                    //是否允许多选
    this.listSize            = size ? size : 20;        //选择框的长度
    this.isTreeStyle         = Boolean(isTreeStyle);    //是否用树状形式显示数据
    this.isShowCode          = Boolean(isShowCode);     //如果是树状形式,是否显示层次码
    this.ctrlStyle           = ctrlStyle;               //按钮样式

    this.needOrder           = true;                   //是否需要排序。(只在普通形式下起作用,树状时必须排序)

    this.itemList            = items;                   //存放所有选择元素的数组

    this.leftSelect          = null;                    //左边的选择框控件
    this.rightSelect         = null;                    //右边的选择框控件
    this.leftDiv             = null;                    //左边放置列表框的层
    this.rightDiv            = null;                    //右边放置列表框的层
    this.leftDiv_innerHTML   = "";                      //左侧选择框层的内部元素,
    this.rightDiv_innerHTML  = "";                      //右侧选择框层的内部元素
    this.leftLabel           = null;                    //左边的文字标签控件
    this.rightLabel          = null;                    //右边的文字标签控件

    this.namespace           = nameSpace;               //控件名称的前缀
    this.leftDivName         = "divAll";                //左边放置列表框的层的名称
    this.rightDivName        = "divChecked";            //右边放置列表框的层的名称
    this.leftSelectName      = "sltAll";                //左边列表框的名称
    this.rightSelectName     = "sltChecked";            //右边列表框的名称
    this.selectButton        = "btnSelect";             //选中按钮的名称
    this.selectAllButton     = "btnSelectAll";          //选中所有按钮的名称
    this.cancelButton        = "btnCancel";             //取消选择按钮的名称
    this.cancelAllButton     = "btnCancelAll";          //取消所有按钮的名称

    this.o_children          = [];                      //一级节点列表
    this.root                = this;                    //根级节点-组件对象
    this.nodes               = {};                      //存放所有节点
    var o_this               = this;                    //组件对象引用

    this.buildNode = function(){                        //处理组件显示数据,建立节点列表对象
        if(this.isTreeStyle){
            //构造树形显示风格
            _build(o_this, 0);
        }else{
            //构造列表显示风格
            for(var i = 0; i < this.itemList.length; i++){
                new GBP_SL_Item(o_this, this.itemList[i]);
            }
        }
    };

    //在子类里迭代,是为了效率考虑。
    function _build(father, level, start){
        if(!start) start = 0;
        for(var i = start; i < o_this.itemList.length; i++){
            curLevel = o_this.itemList[i][4];
            //是否属于本级节点
            if(curLevel == (level + 1)){
                var obj = new GBP_SL_Item(father, o_this.itemList[i]);
                //继续下层递归
                _build(obj, curLevel, i + 1);
            }else if(curLevel <= level){
                //结束本层递归
                break;
            }
        }
    }
}

//对数据进行检查、过滤、排序处理
GBPSelectList.prototype.prepareData = function() {
    var list = new Array();
    var arrays = this.itemList;
    var _pre;

    //按显示名排序
    function _sortByName(a,b){
        if(a[1] == b[1]) return 0
        return (a[1] > b[1]) ? 1 : -1;
    }

     //按层次码排序
    function _sortByTreeCode(a,b){
        if(a[3] == b[3]) return 0
        return (a[3] > b[3]) ? 1 : -1;
    }

    //检查数据是否完整,过滤不完整数据
    for(var n = 0; n < arrays.length; n++){
        var len = list.length;
        //列表节点至少要求有两项数据
        //树形节点至少要求有五项数据
        if((!this.isTreeStyle && arrays[n].length >= 2) || (this.isTreeStyle && arrays[n].length >= 5)){
            list[len] = arrays[n];
        }
    }

    //排序
    if(this.isTreeStyle){
        list.sort(_sortByTreeCode);
    }else if(this.needOrder){
        list.sort(_sortByName);
    }

    //使用已经排序的节点列表替换原来未排序的节点列表
    this.itemList = list;
}

//构造组件,并显示在页面上
GBPSelectList.prototype.make = function() {
    //检查、过滤、排序数据
    this.prepareData();

    var txt , obj;

    txt = "<table width='100%' height='100' border='0' align='center' cellpadding='0' cellspacing='0'>"
             + " <tr align='center'>"
             + "   <td valign='top' width='30%'><div align='left' style='FONT-SIZE: 9pt;'>可用列表</div>"
             + "     <div id='" + this.namespace + this.leftDivName + "'></div>"
             + "   </td>"
             + "   <td valign='middle' width='8%' >"
             + "     <input type='button' name='" + this.namespace + this.selectButton + "' class='" + this.ctrlStyle + "' value='  >  '><br><br>"
             + "     <input type='button' name='" + this.namespace + this.selectAllButton + "' class='" + this.ctrlStyle + "' value='  >> '><br><br>"
             + "     <input type='button' name='" + this.namespace + this.cancelButton + "' class='" + this.ctrlStyle + "' value='  <  '><br><br>"
             + "     <input type='button' name='" + this.namespace + this.cancelAllButton + "' class='" + this.ctrlStyle + "' value=' <<  '>"
             + "   </td>"
             + "   <td valign='top' width='30%'><div align='left' style='FONT-SIZE: 9pt;'>选择列表</div>"
             + "     <div id='" + this.namespace + this.rightDivName + "' align='left'></div>"
             + "   </td>"
             + " </tr>"
             + "</table>" ;

    ///生成对象
    document.write(txt);
   
    var oThis = this;
   
    //关联控制对象
    this.leftDiv = document.getElementById(this.namespace + this.leftDivName);
    this.rightDiv = document.getElementById(this.namespace + this.rightDivName);

    //关联按钮单击事件
    obj = document.getElementById(this.namespace + this.selectButton);
    obj.onclick = function() { oThis.doSelect(1) };

    obj = document.getElementById(this.namespace + this.selectAllButton);
    obj.onclick = function() { oThis.doAll(1) };

    obj = document.getElementById(this.namespace + this.cancelButton);
    obj.onclick = function() { oThis.doSelect(-1) };

    obj = document.getElementById(this.namespace + this.cancelAllButton);
    obj.onclick = function() { oThis.doAll(-1) };

    //生成节点对象列表
    this.buildNode();

    //刷新页面显示
    this.update();
};

//选中/取消选中
GBPSelectList.prototype.doSelect = function(isSelect) {
    var values = new Array();

    //处理哪个对象
    var obj = (isSelect == 1) ? this.leftSelect : this.rightSelect;

    //判断是否多选模式
    if(this.multiple){
        for(var i = 0; i < obj.options.length; i++){
            if(obj.options[i].selected){
                values[values.length] = obj.options[i].value;
            }
        }
    }else{
        if(obj.selectedIndex > -1){
            values[0] = obj[obj.selectedIndex].value;
        }
    }

    if( values.length == 0) return;

    //处理下级节点
    for(var n = 0; n < values.length; n++){
        this.nodes[values[n]].doSelect(isSelect);
    }

    //刷新页面显示
    this.update()
};

//全部选中/取消
GBPSelectList.prototype.doAll = function(isSelect) {
    for(var i = 0; i < this.o_children.length; i++){
        this.o_children[i].doSelect(isSelect);
    }

    this.update()
};

//更新select元素的界面显示
GBPSelectList.prototype.update = function(){
    //用innerHTML来设置select元素,可以加快速度,减少屏幕闪烁
    //给层元素赋初值
    this.rightDiv_innerHTML = "<select name='" + this.namespace + this.rightSelectName + "' " + (this.multiple ? "multiple" : "") + " size='" + this.listSize + "' style='width:100%'>";
    this.leftDiv_innerHTML = "<select name='" + this.namespace + this.leftSelectName + "' " + (this.multiple ? "multiple" : "") + " size='" + this.listSize + "' style='width:100%'>";

    //处理子节点状态,根据子节点的状态设置父节点状态
    for(var i = 0; i < this.o_children.length; i++){
        this.o_children[i].doStatus();
    }
    //生成页面显示
    for(var i = 0; i < this.o_children.length; i++){
        this.o_children[i].update();
    }

    //直接用innerHTML,速度最快
    this.leftDiv.innerHTML = this.leftDiv_innerHTML + "</select>";
    this.rightDiv.innerHTML = this.rightDiv_innerHTML + "</select>";

    //重新获取两侧select元素,并为其绑定双击事件
    var oThis = this;

    this.leftSelect = document.getElementById(this.namespace + this.leftSelectName);
    this.leftSelect.ondblclick = function() { oThis.doSelect(1) };

    this.rightSelect  = document.getElementById(this.namespace + this.rightSelectName);
    this.rightSelect .ondblclick = function() { oThis.doSelect(-1) };
};

/*==================== 节点对象代码 ====================*/
/*
1、构造方法
2、节点选择/取消方法
3、节点状态处理方法
4、节点页面显示实现方法*/

//节点对象
function GBP_SL_Item(o_parent, o_item){
    this.father = o_parent;                                //上级节点引用
    this.root = o_parent.root;                             //根级节点引用
    this.o_children = [];                                  //下级节点数组
    this.info = o_item;                                    //节点对象
    this.status = o_item[2] ?  1 : -1 ;                    //节点是否默认选中标志
    this.level = this.root.isTreeStyle ? o_item[4] : 1;    //节点级次
    this.value = o_item[0];                                //节点编号
    this.showText = o_item[1];                             //节点显示名称

    //根据定义处理显示名称格式
    if(this.root.isShowCode)
        // 是否显示层级编码
        this.showText = this.showText + " - " + o_item[3];

    if(this.level > 0)
        //处理显示缩进
        this.showText = "__________________".substr(0, (this.level - 1)).replace(/_/g, "&nbsp;&nbsp;") + this.showText;

    //加入父级节点的下级节点列表
    o_parent.o_children[o_parent.o_children.length] = this;

    //加入所有节点列表
    this.root.nodes[this.value] = this;
}

//节点的选择函数
GBP_SL_Item.prototype.doSelect = function(isSelected){
    this.status = isSelected;

    //选择上级会自动选择其所有下级
    for(var i = 0; i < this.o_children.length; i++){
        this.o_children[i].doSelect(isSelected);
    }
};

//递归处理指定节点及其下级节点状态
GBP_SL_Item.prototype.doStatus = function(){
    //没有下级节点
    if(this.o_children.length == 0) return this.status;

    var selectedCount = 0, partSelectCount = 0, unselectedCount = 0;
    var returnStatus = null;

    for(var i = 0; i < this.o_children.length; i++){
        //递归处理下级节点状态
        returnStatus = this.o_children[i].doStatus();

        if(returnStatus == 1) selectedCount += 1;
        if(returnStatus == 0) partSelectCount += 1;
        if(returnStatus == -1) unselectedCount += 1;
    }

    if(selectedCount > 0 && unselectedCount == 0 && partSelectCount == 0){
        //下级全部选中
        this.status = 1;
    }else if(unselectedCount > 0 && selectedCount == 0 && partSelectCount == 0){
        //下级一个都没选中
        this.status = -1;
    }else{
        //下级部分选中
        this.status = 0;
    }

    return this.status;
};

//更新界面显示
GBP_SL_Item.prototype.update = function(){
    //status:1表示选中;0表示下级部分选中;-1表示未选
    if(this.status == -1 || this.status == 0){
        this.root.leftDiv_innerHTML += "<option value='" + this.value + "'>" + this.showText + "</option>\n";
    }

    if(this.status == 1 || this.status == 0){
        this.root.rightDiv_innerHTML += "<option value='" + this.value + "'>" + this.showText + "</option>\n";
    }

    //递归处理下级节点
    for(var i = 0; i < this.o_children.length; i++){
        this.o_children[i].update();
    }
};

/*==================== 组件扩展方法 ====================*/

//获得选中的值,返回的是个包含节点编号的数组
GBPSelectList.prototype.getSelectedValues = function() {
    var values = new Array();
    for(var n = 0; n < this.rightSelect.options.length; n++){
        values[n] = this.rightSelect.options[n].value;
    }
    return values;
};

//查看右侧记录的详细信息,返回的是个包含节点对象的二维数组
GBPSelectList.prototype.getRows = function() {
    var values = new Array();
    for(var n = 0; n < this.rightSelect.options.length; n++){
        values[values.length] = this.root.nodes[this.rightSelect.options[n].value].info;
    }
    return values;
};

//查看选中记录的详细信息,返回的是个包含节点对象的二维数组
GBPSelectList.prototype.getSelectedRows = function() {
    var values = new Array();
    for(var n = 0; n < this.rightSelect.options.length; n++){
        if(this.rightSelect[n].selected)
            values[values.length] = this.root.nodes[this.rightSelect.options[n].value].info;
    }
    return values;
};
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics