javascript xml为数据源的下拉框控件

  例如,当你在输入框中输入张三或是长沙,或是湖南,都会出现张三让你选择,输入18,将同时出现张三李四

  测试数据源如下:

  

复制代码 代码如下:

  <?xml version="1.0" encoding="utf-8" ?>

  <students>

  <student>

  <id>s1</id>

  <name>张三</name>

  <province>湖南</province>

  <city>长沙</city>

  <age>18</age>

  </student>

  <student>

  <id>s2</id>

  <name>李四</name>

  <province>湖北</province>

  <city>武汉</city>

  <age>18</age>

  </student>

  <student>

  <id>s3</id>

  <name>王五</name>

  <province>四川</province>

  <city>成都</city>

  <age>20</age>

  </student>

  </students>

  //---------------------------------------------DropDownListx.js------------------------

  function DropDownListx(parent,id)

  {

  this.id = id;

  var i;

  var me = this;

  this.parent = parent;

  var e = this.parent;

  var y = e.offsetTop;

  var x = e.offsetLeft;

  this.text = e.value;

  while (e = e.offsetParent)

  {

  y += e.offsetTop;

  x += e.offsetLeft;

  }

  this.parentInfo = {x:0,y:0};

  this.parentInfo.x = x;

  this.parentInfo.y = y;

  //外观

  this.width = this.parent.offsetWidth;

  this.height = 150;

  this.disabled = false;

  this.visibility = "hidden";

  this.attributed = false;//数据是否以属性表示,也可以用node来表示

  this.mainText = "";//要显示的字段名字

  this.mainValue = "";//要返回的值的字段名字

  this.selectedIndex = -1;//被選中的索引

  this.mouseoverIndex = -1;//鼠標懸停時的索引

  this.mouseoutIndex = -1;//鼠標離開時的索引

  this.selectedValue = "";

  this.selectedText = "";

  this.value = "";

  this.text = "";

  this.drawed = false;//表示是否重繪過

  this.table = null;

  //数据源

  this.dataSource = null;

  try

  {

  for(i = 6;i>0;i--)

  {

  try

  {

  this.dataSource = new ActiveXObject("MSXML2.DOMDocument." + i + ".0");

  break;

  }

  catch(ex1){;};

  }

  }

  catch(ex2){;};

  this.dataSource.async = false;

  this.dataSource.setProperty("SelectionLanguage", "XPath");

  var sh = function(){if(me.visibility == "hidden")me.show();};

  this.parent.attachEvent("onfocus",function(){window.setTimeout(sh,100);});

  this.parent.attachEvent("onchange",function(){me.filter(me.parent.value);});

  this.parent.attachEvent("onkeyup",function(){me.filter(me.parent.value);});

  this.parent.attachEvent("onclick",function(){if(event.button == "1")window.setTimeout(sh,10);});

  this.parent.style.cursor = "hand";

  //事件

  this.onSelected=null;

  this.onmouseover = null;

  this.onmouseout = null;

  this.onhide = null;

  window.document.attachEvent("onclick",function()

  {

  //有可能e不在最上層,所以要找到牠的區域

  if(event.x < me.parentInfo.x ||

  event.x > me.parentInfo.x + me.parent.offsetWidth ||

  event.y < me.parentInfo.y ||

  event.y > me.parentInfo.y + me.parent.offsetHeight)

  {

  if(me.visibility == "visible")

  me.hide();

  }

  });

  }

  //重新獲取位置,因爲parent的位置可能變動

  DropDownListx.prototype.getPosition=function()

  {

  var e = this.parent;

  var y = e.offsetTop;

  var x = e.offsetLeft;

  while (e = e.offsetParent)

  {

  y += e.offsetTop;

  x += e.offsetLeft;

  }

  this.parentInfo = {x:0,y:0};

  this.parentInfo.x = x;

  this.parentInfo.y = y;

  this.width = this.parent.offsetWidth;

  }

  //画出列表

  DropDownListx.prototype.show=function()

  {

  this.getPosition();

  var me = this;

  //画一个div

  var divid = this.id + "_div_" + this.parent.id;

  var d = document.getElementById(divid);

  if(d==null)

  {

  d = document.createElement("div");

  d.style.position = "absolute";

  }

  d.style.borderLeft = "black 1px groove";

  d.style.borderTop = "black 1px groove";

  d.style.borderRight = "black 1px groove";

  document.body.appendChild(d);

  d.setAttribute("id",divid);

  d.style.borderBottom = "black 1px groove";

  d.style.backgroundColor = "white";

  d.style.left = this.parentInfo.x + "px";

  if(document.body.clientHeight < this.parentInfo.y + this.parent.offsetHeight + this.height)

  d.style.top = (this.parentInfo.y - this.height) + "px";

  else

  d.style.top = (this.parentInfo.y +( this.parent.offsetHeight==""?20:this.parent.offsetHeight)) + "px";

  d.style.overflowX = "hidden";

  d.style.overflowY = "auto";

  d.style.zIndex = 999;

  d.style.visibility = "visible";

  d.style.borderWidth = "1px";

  this.visibility = "visible";

  this.listData();

  this._selectByName(this.parent.value);

  }

  DropDownListx.prototype.listData=function()

  {

  var e = this.parent;

  var base = this;

  //显示数据

  if(this.nodeList == null)

  this.nodeList = this.dataSource.documentElement.childNodes;

  var str="<table id = \"" + this.id + "_table_" + e.id + "\" width=\"" + (this.width) + "px\" height=\"24px\">";

  for(var i = 0;i<this.nodeList.length;i++)

  {

  var text = (base.attributed?this.nodeList.item(i).getAttribute(this.mainText):this.nodeList.item(i).selectSingleNode(this.mainText).text);

  str = str + "<tr><td id = \"" + this.id + "_td_" + i + "_" + e.id + "\" style=\"border-bottom: black 1px dotted;cursor:hand\" >" + text + "</td></tr>";

  }

  str += "</table>";

  var div = document.getElementById( this.id + "_div_" + e.id);

  div.innerHTML = str;

  var table = document.getElementById( this.id + "_table_" + e.id);

  this.table = table;

  if(table.offsetHeight < this.height)

  div.style.height = table.offsetHeight + 3;

  else

  div.style.height = this.height + 3;

  div.style.width = table.offsetWidth;

  for(var j = 0;j<this.nodeList.length;j++)

  {

  var d = document.getElementById(this.id + "_td_" + j + "_" + e.id );

  d.attachEvent('onclick',function()

  {

  var _td = document.getElementById(base.id + "_td_" + base.selectedIndex + "_" + e.id);

  if(_td)

  {

  _td.style.backgroundColor = "";

  _td.style.color = "";

  }

  base.selectedIndex = event.srcElement.parentElement.rowIndex;

  document.getElementById(base.id + "_div_" + base.parent.id ).style.visibility="hidden";

  base.selectedValue = (base.attributed?base.nodeList.item(base.selectedIndex).getAttribute(base.mainValue):base.nodeList.item(base.selectedIndex).selectSingleNode(base.mainValue).text);

  base.selectedText = (base.attributed?base.nodeList.item(base.selectedIndex).getAttribute(base.mainText):base.nodeList.item(base.selectedIndex).selectSingleNode(base.mainText).text);

  base.value = base.selectedValue;base.text = base.selectedText;

  if(base.onSelected != null)

  base.onSelected.apply(base);

  return false;

  });

  d.onmouseover=function()

  {

  base.mouseoverIndex =parseInt(event.srcElement.id.split("_td_")[1].split("_")[0]);

  try

  {

  event.srcElement.style.backgroundColor='gray';

  event.srcElement.style.color='white';

  e.value = event.srcElement.innerText;

  if(base.onmouseover != null)

  base.onmouseover.apply(base);

  }

  catch(ex){};

  };

  d.onmouseout = function()

  {

  base.mouseoutIndex = parseInt(event.srcElement.id.split("_td_")[1].split("_")[0]);

  if(event.srcElement.id == base.id + "_td_" + base.selectedIndex + "_" + e.id)

  {

  event.srcElement.style.backgroundColor='red';

  event.srcElement.style.color='blue';

  }

  else

  {

  event.srcElement.style.backgroundColor='';

  event.srcElement.style.color='';

  }

  if(base.onmouseout != null)

  base.onmouseout.apply(base);

  }

  }

  this.drawed = true;

  }

  DropDownListx.prototype.hide=function()

  {

  var d = document.getElementById(this.id + "_div_" + this.parent.id);

  if(d)

  d.style.visibility = "hidden";

  this.visibility = "hidden";

  this._select(this.selectedIndex);//为了防止有筛选的数据,要先选择

  this.nodeList = this.dataSource.documentElement.childNodes;

  if(this.onhide != null)

  this.onhide.apply(this);

  }

  DropDownListx.prototype.setSource=function(d)

  {

  this.dataSource.loadXML(d.xml);

  this.nodeList = d.documentElement.childNodes;

  this.drawed = false;

  }

  DropDownListx.prototype.setChildNodes=function(nodes)

  {

  this.dataSource.loadXML("<?xml version=\"1.0\" encoding=\"utf-8\" ?><options></options>");

  var node = this.dataSource.documentElement;

  for(var i = 0;i<nodes.length;i++)

  {

  var opt = doc.createNode(1,"option","");

  var r = nodes.item(i).childNodes

  for(var j = 0;j<r.length;j++)

  {

  var att = doc.createNode(1,r.item(j).nodeName,"");

  att.text = r.item(j).text;

  opt.appendChild(att);

  }

  node.appendChild(opt);

  }

  this.drawed = false;

  }

  DropDownListx.prototype.filter=function(text)

  {

  if(text==null || text =="")

  {

  this.reset();

  }

  else

  {

  var _text = text.split(" ");

  var str = "./*[contains(.,'" + _text[0] + "')";

  for(var i=1;i<_text.length;i++)

  {

  str = str + " and contains(.,'" + _text[i] + "')"

  }

  str = str + "]";

  this.nodeList = this.dataSource.documentElement.selectNodes(str);

  }

  this.listData();

  }

  //根据查询选中的节点的子节点的值

  DropDownListx.prototype.getNodeValue=function(nodeName)

  {

  if(nodeName == null || nodeName == "")

  return this.value;

  return (this.attributed?this.nodeList.item(this.selectedIndex).getAttribute(nodeName):this.nodeList.item(this.selectedIndex).selectSingleNode(nodeName).text);

  }

  DropDownListx.prototype.reset=function()

  {

  this.nodeList = this.dataSource.documentElement.childNodes;

  var _td = document.getElementById(this.id + "_td_" + this.selectedIndex + "_" + this.parent.id);

  if(_td)

  {

  _td.style.backgroundColor = "";

  _td.style.color = "";

  }

  this.selectedIndex = -1;

  this.selectedValue = "";

  this.selectedText = "";

  this.value = "";

  this.text = "";

  this.parent.value = "";

  }

  DropDownListx.prototype.select=function(index)

  {

  if(index == -1)

  this.reset();

  else

  {

  var _td = document.getElementById(this.id + "_td_" + this.selectedIndex + "_" + this.parent.id);

  if(_td)

  {

  _td.style.backgroundColor = "";

  _td.style.color = "";

  }

  this.nodeList = this.dataSource.documentElement.childNodes;

  this.selectedIndex = index;//被選中的索引

  this.selectedValue = this.attributed?this.nodeList.item(index).getAttribute(this.mainValue):this.nodeList.item(index).selectSingleNode(this.mainValue).text;

  this.selectedText = this.attributed?this.nodeList.item(index).getAttribute(this.mainText):this.nodeList.item(index).selectSingleNode(this.mainText).text;

  this.value = this.selectedValue;

  this.text = this.selectedText;

  this.parent.value = this.selectedText;

  try

  {

  this.table.rows.item(index).cells.item(0).focus();

  this.table.rows.item(index).cells.item(0).style.backgroundColor = "red";

  this.table.rows.item(index).cells.item(0).style.color = "blue";

  this.parent.focus();

  }catch(ex){}

  if(this.onSelected != null)

  this.onSelected.apply(this);

  }

  }

  DropDownListx.prototype.selectByName=function(name)

  {

  if(name == null || name == "")

  {

  this.reset();

  return;

  }

  for(var i = 0;i<this.nodeList.length;i++)

  {

  var _name = this.attributed?this.nodeList.item(i).getAttribute(this.mainText):this.nodeList.item(i).selectSingleNode(this.mainText).text;

  if(_name == name) break;

  }

  if(i != this.nodeList.length)

  {

  this.select(i);

  }

  else

  this.reset();

  }

  DropDownListx.prototype.selectByValue=function(value)//不響應事件的副本

  {

  if(value == null || value == "")

  {

  this.reset();

  return;

  }

  for(var i = 0;i<this.nodeList.length;i++)

  {

  var _value = this.attributed?this.nodeList.item(i).getAttribute(this.mainValue):this.nodeList.item(i).selectSingleNode(this.mainValue).text;

  if(_value == value) break;

  }

  if(i != this.nodeList.length)

  {

  this.select(i);

  }

  else

  this.reset();

  }

  DropDownListx.prototype._select=function(index)//不響應事件的副本

  {

  if(index == -1)

  this.reset();

  else

  {

  var _td = document.getElementById(this.id + "_td_" + this.selectedIndex + "_" + this.parent.id);

  if(_td)

  {

  _td.style.backgroundColor = "";

  _td.style.color = "";

  }

  //this.nodeList = this.dataSource.documentElement.childNodes;

  this.selectedIndex = index;//被選中的索引

  this.selectedValue = this.attributed?this.nodeList.item(index).getAttribute(this.mainValue):this.nodeList.item(index).selectSingleNode(this.mainValue).text;

  this.selectedText = this.attributed?this.nodeList.item(index).getAttribute(this.mainText):this.nodeList.item(index).selectSingleNode(this.mainText).text;

  this.value = this.selectedValue;

  this.text = this.selectedText;

  this.parent.value = this.selectedText;

  try

  {

  this.table.rows.item(index).cells.item(0).focus();

  this.table.rows.item(index).cells.item(0).style.backgroundColor = "red";

  this.table.rows.item(index).cells.item(0).style.color = "blue";

  this.parent.focus();

  }catch(ex){}

  }

  }

  DropDownListx.prototype._selectByName=function(name)//不響應事件的副本

  {

  if(name == null || name == "")

  {

  this.reset();

  return;

  }

  for(var i = 0;i<this.nodeList.length;i++)

  {

  var _name = this.attributed?this.nodeList.item(i).getAttribute(this.mainText):this.nodeList.item(i).selectSingleNode(this.mainText).text;

  if(_name == name) break;

  }

  if(i != this.nodeList.length)

  {

  this._select(i);

  }

  else

  this.reset();

  }

  DropDownListx.prototype._selectByValue=function(value)//不響應事件的副本

  {

  if(value == null || value == "")

  {

  this.reset();

  return;

  }

  for(var i = 0;i<this.nodeList.length;i++)

  {

  var _value = this.attributed?this.nodeList.item(i).getAttribute(this.mainValue):this.nodeList.item(i).selectSingleNode(this.mainValue).text;

  if(_value == value) break;

  }

  if(i != this.nodeList.length)

  {

  this._select(i);

  }

  else

  this.reset();

  }

  //---------------------------------------------DropDownListx-vsdoc.js------------------------

  /// <reference name="MicrosoftAjax.js"/>

  function DropDownListx(parent, id)

  {

  /// <summary>

  /// 自定义的下拉框类

  /// </summary>

  /// </param>

  /// <param name="parent" type="Objec">

  /// 下柆框的父控件,只能是文本输入框元素;

  /// </param>

  /// </param>

  /// <param name="id" type="String">

  /// 下拉框的ID的文本

  /// </param>

  }

  DropDownListx.prototype =

  {

  getPosition: function()

  {

  /// <summary>

  /// 重新获取下拉框的位置,因为parent的位置可能会变动

  /// </summary>

  },

  show: function()

  {

  /// <summary>

  /// 显示下拉框

  /// </summary>

  },

  listData: function()

  {

  /// <summary>

  /// 绘制下拉框

  /// </summary>

  },

  hide: function()

  {

  /// <summary>

  /// 隐藏下拉框

  /// </summary>

  },

  setSource: function(d)

  {

  /// <summary>

  /// 设置下拉框xml数据源

  /// </summary>

  /// <param name="d" type="Objec">

  /// 要指定的下拉框的xml数据源

  /// </param>

  },

  setChildNodes: function(nodes)

  {

  /// <summary>

  /// 设置下拉框xml数据源

  /// </summary>

  /// <param name="nodes" type="Objec">

  /// 要指定的下拉框的xml节点集

  /// </param>

  },

  filter: function(text)

  {

  /// <summary>

  /// 对下拉框进行全局筛选

  /// </summary>

  /// <param name="text" type="String">

  /// 要查找的文枉

  /// </param>

  },

  getNodeValue: function(nodeName)

  {

  /// <summary>

  /// 返回选中节点对应的子节点的值

  /// </summary>

  /// <param name="nodeName" type="String">

  /// 子节点名

  /// </param>

  },

  reset: function()

  {

  /// <summary>

  /// 重置下拉框

  /// </summary>

  },

  select: function(index)

  {

  /// <summary>

  /// 按索引进行选择

  /// </summary>

  /// <param name="index" type="Int">

  /// 索引值

  /// </param>

  },

  selectByName:function(name)

  {

  /// <summary>

  /// 按文本进行选择

  /// </summary>

  /// <param name="name" type="String">

  /// 要选择的文本,此值将会与mainText属性所对应的节点进行对比

  /// </param>

  },

  selectByValue:function(value)

  {

  /// <summary>

  /// 按值进行选择

  /// </summary>

  /// <param name="value" type="String">

  /// 要选择的值,此值将会与mainValue属性所对应的节点进行对比

  /// </param>

  },

  _select:function(index)

  {

  /// <summary>

  /// 按索引进行选择,select方法不响应事件的副本

  /// </summary>

  /// <param name="index" type="Int">

  /// 索引值

  /// </param>

  },

  _selectByName:function(name)

  {

  /// <summary>

  /// 按文本进行选择,selectByName方法不响应事件的副本

  /// </summary>

  /// <param name="name" type="String">

  /// 要选择的文本,此值将会与mainText属性所对应的节点进行对比

  /// </param>

  },

  _selectByValue:function(value)

  {

  /// <summary>

  /// 按值进行选择,selectByValue方法不响应事件的副本

  /// </summary>

  /// <param name="value" type="String">

  /// 要选择的值,此值将会与mainValue属性所对应的节点进行对比

  /// </param>

  }

  }