我的开源框架之Accordion控件
需求:
(1)实现手风琴面板控件,支持静态HTML与JSON方式创建控件
(2)支持远程加载数据
(3)支持面板激活、远程加载事件注册
(4)支持动态添加、删除项目
实现图例
客户代码
<div> <div style="padding-left:100px; padding-bottom:12px; float:left"> <div id="accordionContainer" style="width:300px;height:600px"> <div title="静态html" closable="true"> <p>项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1</p> <div id="text"> <h3>无题</h3> <p>月落湖面两清影,</p> <p>岸柳丝丝弄轻盈。</p> <p>此番凉意写不出,</p> <p>难画秋月一片晴。</p> </div> </div> <div title="iframe加载" isiframe="true" url="/innerpage.html" iconcls="icon-edit" closable="false"> 111 </div> <div title="远程HTML加载" datatype="html" url="/content.html" iconcls="icon-save" closable="true"> 32333 </div> </div> </div> </div> <script type="text/javascript"> var accordion; $(function () { accordion = $("#accordionContainer").accordion({ items: [{ title: '远程加载JSON数据', closable: false, iconcls: 'icon-print', actived: true,// 激活状态 url: 'testServer/jsonQuestTest.ashx?flag=tree',//如果不配置采用公用 $.fn.tabs.defaults里的配置 dataType: 'json'// //如果不配置采用公用 $.fn.tabs.defaults里的配置 },{ title: '文本测试', closable: false, iconcls: 'icon-back', actived: false,// 激活状态 content: '<a>我是测试内容.....................</a>'// 可以是文本,可以是$("#id")对象 }], onLoadSuccess: function (title, context) { console.log(title + "加载完成"); if (title == "远程加载JSON数据") { $("<ul id='tree'></ul>").appendTo(context.target).tree({ onClick: function (data) { console.log(JSON.stringify(data)); alert("click"); }, animate: true, isPlain: false, checkbox: true, textField: 'text1', idField: 'id1', data: context.data, lazy: true, url: 'testServer/jsonQuestTest.ashx?flag=tree', onLoadSuccess: function (data) { console.log("服务器数据返回:" + JSON.stringify(data)); } }); } }, activedHandler: function (tilte,context) { console.log("actived=" + tilte); }, closedHandler: function (title) { console.log("closed=" + title); } }); }); function addaccordion() { accordion.accordion("addAccordion", { title: '动态添加tab', closable: true, iconcls: 'icon-back', actived: false,// 激活状态 url: 'testServer/jsonQuestTest.ashx',//如果不配置采用公用 $.fn.tabs.defaults里的配置 dataType: 'json',// //如果不配置采用公用 $.fn.tabs.defaults里的配置 onLoadSuccess: function (title, context) { context.target.html(title+"loadsucc;我自己注册的事件 "+JSON.stringify(context.data)); } }); } function getAccordion() { var res = accordion.accordion("getActived"); alert(res.titleObj.attr("title")); } </script>
组件代码
1 /************************************************************** 2 *作者:hjwen 3 *电邮:hjwen88@126.com 4 *版本:1.0 5 *版权许可:中国通用开源许可协议V1.0 6 *说明:myui组件accordion组件 7 ***************************************************************/ 8 (function ($) { 9 /****** 10 *渲染目标:renderHtml为构建html结构的函数,init初始化会调用 11 *******/ 12 var itemTitleContainer, itemContentContainer, itemCount; 13 var contentHeight = 0; 14 function renderHtml(target) { 15 createAccordions(target); 16 }; 17 /**********私有方法开始********************/ 18 function createAccordions(target) { 19 var opts = target.data("settings"); 20 var items = opts.items; 21 $.each(items, function (i, item) { 22 if (item.exist == null) { 23 item.exist = $("<div></div>").appendTo(target); 24 } 25 createAccordion(item, i); 26 }); 27 itemContentContainer.animate({ height: contentHeight + "px" },300); 28 itemTitleContainer.css("border-bottom", "1px solid #99BBE8"); 29 } 30 function createAccordion(item, index) { 31 var onePanel = item.exist; 32 if (onePanel != null) { 33 var panelOpt = { 34 title: item.title, 35 iconCls: item.iconcls, 36 collapseable: false, //可收缩 37 closeable: item.closable, 38 expandable: false,//可展开 39 maximizable: false//可最大化 40 }; 41 if (typeof item.url != 'undefined' && item.url != '' && item.url != null) { 42 panelOpt.remoteRequest = { 43 dataType: item.dataType, 44 url: item.url, 45 load: function () { }, 46 loaded: function (result) { 47 if (typeof item.onLoadSuccess == 'function') 48 item.onLoadSuccess(item.title, { data: result, target: item.exist }); 49 } 50 }; 51 } 52 if (item.closable) { 53 panelOpt.onClosed=function (txt) { 54 contentHeight = contentHeight + 30; 55 itemCount--; 56 itemContentContainer.height(contentHeight + "px"); 57 if (typeof item.closedHandler == 'function') { 58 item.closedHandler(txt); 59 } 60 } 61 } 62 var panel = onePanel.panel(panelOpt); 63 var tmpObj = panel.panel("getPanelObjs"); 64 tmpObj.contentObj.css({ "height": "0" }).parent("div").css("height", "auto"); 65 if (item.content != null) { 66 if (typeof item.content == 'object') { 67 item.content.appendTo(tmpObj.contentObj); 68 } else { 69 tmpObj.contentObj.html(item.content); 70 } 71 } 72 if (index < itemCount - 1) { 73 tmpObj.contentObj.css("border-bottom", "none"); 74 } 75 tmpObj.titleObj.css({ "background": "#E0ECFF", "border-bottom": "none" }).attr("title",item.title).attr("for",index).bind({ 76 click: function () { 77 itemContentContainer.animate({ height: 0 }, 300); 78 itemTitleContainer.css("border-bottom", "none"); 79 itemTitleContainer = $(this).css("border-bottom", "1px solid #99BBE8"); 80 itemContentContainer = $(this).next().animate({ height: contentHeight + "px" }, 300); 81 if (typeof item.activedHandler == 'function') { 82 item.activedHandler(itemTitleContainer.children(".panel-tilte").children("h2").text(), itemContentContainer); 83 } 84 }, 85 mouseenter: function () { 86 $(this).css({ 87 'cursor': 'pointer', 88 'background': '#E8F0FC' 89 }); 90 }, 91 mouseleave: function () { 92 $(this).css({ 93 "background": "#E0ECFF" 94 }); 95 } 96 }); 97 if (index == 0) { 98 itemTitleContainer = tmpObj.titleObj; 99 itemContentContainer = tmpObj.contentObj; 100 } 101 if (item.actived) { 102 itemTitleContainer = tmpObj.titleObj; 103 itemContentContainer = tmpObj.contentObj; 104 } 105 } 106 }; 107 /**********私有方法结束*******************/ 108 /***************************************************************************** 109 *对外的函数统一封装到methods中 110 *调用方式:$.pluginInstance.pluginName("methodName",params) 111 ******************************************************************************/ 112 var methods = { 113 init: function (options) { 114 var $this = $(this); 115 var settings 116 if (typeof options == 'undefined') 117 settings = $.fn.accordion.defaults; 118 else 119 settings = $.extend({}, $.fn.accordion.defaults, options); 120 var newItemArr = []; 121 var existItems = $this.children("div");//已经存在的item项 122 if (existItems.length > 0) { 123 $.each(existItems, function (i, it) { 124 var $it = $(it); 125 var opt = { 126 title: $it.attr("title"), 127 content: $it.attr("content") == undefined ? null : $("#" + $it.attr("content")), 128 closable: $it.attr("closable") == "true" ? true : false, 129 iconcls: $it.attr("iconcls") == undefined ? "" : $it.attr("iconcls"), 130 actived: $it.attr("actived") == "true" ? true : false,// 激活状态 131 isiframe: $it.attr("isiframe") == "true" ? true : false,//如果不配置采用公用 $.fn.accordion.defaults里的配置 132 url: $it.attr("url") == undefined ? "" : $it.attr("url"),//如果不配置采用公用 $.fn.accordion.defaults里的配置 133 dataType: $it.attr("dataType") == undefined ? "json" : $it.attr("dataType"), //如果不配置采用公用 $.fn.accordion.defaults里的配置 134 exist: $it, // 135 onLoadSuccess: settings.onLoadSuccess,//fn(title,resdata) 136 activedHandler: settings.activedHandler,//fn(title,context) 137 closedHandler: settings.closedHandler //fn(title) tab被关闭时触发 138 }; 139 if (opt.isiframe) 140 opt.dataType = 'iframe'; 141 newItemArr.push(opt); 142 }); 143 } 144 //合并每一个accordion项的默认设置 145 $.each(settings.items, function (i, item) { 146 var newIt = $.extend({}, $.fn.accordion.itemdefaults, item); 147 newIt.exist = null; 148 if (typeof newIt.onLoadSuccess != 'function') 149 newIt.onLoadSuccess = settings.onLoadSuccess;//fn(title,resdata) 150 if (typeof newIt.activedHandler != 'function') 151 newIt.activedHandler = settings.activedHandler;//fn(title,context) 152 if (typeof newIt.closedHandler != 'function') 153 newIt.closedHandler = settings.closedHandler; //fn(title) tab被关闭时触发 154 newItemArr.push(newIt); 155 }); 156 settings.items = newItemArr; 157 itemCount = settings.items.length; 158 //设置每一项的高度 159 contentHeight = $this.height() - 30 * newItemArr.length; 160 //创建ui布局 161 $this.data('settings', settings); 162 renderHtml($this); 163 if ($.myui.isDebug) { 164 $.myui.log("jQuery.accordion init finish......"); 165 } 166 return $this; 167 }, 168 destroy: function (options) { 169 var $this = $(this); 170 $this.removeData('settings'); 171 return $this.remove(); 172 }, 173 /*** 174 *opt={ 175 title: 'Accordion标题', 176 closable: false, 177 iconcls: '', 178 actived: false,// 激活状态 179 isiframe: false,//如果不配置采用公用 $.fn.accordion.defaults里的配置 180 url: '',//如果不配置采用公用 $.fn.accordion.defaults里的配置 181 content: '',//内容默认为空,如果该属性有值,则优先默认采用这个,即使设置url也不会去远程加载数据,content可以是html对象,也可以是文本 182 dataType: 'json'// //如果不配置采用公用 $.fn.accordion.defaults里的配置 183 } 184 ***/ 185 addAccordion: function (opts) { 186 var newOpt = $.extend({}, $.fn.accordion.itemdefaults, opts); 187 newOpt.actived = true; 188 var $this = $(this); 189 //修改最后一个的border-bottom", "none" 190 $this.children().last().children(".panel-body").css("border-bottom", "none"); 191 newOpt.exist = $("<div></div>").appendTo($this); 192 contentHeight = contentHeight - 30; 193 if (itemContentContainer!=null) 194 itemContentContainer.animate({ height: 0 }, 300).css("border-bottom", "none"); 195 if (itemTitleContainer!=null) 196 itemTitleContainer.css("border-bottom", "none"); 197 createAccordion(newOpt, itemCount + 1); 198 itemContentContainer.animate({ height: contentHeight + "px" },300); 199 itemTitleContainer.css("border-bottom", "1px solid #99BBE8"); 200 return $this; 201 }, 202 getActived: function () { 203 return { titleObj: itemTitleContainer, contentObj: itemContentContainer }; 204 } 205 }; 206 /******************** 207 *组件的构造函数 208 *********************/ 209 $.fn.accordion = function () { 210 var method = arguments[0]; 211 if (methods[method]) { 212 method = methods[method]; 213 arguments = Array.prototype.slice.call(arguments, 1); 214 } else if (typeof (method) == 'object' || !method) { 215 if ($.myui.isDebug) { 216 $.myui.log("jQuery.accordion init....."); 217 } 218 method = methods.init; 219 } else { 220 $.error('Method ' + method + ' does not exist on jQuery.accordion'); 221 return this; 222 } 223 return method.apply(this, arguments); 224 }; 225 /******************** 226 *组件的默认配置值 227 *options={ 228 items: [], //accordion项配置,对应$.fn.accordion.itemdefaults 229 isiframe: false,// 是否嵌入iframe,嵌入iframe 需要与url配合使用,即采用url加载远程页面时【dataType=html】才起作用 230 url: '', 231 dataType: 'json',// json/html 远程加载时的数据格式 232 onLoadSuccess: null,//fn(title,resdata) 233 activedHandler: null,//fn(title,context) 234 closedHandler: null //fn(title) accordion被关闭时触发 235 } 236 *********************/ 237 $.fn.accordion.defaults = { 238 items: [], //accordion项配置,对应$.fn.accordion.itemdefaults 239 isiframe: false,// 是否嵌入iframe,嵌入iframe 需要与url配合使用,即采用url加载远程页面时【dataType=html】才起作用 240 url: '', 241 dataType: 'json',// json/html 远程加载时的数据格式 242 onLoadSuccess: null,//fn(title,resdata) 243 activedHandler: null,//fn(title,context) 244 closedHandler: null //fn(title) accordion被关闭时触发 245 }; 246 /*** 247 *每一个accordion项目的默认配置 248 ****/ 249 $.fn.accordion.itemdefaults = { 250 title: 'accordion标题', 251 closable: false,//是否可以删除 252 iconcls: '', 253 actived: false,// 激活状态 254 isiframe: false,//如果不配置采用公用 $.fn.accordion.defaults里的配置 255 url: '',//如果不配置采用公用 $.fn.accordion.defaults里的配置 256 content: null,//内容默认为空,如果该属性有值,则优先默认采用这个,即使设置url也不会去远程加载数据,content可以是html对象,也可以是文本 257 dataType: 'json'// //如果不配置采用公用 $.fn.accordion.defaults里的配置 258 } 259 })(jQuery);