You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
5.5 KiB

  1. /* ******************************
  2. Accordion
  3. Author: Jack Lukic
  4. Notes: First Commit July 19, 2012
  5. Simple accordion design
  6. ****************************** */
  7. ;(function ($, window, document, undefined) {
  8. $.fn.accordion = function(parameters) {
  9. var
  10. settings = $.extend(true, {}, $.fn.accordion.settings, parameters),
  11. // hoist arguments
  12. moduleArguments = arguments || false
  13. ;
  14. $(this)
  15. .each(function() {
  16. var
  17. $module = $(this),
  18. $title = $module.find(settings.selector.title),
  19. $icon = $module.find(settings.selector.icon),
  20. $content = $module.find(settings.selector.content),
  21. instance = $module.data('module'),
  22. className = settings.className,
  23. module
  24. ;
  25. module = {
  26. initialize: function() {
  27. // initializing
  28. $title
  29. .on('click', module.change)
  30. ;
  31. $module
  32. .data('module', module)
  33. ;
  34. },
  35. change: function() {
  36. var
  37. $activeTitle = $(this),
  38. $activeContent = $activeTitle.next($content),
  39. contentIsOpen = $activeTitle.hasClass(className.active)
  40. ;
  41. if(contentIsOpen) {
  42. if(settings.collapsible) {
  43. $.proxy(module.close, $activeTitle)();
  44. }
  45. }
  46. else {
  47. $.proxy(module.open, $activeTitle)();
  48. }
  49. },
  50. open: function() {
  51. var
  52. $activeTitle = $(this),
  53. $activeContent = $activeTitle.next($content),
  54. $currentTitle = $title.filter('.' + className.active),
  55. $currentContent = $currentTitle.next($title)
  56. ;
  57. if(settings.exclusive && $currentTitle.size() > 0) {
  58. $currentTitle
  59. .removeClass('active')
  60. ;
  61. $currentContent
  62. .stop()
  63. .slideUp(settings.speed , settings.easing, function() {
  64. $(this)
  65. .removeClass('active')
  66. .removeAttr('style')
  67. ;
  68. })
  69. ;
  70. }
  71. $activeTitle
  72. .addClass(className.active)
  73. ;
  74. $activeContent
  75. .hide()
  76. .addClass(className.active)
  77. .stop()
  78. .slideDown(settings.speed, settings.easing, function() {
  79. $(this)
  80. .removeAttr('style')
  81. ;
  82. })
  83. ;
  84. },
  85. close: function() {
  86. var
  87. $activeTitle = $(this),
  88. $activeContent = $activeTitle.next($content)
  89. ;
  90. $activeTitle
  91. .removeClass(className.active)
  92. ;
  93. $activeContent
  94. .removeClass(className.active)
  95. .show()
  96. .stop()
  97. .slideUp(settings.speed, settings.easing, function(){
  98. $(this)
  99. .removeAttr('style')
  100. ;
  101. })
  102. ;
  103. },
  104. debug: function(message) {
  105. if(settings.debug) {
  106. console.info(settings.moduleName + ': ' + message);
  107. }
  108. },
  109. error: function(errorMessage) {
  110. console.warn(settings.moduleName + ': ' + errorMessage);
  111. },
  112. invoke: function(methodName, context, methodArguments) {
  113. var
  114. method
  115. ;
  116. methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 );
  117. if(typeof methodName == 'string' && instance !== undefined) {
  118. methodName = methodName.split('.');
  119. $.each(methodName, function(index, name) {
  120. if( $.isPlainObject( instance[name] ) ) {
  121. instance = instance[name];
  122. return true;
  123. }
  124. else if( $.isFunction( instance[name] ) ) {
  125. method = instance[name];
  126. return true;
  127. }
  128. module.error(settings.errors.method);
  129. return false;
  130. });
  131. }
  132. if ( $.isFunction( method ) ) {
  133. return method.apply(context, methodArguments);
  134. }
  135. // return retrieved variable or chain
  136. return method;
  137. }
  138. };
  139. // calling a method
  140. if(instance !== undefined && moduleArguments) {
  141. // simpler than invoke realizing to invoke itself (and losing scope due prototype.call()
  142. if(moduleArguments[0] == 'invoke') {
  143. moduleArguments = Array.prototype.slice.call( moduleArguments, 1 );
  144. }
  145. return module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) );
  146. }
  147. // initializing
  148. module.initialize();
  149. })
  150. ;
  151. return this;
  152. };
  153. $.fn.accordion.settings = {
  154. moduleName : 'Accordion',
  155. debug : false,
  156. exclusive : true,
  157. collapsible : true,
  158. errors: {
  159. method : 'The method you called is not defined'
  160. },
  161. className : {
  162. active : 'active',
  163. hover : 'hover'
  164. },
  165. selector : {
  166. title : '.title',
  167. icon : '.icon',
  168. content : '.content'
  169. },
  170. speed : 500,
  171. easing : 'easeInOutQuint'
  172. };
  173. })( jQuery, window , document );