jquery.accordion.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /**
  2. * accordion - jQuery EasyUI
  3. *
  4. * Copyright (c) 2009-2013 www.jeasyui.com. All rights reserved.
  5. *
  6. * Licensed under the GPL or commercial licenses
  7. * To use it on other terms please contact us: info@jeasyui.com
  8. * http://www.gnu.org/licenses/gpl.txt
  9. * http://www.jeasyui.com/license_commercial.php
  10. *
  11. * Dependencies:
  12. * panel
  13. *
  14. */
  15. (function($){
  16. function setSize(container){
  17. var state = $.data(container, 'accordion');
  18. var opts = state.options;
  19. var panels = state.panels;
  20. var cc = $(container);
  21. opts.fit ? $.extend(opts, cc._fit()) : cc._fit(false);
  22. if (opts.width > 0){
  23. cc._outerWidth(opts.width);
  24. }
  25. var panelHeight = 'auto';
  26. if (opts.height > 0){
  27. cc._outerHeight(opts.height);
  28. // get the first panel's header height as all the header height
  29. var headerHeight = panels.length ? panels[0].panel('header').css('height', '')._outerHeight() : 'auto';
  30. var panelHeight = cc.height() - (panels.length-1)*headerHeight;
  31. }
  32. for(var i=0; i<panels.length; i++){
  33. var panel = panels[i];
  34. panel.panel('header')._outerHeight(headerHeight);
  35. panel.panel('resize', {
  36. width: cc.width(),
  37. height: panelHeight
  38. });
  39. }
  40. }
  41. /**
  42. * get the current panel
  43. */
  44. function getCurrent(container){
  45. var panels = $.data(container, 'accordion').panels;
  46. for(var i=0; i<panels.length; i++){
  47. var panel = panels[i];
  48. if (panel.panel('options').collapsed == false){
  49. return panel;
  50. }
  51. }
  52. return null;
  53. }
  54. /**
  55. * get panel index, start with 0
  56. */
  57. function getPanelIndex(container, panel){
  58. var panels = $.data(container, 'accordion').panels;
  59. for(var i=0; i<panels.length; i++){
  60. if (panels[i][0] == $(panel)[0]){
  61. return i;
  62. }
  63. }
  64. return -1;
  65. }
  66. /**
  67. * get the specified panel, remove it from panel array if removeit setted to true.
  68. */
  69. function getPanel(container, which, removeit){
  70. var panels = $.data(container, 'accordion').panels;
  71. if (typeof which == 'number'){
  72. if (which < 0 || which >= panels.length){
  73. return null;
  74. } else {
  75. var panel = panels[which];
  76. if (removeit){
  77. panels.splice(which,1);
  78. }
  79. return panel;
  80. }
  81. }
  82. for(var i=0; i<panels.length; i++){
  83. var panel = panels[i];
  84. if (panel.panel('options').title == which){
  85. if (removeit){
  86. panels.splice(i, 1);
  87. }
  88. return panel;
  89. }
  90. }
  91. return null;
  92. }
  93. function setProperties(container){
  94. var opts = $.data(container, 'accordion').options;
  95. var cc = $(container);
  96. if (opts.border){
  97. cc.removeClass('accordion-noborder');
  98. } else {
  99. cc.addClass('accordion-noborder');
  100. }
  101. }
  102. function wrapAccordion(container){
  103. var cc = $(container);
  104. cc.addClass('accordion');
  105. var panels = [];
  106. cc.children('div').each(function(){
  107. var opts = $.extend({}, $.parser.parseOptions(this), {
  108. selected: ($(this).attr('selected') ? true : undefined)
  109. });
  110. var pp = $(this);
  111. panels.push(pp);
  112. createPanel(container, pp, opts);
  113. });
  114. cc.bind('_resize', function(e,force){
  115. var opts = $.data(container, 'accordion').options;
  116. if (opts.fit == true || force){
  117. setSize(container);
  118. }
  119. return false;
  120. });
  121. return {
  122. accordion: cc,
  123. panels: panels
  124. }
  125. }
  126. function createPanel(container, pp, options){
  127. pp.panel($.extend({}, options, {
  128. collapsible: false,
  129. minimizable: false,
  130. maximizable: false,
  131. closable: false,
  132. doSize: false,
  133. collapsed: true,
  134. headerCls: 'accordion-header',
  135. bodyCls: 'accordion-body',
  136. onBeforeExpand: function(){
  137. if (options.onBeforeExpand){
  138. if (options.onBeforeExpand.call(this) == false){return false}
  139. }
  140. var curr = getCurrent(container);
  141. if (curr){
  142. var header = $(curr).panel('header');
  143. header.removeClass('accordion-header-selected');
  144. header.find('.accordion-collapse').triggerHandler('click');
  145. }
  146. var header = pp.panel('header');
  147. header.addClass('accordion-header-selected');
  148. header.find('.accordion-collapse').removeClass('accordion-expand');
  149. },
  150. onExpand: function(){
  151. if (options.onExpand){options.onExpand.call(this)}
  152. var opts = $.data(container, 'accordion').options;
  153. opts.onSelect.call(container, pp.panel('options').title, getPanelIndex(container, this));
  154. },
  155. onBeforeCollapse: function(){
  156. if (options.onBeforeCollapse){
  157. if (options.onBeforeCollapse.call(this) == false){return false}
  158. }
  159. var header = pp.panel('header');
  160. header.removeClass('accordion-header-selected');
  161. header.find('.accordion-collapse').addClass('accordion-expand');
  162. }
  163. }));
  164. var header = pp.panel('header');
  165. var t = $('<a class="accordion-collapse accordion-expand" href="javascript:void(0)"></a>').appendTo(header.children('div.panel-tool'));
  166. t.bind('click', function(e){
  167. var animate = $.data(container, 'accordion').options.animate;
  168. stopAnimate(container);
  169. if (pp.panel('options').collapsed){
  170. pp.panel('expand', animate);
  171. } else {
  172. pp.panel('collapse', animate);
  173. }
  174. return false;
  175. });
  176. header.click(function(){
  177. $(this).find('.accordion-collapse').triggerHandler('click');
  178. return false;
  179. });
  180. }
  181. /**
  182. * select and set the specified panel active
  183. */
  184. function select(container, which){
  185. var panel = getPanel(container, which);
  186. if (!panel) return;
  187. var curr = getCurrent(container);
  188. if (curr && curr[0] == panel[0]){
  189. return;
  190. }
  191. panel.panel('header').triggerHandler('click');
  192. }
  193. function doFirstSelect(container){
  194. var panels = $.data(container, 'accordion').panels;
  195. for(var i=0; i<panels.length; i++){
  196. if (panels[i].panel('options').selected){
  197. _select(i);
  198. return;
  199. }
  200. }
  201. if (panels.length){
  202. _select(0);
  203. }
  204. function _select(index){
  205. var opts = $.data(container, 'accordion').options;
  206. var animate = opts.animate;
  207. opts.animate = false;
  208. select(container, index);
  209. opts.animate = animate;
  210. }
  211. }
  212. /**
  213. * stop the animation of all panels
  214. */
  215. function stopAnimate(container){
  216. var panels = $.data(container, 'accordion').panels;
  217. for(var i=0; i<panels.length; i++){
  218. panels[i].stop(true,true);
  219. }
  220. }
  221. function add(container, options){
  222. var state = $.data(container, 'accordion');
  223. var opts = state.options;
  224. var panels = state.panels;
  225. if (options.selected == undefined) options.selected = true;
  226. stopAnimate(container);
  227. var pp = $('<div></div>').appendTo(container);
  228. panels.push(pp);
  229. createPanel(container, pp, options);
  230. setSize(container);
  231. opts.onAdd.call(container, options.title, panels.length-1);
  232. if (options.selected){
  233. select(container, panels.length-1);
  234. }
  235. }
  236. function remove(container, which){
  237. var state = $.data(container, 'accordion');
  238. var opts = state.options;
  239. var panels = state.panels;
  240. stopAnimate(container);
  241. var panel = getPanel(container, which);
  242. var title = panel.panel('options').title;
  243. var index = getPanelIndex(container, panel);
  244. if (opts.onBeforeRemove.call(container, title, index) == false) return;
  245. var panel = getPanel(container, which, true);
  246. if (panel){
  247. panel.panel('destroy');
  248. if (panels.length){
  249. setSize(container);
  250. var curr = getCurrent(container);
  251. if (!curr){
  252. select(container, 0);
  253. }
  254. }
  255. }
  256. opts.onRemove.call(container, title, index);
  257. }
  258. $.fn.accordion = function(options, param){
  259. if (typeof options == 'string'){
  260. return $.fn.accordion.methods[options](this, param);
  261. }
  262. options = options || {};
  263. return this.each(function(){
  264. var state = $.data(this, 'accordion');
  265. var opts;
  266. if (state){
  267. opts = $.extend(state.options, options);
  268. state.opts = opts;
  269. } else {
  270. opts = $.extend({}, $.fn.accordion.defaults, $.fn.accordion.parseOptions(this), options);
  271. var r = wrapAccordion(this);
  272. $.data(this, 'accordion', {
  273. options: opts,
  274. accordion: r.accordion,
  275. panels: r.panels
  276. });
  277. }
  278. setProperties(this);
  279. setSize(this);
  280. doFirstSelect(this);
  281. });
  282. };
  283. $.fn.accordion.methods = {
  284. options: function(jq){
  285. return $.data(jq[0], 'accordion').options;
  286. },
  287. panels: function(jq){
  288. return $.data(jq[0], 'accordion').panels;
  289. },
  290. resize: function(jq){
  291. return jq.each(function(){
  292. setSize(this);
  293. });
  294. },
  295. getSelected: function(jq){
  296. return getCurrent(jq[0]);
  297. },
  298. getPanel: function(jq, which){
  299. return getPanel(jq[0], which);
  300. },
  301. getPanelIndex: function(jq, panel){
  302. return getPanelIndex(jq[0], panel);
  303. },
  304. select: function(jq, which){
  305. return jq.each(function(){
  306. select(this, which);
  307. });
  308. },
  309. add: function(jq, options){
  310. return jq.each(function(){
  311. add(this, options);
  312. });
  313. },
  314. remove: function(jq, which){
  315. return jq.each(function(){
  316. remove(this, which);
  317. });
  318. }
  319. };
  320. $.fn.accordion.parseOptions = function(target){
  321. var t = $(target);
  322. return $.extend({}, $.parser.parseOptions(target, [
  323. 'width','height',{fit:'boolean',border:'boolean',animate:'boolean'}
  324. ]));
  325. };
  326. $.fn.accordion.defaults = {
  327. width: 'auto',
  328. height: 'auto',
  329. fit: false,
  330. border: true,
  331. animate: true,
  332. onSelect: function(title, index){},
  333. onAdd: function(title, index){},
  334. onBeforeRemove: function(title, index){},
  335. onRemove: function(title, index){}
  336. };
  337. })(jQuery);