【jquery模仿net控件】简单的dropdownlist与datalist
来源:互联网 发布:js实现视频播放 编辑:程序博客网 时间:2024/05/01 09:15
各位大哥晚上好,好久不见。小弟实习了三个月了,由.net转成了java,工作期间正在努力学习。
但是有一点非常痛苦,我不止一次听到一个声音,”.net真的很简单,我原来也学过。直接拖就是了......“
啊!!!感觉好没有技术含量啊!莫法,小弟技术不行,无力辩驳什么。
并且就技术层次本身来说,不论我确实还有很多路要走,就不多说了。
起因
我们最近在做一个项目,其中核心模块需要用到类似于igoogle中那种小工具的功能,当时经过众人商议,
最后决定用jquery写控件。
控件!!!好机会啊!我发现项目需要的功能和.net中的datalist真的非常像,于是很想插进去.......
但是,我那浅薄的水平,以及我那悲剧的实习生头衔,在其他同事面前确实不大说得上话。
最后眼睁睁看着别人写了1more js代码,然后让我去读。
呵呵,不是那个前辈代码写的不好,相反我在他的代码中学了很多东西,当然是带着极其抵触的情绪在努力的看!
总觉得这也不好,那也不好,甚至有时候在抠人家命名规范的问题,总是想推翻一点加上自己的思路......
说到这里,我深刻的感觉团队合作,团队交流,团队协作真的很重要!
你有一个想法,你要如何表达自己的思路,如何写出代码,如何让别人接受你的想法,接受你的代码,
甚至让别人帮助你充实你的想法,真的是一门大学问!
你若是做了一个东西,确实不错,但是你不表现的谦虚,其他同事必定不会买账,根本不会认同你的想法。
而且,一个你觉得很好的点子,在人家的分析后,肯定会发现很多问题,那就要看你如何获得人家的认同与帮助了!
项目过程
就那前辈的代码,我其实发现了一些问题,项目过程中他的代码也确实遇到了一点问题,主要原因就是代码除他之外,没人想去动。
然后站在设计模式的高度来看,他的代码可维护性,可扩展性有点问题,当然我设计模式看了一次也忘得车不多了。
最后在学习前辈的代码,再加上.net控件思路的高度,我自己花了点时间写了两个控件模拟.net中的dropdownlist与datalist。
再次交出代码,抛砖引玉,请各位大哥弄点更好的东西出来吧!!!
因为我也是才学js,代码写的不好,请各位大哥提点下吧!
Dropdownlist
一、效果图()
因为这个控件是练手的,我需要的是datalist,所以就算起一个探索作用,没有写太多。
其功能就算想模拟.net中的控件,根据不同数据源,生成不同的代码。
最主要是想把事件控制权交出来,让使用这个控件的人不用去关注控件本身,(这也是前辈的主要问题)
二、简单代码
核心代码:
var item = function (value, text) { this.attribute = { id: '', value: value ? value : '', text: text ? text : '', title: '', selected: '' }; this.htmlElement = null; this.callBack = { onClick: null };}item.prototype.bindEvent = function () { var sender = this; // alert(sender.dataSource); var element = sender.htmlElement; if (sender.callBack.onClick) { element.unbind("click"); element.bind("click", function () { sender.callBack.onClick.call(sender); }); }}var dropDownList = function (id) { this.attribute = { id: id }; this.style = { width: '', height: '' }; this.callBack = { onSelectedChanged: null, onClick:null }; this.htmlElement = null; this.items = []; this.selectedValue = ''; this.selectedItem = {}; this.dataSourceType = ''; this.dataSource = {}; //应该支持不同数据源 this.dataTextField = ''; this.dataValueField = ''; this.dataTitleField = '';}dropDownList.prototype.bindEvent = function () { var sender = this; // alert(sender.dataSource); var element = sender.htmlElement; if (sender.callBack.onSelectedChanged) { element.unbind("change"); element.bind("change", function () { sender.callBack.onSelectedChanged.call(sender); }); } if (sender.callBack.onClick) { element.unbind("click"); element.bind("click", function () { sender.callBack.onClick.call(sender); }); }}dropDownList.prototype.dataBind = function (element) { var sender = this; sender.htmlElement = $('<select id="' + sender["attribute"]["id"] + '"></select>'); $.each(sender.dataSource, function (itemKey, itemValue) { // alert(itemKey + ":" + itemValue); var _item = new item(); _item["attribute"]['value'] = itemValue[sender['dataValueField']]; _item["attribute"]['text'] = itemValue[sender['dataTextField']]; _item["attribute"]['title'] = itemValue[sender['dataTitleField']]; sender.items.push(_item); sender.insertItem(_item); }); //呈现前,样式加载 sender.styleLoad(); element.append(sender.htmlElement);}dropDownList.prototype.styleLoad = function () { var sender = this; var element = sender.htmlElement; $.each(sender["style"], function (styleKey, styleValue) { // alert(styleKey + ":" + styleValue); if (styleValue) { element.css(styleKey, styleValue); } });}dropDownList.prototype.insertItem = function (optionItem) { var sender = this; var element = sender.htmlElement; var itemSender = optionItem; // alert(element["id"]); var option = $('<option></option>'); var optrinAtrribute = optionItem["attribute"]; var id = optrinAtrribute["id"]; var value = optrinAtrribute["value"]; var text = optrinAtrribute["text"]; var title = optrinAtrribute["title"]; var selected = optrinAtrribute["selected"]; if (id && id.length > 0) { option.attr("id", id); } if (value && value.length > 0) { option.attr("value", value); } if (title && title.length > 0) { option.attr("title", title); } if (selected && selected.length > 0) { option.attr("selected", selected); } if (text && text.length > 0) { option.text(text); } itemSender.htmlElement = option; element.append(option);}
前端调用:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title></title> <script src="scripts/jquery-1.4.1.js" type="text/javascript"></script> <script src="js/dropDownList.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { var data = []; for (var i = 0; i < 3; i++) { data[i] = {}; data[i]["v"] = "value_" + i.toString(); data[i]["t"] = "text_" + i.toString(); } var $div = $("#divwl"); var drop1 = new dropDownList("drop1"); drop1.dataSource = data; drop1.dataValueField = "v"; drop1.dataTextField = "t"; drop1.dataTitleField = "v"; drop1.dataBind($div); for (var i = 0; i < 3; i++) { var v = "inertValue_" + i; var t = "insertText_" + i; var _item = new item(v, t); drop1.insertItem(_item); } drop1.style.width = '300px'; drop1.style.height = '50px'; drop1.style.background = 'green'; drop1.styleLoad(); var funClick = function () { var dropSender = this.htmlElement; var selectedValue = dropSender.val() var $div = $("#text"); $div.html(selectedValue); }; var funChange = function () { var dropSender = this.htmlElement; var selectedValue = dropSender.val() alert(selectedValue); }; drop1.items[1].callBack.onClick = funClick; drop1.items[1].bindEvent(); drop1.callBack.onSelectedChanged = funChange; drop1.bindEvent(); }); </script></head><body> <div id="divwl"> </div> <div id="text"> </div> </body></html>
Datalist
好了,开始进入本文重点,这也是项目真正需要的,这个版本没有完全完成,在得到大家意见后再改吧!
一、效果图:
所用数据源:
二、思路
原来也读过.net 控件开发一书,对控件开发知识有个大概了解,所以做起来时候还是比较顺手。
① datalist首先提供了一个公共的模板,就是itemtemplate中可以写任何代码包括数据绑定代码,
然后依次循环调用,所以我觉得这个控件需要一个模板保存类似于.net中的html代码,以及数据绑定代码。
当然,我们不可能写在js代码中,于是出现了一下模板文件:
itemTemplate.spt:
<table> <tr> <td> 新闻ID </td> <td> {%newsId%} </td> </tr> <tr > <td > 新闻标题 </td> <td> {%newsName%} </td> </tr> <tr > <td> 新闻摘要 </td> <td> <input id="contentMore" value="详情" type="button"/> </td> </tr> <tr > <td colspan="2" style=" display:none;" class="content"> {%newsContent%} </td> </tr></table><hr/>
{%newsName%} 是模拟Eval("")的写法,后期作为数据绑定使用
② 然后每次循环生成具体的模板js代码如下:itemTemplate.js
/// <reference path="../scripts/jquery-1.4.1.js" />var itemTemplate = function () { //源模板文本,现在为itemTemplate.spt //可能是文本,可能是js文件,可能是字符串 //最终形成字符串传给htmlTemplateText this.htmlTemplateText = ""; //最终会形成一独立html字符串,dom结构的标签 this.htmlElement = null; this.idPrefix = "id_"; //id前缀 this.parentId = ""; this.id = ""; this.event = { onClick: null, onMousemove: null }; //将要执行 // this.evetElementSource = {}; this.elementEvent = null;};itemTemplate.prototype.getItemElement = function (elementKey) { var sender = this; var id = "#" + sender.id + " " + elementKey; var element = $(id); return element;}//elementKey #id、 .className、 htmlElementitemTemplate.prototype.bindElementEvent = function (elementKey, eventType, funcName) { var sender = this; var id = "#" + sender.id + " " + elementKey; var element = $(id); if (funcName) { element.unbind(eventType); element.bind(eventType, function () { funcName.call(sender); }); }}//elementKey #id、 .className、 htmlElementitemTemplate.prototype.bindAllElementEvent = function () { var sender = this; var itemElementEvents = sender.elementEvent; // alert(element+"=="+id); //数据项元素事件绑定 $.each(itemElementEvents, function (eventObjKey, eventObj) { var elementKey = eventObj.elementKey; var eventType = eventObj.eventType; var funcName = eventObj.funcName; sender.bindElementEvent(elementKey, eventType, funcName); });}itemTemplate.prototype.bindEvent = function () { var sender = this; var element = sender.htmlElement; var events = sender.event; $.each(events, function (eventKey, funcName) { // alert(funcKey + "---" + funcValue); if (funcName) { var _event = eventKey; _event = _event.substring(2, _event.length); _event = _event.toLowerCase(); element.unbind(_event); element.bind(_event, function () { funcName.call(sender); }); } });};itemTemplate.prototype.load = function (itemIndex, itemDataSource) { var sender = this; var id = sender.parentId + "_" + sender.idPrefix + itemIndex; sender.id = id; var element = $("<div id='" + id + "'></div>"); var html = ""; var _templateText = sender.htmlTemplateText; tempHtm = _templateText; $.each(itemDataSource, function (i, item) { var id = item; var regStr = "/\\{%" + i + "%\\}/g"; var reg = eval(regStr); tempHtm = tempHtm.replace(reg, item); }); html = tempHtm; element.append($(html)) sender.htmlElement = element; sender.bindEvent();};
技术细节便不说了,其主要采用正则表达式方式替换相应内容,所以完全根据我们提供的数据源而定:
③ 外层datalist代码:dataList.js
/// <reference path="../scripts/jquery-1.4.1.js" />/*思考:1 如何给数据项某个html标签添加事件因为我们并不知道生成的dom树是什么,所以模板里面的html标签无法绑定事件,暂时只能后期绑定*//* 控件生成流程*/var dataList = function (id, templateUrl) { this.attribute = { id: id }; this.style = { width: "", height: "" }; this.itemEvent = { onClick: null, onDblclick: null, onKeydown: null, onKeypress: null, onKeyup: null, onMousedown: null, onMousemove: null, onMouseout: null, onMouseover: null, onMouseup: null }; this.itemElementEvent = {}; // this.itemElementEvent = { // one: { // elementKey: "", // eventType: "", // funcName: null // } // }; this.htmlElement = null; this.templateUrl = templateUrl ? templateUrl : ""; //提供项目模板地址 this.htmlTemplateText = ""; this.items = []; this.dataSource = {}; //应该支持不同数据源};dataList.prototype.init = function () { var sender = this; var templateUrl = sender.templateUrl; if (!templateUrl || templateUrl.length == 0) templateUrl = "itemTemplate/itemTemplate.spt"; this.htmlTemplateText = getAjaxStr(templateUrl); var htmlElement = $("<div id='" + sender.attribute.id + "'></div>"); sender.htmlElement = htmlElement;};dataList.prototype.dataBind = function (element) { this.init(); var sender = this; var templateText = sender.htmlTemplateText; var itemEvent = sender.itemEvent; var itemElementEvents = sender.itemElementEvent; //需要替换itemTemplate var itemIndex = 0; $.each(sender.dataSource, function (dataKey, dataValue) { var _item = new itemTemplate(); _item.parentId = sender.attribute.id; _item.htmlTemplateText = templateText; _item.event = itemEvent; _item.elementEvent = itemElementEvents; //传递父ID ,当前模板编号,源模板,当前项数据项源,事件绑定源 _item.load(itemIndex, dataValue); var _itemElement = _item.htmlElement; sender.items.push(_item); sender.insertDomItem(_itemElement); itemIndex++; }); //呈现前,样式加载 sender.styleLoad(); element.append(sender.htmlElement); //模板中的html标签的事件绑定 var items = sender.items; $.each(items, function (i, item) { item.bindAllElementEvent(); });};dataList.prototype.styleLoad = function () { var sender = this; var element = sender.htmlElement; $.each(sender.style, function (styleKey, styleValue) { // alert(styleKey + ":" + styleValue); if (styleValue) { // alert(element); element.css(styleKey, styleValue); } });}dataList.prototype.insertDomItem = function (domItem) { var sender = this; var element = sender.htmlElement; element.append(domItem);};//dataList.prototype.bindItemEvent = function (domItem) {// var sender = this;// var element = sender.htmlElement;// element.append(domItem);//};//dataList.prototype.bindEvent = function () {// var sender = this;// var element = sender.htmlElement;// var events = sender["event"];// $.each(events, function (eventKey, funcName) {// // alert(funcKey + "---" + funcValue);// if (funcName) {// var _event = eventKey;// _event = _event.substring(2, _event.length);// _event = _event.toLowerCase();// element.unbind(_event);// element.bind(_event, function () {// funcName.call(sender);// });// }// });//};//异步获取文件function getAjaxStr(url) { var templateStr = ""; $.ajax({ url: url, async: false, dataType: "html", success: function (result) { templateStr = result; if (templateStr) return templateStr; }, error: function (e) { alert("模板加载错误:" + e.toString()); } }); return templateStr;}
③ 前台调用界面代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title></title> <script src="scripts/jquery-1.4.1.js" type="text/javascript"></script> <script src="js/itemTemplate.js" type="text/javascript"></script> <script src="js/dataList.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { var dataSource = {}; $.ajax({ type: "post", url: "Ajax.aspx", type: "json", async: false, success: function (data) { dataSource = data; } }); var $divHtml = $("#html"); var $div = $("#wl"); var $div1 = $("#wl1"); var itemElementEvents = { contentClick: { elementKey: "#contentMore", eventType: "click", funcName: contentMoreClick } }; var list = new dataList("divwl"); list.itemEvent.onMousemove = itemmousemove; list.itemEvent.onMouseout = itemmouseout; list.itemElementEvent = itemElementEvents; list.style.width = "700px"; list.dataSource = dataSource; list.dataBind($div); function contentMoreClick() { var sender = this; var newsContent = sender.getItemElement(".content"); var contentMore = sender.getItemElement("#contentMore"); if (newsContent.css("display") == "none") { contentMore.attr("value", "隐藏"); newsContent.css("display", ""); } else { contentMore.attr("value", "详情"); newsContent.css("display", "none"); } } function itemmousemove() { var sender = this; var $ee = sender.htmlElement; $ee.css("background", "Gray"); } function itemmouseout() { var sender = this; var $ee = sender.htmlElement; $ee.css("background", "white"); } }); </script></head><body> <div id="html" style="display: block"> </div> <div id="wl"> </div> <div id="wl1"> </div></body></html>
大概代码如上,看一下调用界面基本知道如何使用的。
在此我有个没有解决的问题,请各位大哥帮下忙:
除模板之中的html dom 结构没有前期事件绑定外,其他生成的dom都是在展现前便绑定事件:
//呈现前,样式加载 sender.styleLoad(); element.append(sender.htmlElement); //模板中的html标签的事件绑定 var items = sender.items; $.each(items, function (i, item) { item.bindAllElementEvent(); });
其实这个代码最先是写在itemTemplate.js文件中的,在没有将dom append到页面中,但是因为dom结构没有生成,我无法通过除以上的方法找到
对应html标签,所有无法做事件绑定,这里把我弄模糊了。各位大哥有兴趣看了代码便和我说说吧,代码会跟进。
今天又更新了一点代码,有点变化,现在先弄上datalist嵌套的用法,具体的代码后面点看有没有需要弄出来
效果:其实就是新闻类型嵌套一个新闻列表
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title></title> <script src="scripts/jquery-1.4.1.js" type="text/javascript"></script> <script src="js/itemTemplate.js" type="text/javascript"></script> <script src="js/dataList.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { var dataItems = {}; $.ajax({ type: "post", url: "Ajax.aspx?sql=select top 5 * from Item where ItemKind=1 ", type: "json", async: false, success: function (data) { dataItems = data; } }); var $div = $("#wl"); var listItem = new dataList("newsItem", "itemTemplate/items.spt"); var itemElementEvents = { loadItemNews: { elementKey: "#itemNews", eventType: "ready", funcName: elementDatabind } }; listItem.itemElementEvent = itemElementEvents; listItem.dataSource = dataItems; listItem.dataBind($div); function elementDatabind() { var sender = this; var $itemId = sender.getItemElement("#itemId"); var $itemNews = sender.getItemElement("#itemNews"); var listItemNews = new dataList("news", "itemTemplate/itemTemplate.spt"); var _itemElementEvents = { contentClick: { elementKey: "#contentMore", eventType: "click", funcName: contentMoreClick } }; var id = $itemId.html(); var s = $itemNews.html(); var dataNews = {}; $.ajax({ type: "post", url: "Ajax.aspx?sql=select top 3 newsId,newsName, newsContent from news where itemId='" + id + "' ", type: "json", async: false, success: function (data) { dataNews = data; } }); listItemNews.itemEvent.onMousemove = itemmousemove; listItemNews.itemEvent.onMouseout = itemmouseout; listItemNews.itemElementEvent = _itemElementEvents; listItemNews.dataSource = dataNews; listItemNews.dataBind($itemNews); } function contentMoreClick() { var sender = this; var newsContent = sender.getItemElement(".content"); var contentMore = sender.getItemElement("#contentMore"); if (newsContent.css("display") == "none") { contentMore.attr("value", "隐藏"); newsContent.css("display", ""); } else { contentMore.attr("value", "详情"); newsContent.css("display", "none"); } } function itemmousemove() { var sender = this; var $ee = sender.htmlElement; $ee.css("background", "Gray"); } function itemmouseout() { var sender = this; var $ee = sender.htmlElement; $ee.css("background", "white"); } }); </script></head><body> <div id="wl"> </div></body></html>
等以后代码完善了,我在整理发出吧。
- 【jquery模仿net控件】简单的dropdownlist与datalist
- 【jquery模仿net控件】简单的datalist控件更新,及其简单应用
- 【jquery模仿net控件】简单分页控件1.0,附上gridview使用测试
- DataList 中DropDownList取隐藏控件label的值
- 如何动态绑定DataList 的EditItemTemplate中的控件DropDownList
- asp.net 中的DropDownList控件的前台与后台
- 模仿JQuery的简单Demo
- 【jquery模仿net控件】初步GridView模型实现,及其简单应用
- 无敌的datalist控件 asp.net
- ASP.NET的DataList和Repeater控件
- ASP.NET 2.0中DataList控件与GridView控件的使用实例
- DropDownList控件 与TextBox控件的组合
- asp.net的DropDownList控件的使用
- ASP.NET - DataList 控件
- 一个简单的级联DropdownList自定义控件
- 关于简单控件DropDownList的使用.
- jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist
- asp.net DropDownList 控件
- 在java中实现类似于.net中的DataTable,请各位看看,这种方法可行吗?
- 在Java中实现.net中DataTable功能以及操作双数据库的List连接问题解决方案探究
- Java中实现DataTable工具类,并利用其实现简单分页控件。
- 只言碎语总结,今后发展web前端,并分享两个项目难点解决方案。
- 工作四天的体会,公司就是公司和学校果然不同!!!
- 【jquery模仿net控件】简单的dropdownlist与datalist
- Linux下,“ORA-01031: insufficient privileges”的处理
- 【jquery模仿net控件】简单的datalist控件更新,及其简单应用
- 【jquery版.net控件—dropdownlist】附源码,欢迎大家指点、指正、拍砖!!!
- 【jquery仿dataList】应用之——模仿igoogle【定制化、拖动排序,最大化、分屏】
- 【jquery仿datalist的一个问题,求助】——设置每行显示几列,块状DIV的解决办法
- 【jquery仿dataList——性能优化】模板预编译思想提高性能10倍以上!!!
- 【求勿删】【求助!!!】如何破解.net的viewerstate??如何将隐藏的服务器控件显示出来
- 【jquery模仿net控件】初步GridView模型实现,及其简单应用