我的开源框架之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);

 

posted @ 2014-08-16 11:16  hjwen  Views(2097)  Comments(0Edit  收藏  举报