Namespace.register("U.MD.UI.City"); U.MD.UI.City.contorlNode = null; //存放元素与变量的json全局变量 未赋值 U.MD.UI.City.usedCity = null; //存放常用市数据的变量 U.MD.UI.City.province = null; //存放省数据的变量 U.MD.UI.City.city = {}; //存放市数据的变量 U.MD.UI.City.area = {}; //存放区数据的变量 /** * [Control description] 城市控件接口 * @param {[类的名称]} eleClass [需要使用城市控件的input的类名] */ U.MD.UI.City.Control = function (eleClass) { var _city = U.MD.UI.City; //简写命名空间 var _flag = _city.addHtml(); //将控件html代码添加到body上,如若存在则返回true; if (_flag) { //如若控件添加过html代码,则表示js功能已经添加过 因此可以返回 return; } _city.contorlNode = { //存放节点 与 变量 的json对象 "hidden": "U_MD_UI_City_hidden", //class样式名 由于太长赋值给变量 _hidden 控制元素display的样式 "inputAll": $("." + eleClass), //获取所有input节点 "inputNode": null, //判断是哪个表单点击的 为赋值所用 "cityBox": $("#U_MD_UI_City_cityBox")[0], //城市控件总盒子节点 "liTemplate": $("#U_MD_UI_City_liTemplate")[0], //要clone的li的模板 "usedCityMenu": $("#U_MD_UI_City_usedCityMenu")[0], //常用市菜单按钮 "provinceMenu": $("#U_MD_UI_City_provinceMenu")[0], //省菜单按钮 "cityMenu": $("#U_MD_UI_City_cityMenu")[0], //市菜单按钮 "areaMenu": $("#U_MD_UI_City_areaMenu")[0], //区菜单按钮 "usedCityCont": $("#U_MD_UI_City_usedCityCont")[0], //常用市内容区域 "provinceCont": $("#U_MD_UI_City_provinceCont")[0], //省内容区域 "cityCont": $("#U_MD_UI_City_cityCont")[0], //市内容区域 "areaCont": $("#U_MD_UI_City_areaCont")[0], //区内容区域 "MenuAllNode": $("[data-city-mark]") //所有菜单节点 }; _city.init(); //函数初始化 }; /** * 添加html代码,并且判断html代码是否存在 若存在 则不添加 */ U.MD.UI.City.addHtml = function () { var _cityBox = $("#U_MD_UI_City_cityBox"); if (!(_cityBox.length)) { _cityBox = $$("div", { id: 'U_MD_UI_City_cityBox', className: 'U_MD_UI_City_cityBox U_MD_UI_City_hidden' }, document.body); _cityBox.innerHTML += U.MD.UI.City.htmlTemplate; return false; } _cityBox.removeClass('U_MD_UI_City_hidden'); return true; }; /** * 函数初始化 */ U.MD.UI.City.init = function () { var _city = U.MD.UI.City; //简写命名空间 _city.inputEvent(); //添加监听事件: 点击表单显示城市控件并发送后台请求数据 与 点击body区域隐藏城市控件 _city.menuEvent(); //添加监听事件: 点击菜单显示对应的内容 }; /** * 为表单添加点击事件 */ U.MD.UI.City.inputEvent = function () { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 for (var i = 0, len = _node.inputAll.length; i < len; i++) { $(_node.inputAll[i]).bind("click", function (e) { _city.getUsedCity(); //获取常用城市数据并打印 _node.inputNode = e.srcElement; //由于IE的this在这里指向window 因此 需要将事件元素 赋值给_inputNode变量 _city.Method.insertAfter(_node.cityBox, _node.inputNode); //将控件html代码 插入到 表单下面的节点 _node.cityBox.style.top = _node.inputNode.offsetTop + _node.inputNode.offsetHeight + "px"; //调整控件的top位置 _node.cityBox.style.left = _node.inputNode.offsetLeft + "px"; //调整控件的left位置 $(_node.cityBox).removeClass(_node.hidden); //删除掉hidden的class名 目的: 去除掉display为none的样式 U.UF.EV.stopBubble(e); //阻止事件冒泡 防止被body的事件覆盖 }); } $(document).bind('click', function () { //点击body时 隐藏城市控件 $(_node.cityBox).addClass(_node.hidden); //添加掉hidden的class名 目的: 添加display为none的样式 }); $(_node.cityBox).bind('click', function (e) { //防止点击城市控件时 被body的事件覆盖而隐藏 因此加上防止冒泡处理 U.UF.EV.stopBubble(e); //阻止事件冒泡 }); }; /** * 为每个菜单添加点击事件 */ U.MD.UI.City.menuEvent = function () { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 for (var i = 0, len = _node.MenuAllNode.length; i < len; i++) { //循环所有菜单元素 var _el = _node.MenuAllNode[i]; //获取每个菜单 赋值给变量el $(_el).bind('click', function () { //添加点击事件 _city.menuClassControl(this, "U_MD_UI_City_menuChecked", "data-city-mark", _node.hidden); //为每个菜单添加对应每个区域的事件 }); if (_el.id === "U_MD_UI_City_provinceMenu") { //如果点击的是 省/直辖市 菜单 则获取对应的数据 $(_el).bind('click', function () { _city.getProvince(); //省/直辖市菜单的点击事件 获取数据 }) } } }; /** * 获取数据常用市的所有数据 */ U.MD.UI.City.getUsedCity = function () { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 if (!_city.usedCity) { //如果 常用市(_city.usedCity) 无数据 则发送请求到后台获取数据 并打印出来 U.A.Request("http://cd.1473.cn/php", ["db.1473.cn", "UseStudio_Controls", "City_UsedCity"], function (r) { _city.usedCity = r.value; _city.allDataPrint(_node.usedCityMenu, _city.usedCity, _node.liTemplate, "usedCity", _node.usedCityCont); //打印数据 }); } }; /** * 获取省/直辖市的所有数据 */ U.MD.UI.City.getProvince = function () { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 if (!_city.province) { //如果 省/直辖市(_city.province) 无数据 则发送请求到后台获取数据 并打印出来 U.A.Request("http://cd.1473.cn/php", ["db.1473.cn", "UseStudio_Controls", "City_Province"], function (r) { _city.province = r.value; _city.allDataPrint(_node.provinceMenu, _city.province, _node.liTemplate, "province", _node.provinceCont); //打印数据 }); } }; /** * 通过code 获取市的所有数据 * @param code 省级的id */ U.MD.UI.City.getCity = function (code) { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 if (!_city.city[code]) { //_city.city = json 而_city.city[code]则是对应的数组值 例如:我点击广东后 获取到了广东的id 则我要通过 广东的id 获取下级的市数据 因此如果json中没有该值 则向后台发送请求获取 _city.menuClassControl(_node.cityMenu, "U_MD_UI_City_menuChecked", "data-city-mark", _node.hidden); //相当于点击菜单 将城市的菜单于内容 "先"显示出来 再加载数据 防止多次点击 U.A.Request("http://cd.1473.cn/php", ["db.1473.cn", "UseStudio_Controls", "City_PidFind", code, 1], function (r) { _city.city[code] = r.value; //_city.city = {} //r.value = [{},{},{}] //为了能判断该code下是否有数据 因此需要在_city.city下添加一个 以code为键名 r.value为值的数组 //例如:_city.city = {} code = 123 r.value = [{a:1},{a:1},{a:1}] 最后会变成 _city.city = {123:[{a:1},{a:1},{a:1}]} _city.allDataPrint(_node.cityMenu, _city.city[code], _node.liTemplate, "city", _node.cityCont); //打印数据 }); } else { //如果json下有数据 则直接打印该数据 _city.menuClassControl(_node.cityMenu, "U_MD_UI_City_menuChecked", "data-city-mark", _node.hidden); //相当于点击菜单 将城市的菜单与内容区域 显示出来 _city.allDataPrint(_node.cityMenu, _city.city[code], _node.liTemplate, "city", _node.cityCont); //打印数据 } }; /** * 通过code 获取区级的所有数据 函数的意思可参看上面getCity的注释 * @param code 参数为市级的id */ U.MD.UI.City.getarea = function (code) { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 if (!_city.area[code]) { _city.menuClassControl(_node.areaMenu, "U_MD_UI_City_menuChecked", "data-city-mark", _node.hidden); //相当于点击菜单 将城市的菜单于内容 "先"显示出来 再加载数据 防止多次点击 U.A.Request("http://cd.1473.cn/php", ["db.1473.cn", "UseStudio_Controls", "City_PidFind", code, 2], function (r) { _city.area[code] = r.value; _city.allDataPrint(_node.areaMenu, _city.area[code], _node.liTemplate, "area", _node.areaCont); }); } else { _city.menuClassControl(_node.areaMenu, "U_MD_UI_City_menuChecked", "data-city-mark", _node.hidden); //相当于点击菜单 将城市的菜单于内容 "先"显示出来 再加载数据 防止多次点击 _city.allDataPrint(_node.areaMenu, _city.area[code], _node.liTemplate, "area", _node.areaCont); } }; /** * 打印传过来的数组json数据 * @param {[type]} menu [与之对应的菜单元素] * @param {[type]} data [是一个数组json] * @param {[type]} template [是一个li模板 clone用的] * @param {[type]} type [数据类型("province"、"usedCity"....) 为判断所用] * @param {[type]} parent [父节点("cityCont,areaCont...") 也叫做内容区域 ] */ U.MD.UI.City.allDataPrint = function (menu, data, template, type, parent) { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 var _len = data.length; //数组json的长度 var _menu = menu; //菜单元素 赋值给 _menu变量 for (var i = 0; i < _len; i++) { // 遍历 data数据(数组json) var _span = _city.dataPrint(data[i], template, type, parent); //单个数据打印 PS:由于data是一个 数组json([{a:1},{a:2},{a:3}]) 因此 需要将获取对应的数据 并添加在 对应的 parent(内容区域) 上 _span.onclick = function () { var _type = $(this).attr("data-city-type"); //获取点击的span标签的属于哪一类型 (比如: 点击省的数据 是 province 市的数据 则时 city) var _code = $(this).attr("data-city-code"); //获取数据编码 为寻找下一层所用 $(_menu.children[0]).addClass("U_MD_UI_City_menuoChecked"); //点击后为 对应的相对应的菜单添加红色小圆点样式 例如:点击省/直辖市菜单下的 广东后 省/直辖市就会多一个红色小圆点的样式 _menu.children[0].innerText = this.innerText; //改变对应菜单的名字为:点击数据的值 例如:点击"省/直辖市"菜单 下的广东 则 菜单的名字则变为 广东 PS: children[0] 为 li下的span标签 $(_menu).attr("data-city-res", this.innerText); //给自定义属性 data-city-res 添加为: 点击数据的值 PS: 为获取最终值给表单所用 _city.contClassControl(this, "U_MD_UI_City_Cont_ochecked"); //给所选的内容数据添加红色背景 并且删除同一内容区域拥有红色背景的其他元素 switch (_type) { //此处为 判断 点击 各类型数据需要做的动作 type为判断哪种类型 比如: type值为 "province" 则是 省/直辖市菜单下的 数据 点击这些数据后 就是要做的事情 case "province": _city.getCity(_code); //将数据的 code 值传入给 城市函数 来获取城市数据 PS: 获取市的数据需要获取他们的parentid 而code则是他们的parentid _city.initAllClass(_node.usedCityMenu); //点击省/直辖市下的数据的话 则初始化 常用市菜单 与 相对应的内容区域样式 break; case "usedCity": if (this.innerText === "重庆") { //由于重庆这个城市比较特殊 因此需要在常用市那将重庆转为省数据 _city.getCity(_code); } else { _city.getarea(_code); } //在将数据的 code 值传入给 城市函数 来获取城市数据 PS: 获取市的数据需要获取他们的parentid 而code则是他们的parentid _city.initAllClass(_node.provinceMenu); //点击常用市下的数据的话 则初始化 省/直辖市菜单 与 相对应的内容区域样式 break; case "city": _city.getarea(_code); //在将数据的 code 值传入给 区函数 来获取区数据 PS: 获取区的数据需要获取他们的parentid 而code则是他们的parentid break; case "area": _city.getRes("data-city-res"); //由于该控件是 省-市-区 因此 当点击区里的数据时 则调用获取最终值的函数 break; } } } }; /** * 打印单个数据api(创建节点,赋id 赋innerText 等等) * @param {[json对象]} data [json对象的数据] * @param {[元素]} template [需要clone的li模板] * @param {[字符串]} type [属于哪种城市类型] * @param {[元素]} parent [父节点] * @return {[元素]} [克隆完后的一条li下的span节点] */ U.MD.UI.City.dataPrint = function (data, template, type, parent) { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 var _liNode = _city.Method.clone(template), //克隆已建好的li模板 _spanNode = _liNode.children[0]; //获取li的span节点 var _shortName = data.short_name; //获取城市名字缩写 var _name = data.name; //获取名字全称 _liNode.id = type + data.id; //添加id _spanNode.innerText = _shortName; //添加文字内容 if (_shortName === "北京" || _shortName === "上海" || _shortName === "天津" || _shortName === "重庆") {//由于这4个城市的 缩写 和省的名字相同 因此 需要将数据名 改成name 详见数据库 if (parent.id === "U_MD_UI_City_cityCont") { _spanNode.innerText = _name; //添加文字内容 } } if (parent.id === "U_MD_UI_City_areaCont") { //由于区级数据库 的缩写少了一个区 例如:显示出来的 龙岗区 被缩成 龙岗 因此需要将值等于他们的全称 _spanNode.innerText = _name; //添加文字内容 } _spanNode.id = "span_" + type + data.id; $(_spanNode).attr("data-city-code", data.id); //添加自定义属性 编号 $(_spanNode).attr("data-city-type", type); //添加自定义属性 类型 parent.appendChild(_liNode); //添加到parent节点上 return _spanNode; //返回该元素 }; /** * 添加选中时的class 并删除已有该class的元素 * @param {[元素]} el [点击菜单的元素] * @param {[字符串]} cs [选中菜单时的class] * @param {[字符串]} dataattr [菜单的自定义属性 与 对应内容区域的id相同] * @param {[字符串]} hiddenCs [对应内容区域的class] */ U.MD.UI.City.menuClassControl = function (el, cs, dataattr, hiddenCs) { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 var _oEl = $("." + cs)[0]; //找到拥有该class的元素 if (_oEl) { $(_oEl).removeClass(cs) }; //如果找的到该元素 则删除此元素的class $(el).addClass(cs); //为el元素添加该class var _oElCont = $("#" + $(_oEl).attr(dataattr))[0]; //找到拥有该class的菜单元素的自定义属性的值 并找到对应区域块的元素(区域块元素的id 与 自定义属性的值相等) var _elCont = $("#" + $(el).attr(dataattr))[0]; //同上 找到点击菜单元素的自定义属性的值 $(_oElCont).addClass(hiddenCs); //添加名为hiddenCs 的className (添加与删除 display为none) $(_elCont).removeClass(hiddenCs); //elCont元素的display为block var _id = el.id; switch (_id) { //以下为点击菜单时所作出的不同执行命令 case "U_MD_UI_City_usedCityMenu": case "U_MD_UI_City_provinceMenu": //当为菜单常用市 或者 省直辖市时 将区 与 市菜单 与对应内容区域 清空初始化 $(_node.cityMenu).addClass(hiddenCs); $(_node.areaMenu).addClass(hiddenCs); $(_node.cityCont).addClass(hiddenCs); $(_node.areaCont).addClass(hiddenCs); _node.cityMenu.children[0].innerText = "请选择"; _node.areaMenu.children[0].innerText = "请选择"; _node.cityCont.innerHTML = ""; _node.areaCont.innerHTML = ""; $(_node.cityMenu).attr("data-city-res", ""); $(_node.areaMenu).attr("data-city-res", ""); break; case "U_MD_UI_City_cityMenu": //当为市菜单时 将 区菜单 与对应内容区域 清空初始化 $(el).removeClass(hiddenCs); $(_node.areaMenu).addClass(hiddenCs); $(_node.areaCont).addClass(hiddenCs); _node.areaMenu.children[0].innerText = "请选择"; _node.areaCont.innerHTML = ""; break; case "U_MD_UI_City_areaMenu": $(el).removeClass(hiddenCs); break; } }; /** * 内容区域的class 的控制函数 PS:添加红色背景的样式 * @param {[type]} el [所选中的数据元素] * @param {[type]} ocheckcs [所需要对el添加的样式] */ U.MD.UI.City.contClassControl = function (el, ocheckcs) { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 var _oEls = $("." + ocheckcs); //找到拥有该class的所有元素 var _type = $(el).attr("data-city-type"); //获取他们的该元素的类型 for (var i = 0, len = _oEls.length; i < len; i++) { //遍历oEls var _otype = $(_oEls[i]).attr("data-city-type"); if (_oEls[i] && _otype === _type) { //如果找的到该元素 并且还是同一内容区域的元素 则删除他的class 例如:(市内容区域下)点击深圳后 在点广州 则 广州的背景颜色为红色 深圳的背景颜色为初始颜色 $(_oEls[i]).removeClass(ocheckcs) } } $(el).addClass(ocheckcs); //为el元素添加该class }; /** * 此函数专门为 初始化 常用市 或者 省/直辖市的样式而写的 例如:点击常用市下的数据后 省/直辖市的菜单与对应的内容 样式初始化为不选中 * @param el 只能放 常用市菜单(元素) 和 省/直辖市菜单(元素) */ U.MD.UI.City.initAllClass = function (el) { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 el.className = "U_MD_UI_City_filled"; //将菜单li的样式初始化 U_MD_UI_City_filled无样式属性 摆设占位置用 el.children[0].className = ""; //将li里的span样式也初始化 $(el).attr("data-city-res", ""); //将span的自定义属性也初始化 var oEl = $(".U_MD_UI_City_Cont_ochecked"); //获取内容区域中被选中的span元素 for (var i = 0; i < oEl.length; i++) { $(oEl[i]).removeClass("U_MD_UI_City_Cont_ochecked"); //判断是否存在此元素 如果存在 则删除被选中的样式 } if (el.id === "U_MD_UI_City_provinceMenu") { //比如: 点完省/直辖市内容区域的数据时 传过来的el则会是常用市菜单元素 然后常用市菜单的innerText则会初始化回常用市 el.children[0].innerText = "省/直辖市"; } if (el.id === "U_MD_UI_City_usedCityMenu") { //同上 el.children[0].innerText = "常用市"; } }; /** * 通过获取自定义属性的值 查出最终值 * @param dataattr 自定义属性的名字 */ U.MD.UI.City.getRes = function (dataattr) { var _city = U.MD.UI.City; //简写命名空间 var _node = _city.contorlNode; //简写节点json名 var resAll = $("[" + dataattr + "]"); //获取所有拥有该自定义属性的元素 得到一个数组 var _arr = []; //声明一个空数组 存放最终值 for (var i = 0, len = resAll.length; i < len; i++) { //遍历所有自定义元素 var _val = $(resAll[i]).attr(dataattr); //获取他们的自定义值 if (_val) { //判断值是否存在 _arr.push(_val); //若存在 则将最终值依次添加到arr数组里 } } _node.inputNode.value = (_arr.join("-")); //最后分割数组用“-” 隔开 添加到表单上 $(_node.cityBox).addClass(_node.hidden); //最后隐藏控件 }; U.MD.UI.City.htmlTemplate = '
\n' + '\n' + '\n' + ' \n' + ' \n' + '