Dashboard sipadu mbip
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.

aui-toggler.js 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. AUI.add('aui-toggler-base', function(A) {
  2. var Lang = A.Lang,
  3. isBoolean = Lang.isBoolean,
  4. isObject = Lang.isObject,
  5. isUndefined = Lang.isUndefined,
  6. toInt = Lang.toInt,
  7. DASH = '-',
  8. DOT = '.',
  9. EMPTY_STR = '',
  10. PIXEL = 'px',
  11. SPACE = ' ',
  12. ANIMATED = 'animated',
  13. ANIMATING = 'animating',
  14. BIND_DOM_EVENTS = 'bindDOMEvents',
  15. CLICK = 'click',
  16. COLLAPSED = 'collapsed',
  17. CONTENT = 'content',
  18. DOWN = 'down',
  19. ENTER = 'enter',
  20. ESC = 'esc',
  21. EXPANDED = 'expanded',
  22. EXPANDED_CHANGE = 'expandedChange',
  23. GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',
  24. GUTTER = 'gutter',
  25. HEADER = 'header',
  26. HELPER = 'helper',
  27. KEYDOWN = 'keydown',
  28. LEFT = 'left',
  29. LINEAR = 'linear',
  30. MARGIN_TOP = 'marginTop',
  31. MINUS = 'minus',
  32. NUM_MINUS = 'num_minus',
  33. NUM_PLUS = 'num_plus',
  34. PARENT_NODE = 'parentNode',
  35. PLUS = 'plus',
  36. RIGHT = 'right',
  37. SPACE = 'space',
  38. TOGGLER = 'toggler',
  39. TRANSITION = 'transition',
  40. TRANSITION_END = 'transitionEnd',
  41. TRANSITION_START = 'transitionStart',
  42. UP = 'up',
  43. WRAPPER = 'wrapper',
  44. getCN = A.getClassName,
  45. CSS_TOGGLER_CONTENT = getCN(TOGGLER, CONTENT),
  46. CSS_TOGGLER_CONTENT_COLLAPSED = getCN(TOGGLER, CONTENT, COLLAPSED),
  47. CSS_TOGGLER_CONTENT_EXPANDED = getCN(TOGGLER, CONTENT, EXPANDED),
  48. CSS_TOGGLER_CONTENT_WRAPPER = getCN(TOGGLER, CONTENT, WRAPPER),
  49. CSS_TOGGLER_HEADER = getCN(TOGGLER, HEADER),
  50. CSS_TOGGLER_HEADER_COLLAPSED = getCN(TOGGLER, HEADER, COLLAPSED),
  51. CSS_TOGGLER_HEADER_EXPANDED = getCN(TOGGLER, HEADER, EXPANDED),
  52. CSS_TOGGLER_CONTENT_STATE = {
  53. 'false': CSS_TOGGLER_CONTENT_COLLAPSED,
  54. 'true': CSS_TOGGLER_CONTENT_EXPANDED
  55. },
  56. CSS_TOGGLER_HEADER_STATE = {
  57. 'false': CSS_TOGGLER_HEADER_COLLAPSED,
  58. 'true': CSS_TOGGLER_HEADER_EXPANDED
  59. },
  60. TPL_CONTENT_WRAPPER = '<div class="' + CSS_TOGGLER_CONTENT_WRAPPER + '"></div>';
  61. var Toggler = A.Component.create({
  62. NAME: TOGGLER,
  63. ATTRS: {
  64. animated: {
  65. validator: isBoolean,
  66. value: false,
  67. writeOnce: true
  68. },
  69. animating: {
  70. validator: isBoolean,
  71. value: false
  72. },
  73. bindDOMEvents: {
  74. validator: isBoolean,
  75. value: true,
  76. writeOnce: true
  77. },
  78. content: {
  79. setter: A.one
  80. },
  81. expanded: {
  82. validator: isBoolean,
  83. value: true
  84. },
  85. header: {
  86. setter: A.one
  87. },
  88. transition: {
  89. validator: isObject,
  90. value: {
  91. duration: 0.4
  92. }
  93. }
  94. },
  95. EXTENDS: A.Base,
  96. headerEventHandler: function(event, instance) {
  97. if (event.type === CLICK || event.isKey(ENTER) || event.isKey(SPACE)) {
  98. event.preventDefault();
  99. return instance.toggle();
  100. }
  101. else if (event.isKey(DOWN) || event.isKey(RIGHT) || event.isKey(NUM_PLUS)) {
  102. event.preventDefault();
  103. return instance.expand();
  104. }
  105. else if (event.isKey(UP) || event.isKey(LEFT) || event.isKey(ESC) || event.isKey(NUM_MINUS)) {
  106. event.preventDefault();
  107. return instance.collapse();
  108. }
  109. },
  110. prototype: {
  111. initializer: function() {
  112. var instance = this;
  113. instance.bindUI();
  114. instance.syncUI();
  115. instance._uiSetExpanded(instance.get(EXPANDED));
  116. },
  117. bindUI: function() {
  118. var instance = this;
  119. var header = instance.get(HEADER);
  120. header.setData(TOGGLER, instance);
  121. instance.on(EXPANDED_CHANGE, A.bind(instance._onExpandedChange, instance));
  122. if (instance.get(BIND_DOM_EVENTS)) {
  123. header.on([CLICK, KEYDOWN], A.rbind(Toggler.headerEventHandler, null, instance));
  124. }
  125. },
  126. syncUI: function() {
  127. var instance = this;
  128. instance.get(CONTENT).addClass(CSS_TOGGLER_CONTENT);
  129. instance.get(HEADER).addClass(CSS_TOGGLER_HEADER);
  130. },
  131. animate: function(config, fn) {
  132. var instance = this;
  133. instance._uiSetExpanded(true);
  134. var transition = A.merge(config, instance.get(TRANSITION));
  135. instance.get(CONTENT).transition(transition, A.bind(fn, instance));
  136. },
  137. collapse: function() {
  138. var instance = this;
  139. return instance.toggle(false);
  140. },
  141. expand: function() {
  142. var instance = this;
  143. return instance.toggle(true);
  144. },
  145. getContentHeight: function() {
  146. var instance = this;
  147. var content = instance.get(CONTENT);
  148. var expanded = instance.get(EXPANDED), height;
  149. if (!expanded) {
  150. instance._uiSetExpanded(true);
  151. }
  152. if (content.hasMethod(GET_BOUNDING_CLIENT_RECT)) {
  153. var preciseRegion = content.invoke(GET_BOUNDING_CLIENT_RECT);
  154. if (preciseRegion) {
  155. height = preciseRegion.bottom - preciseRegion.top;
  156. }
  157. }
  158. else {
  159. height = content.get(OFFSET_HEIGHT);
  160. }
  161. if (!expanded) {
  162. instance._uiSetExpanded(false);
  163. }
  164. return height;
  165. },
  166. toggle: function(expand) {
  167. var instance = this;
  168. if (isUndefined(expand)) {
  169. expand = !instance.get(EXPANDED);
  170. }
  171. if (instance.get(ANIMATED)) {
  172. if (instance.get(ANIMATING)) {
  173. return expand;
  174. }
  175. var content = instance.get(CONTENT);
  176. var height = instance.getContentHeight();
  177. var gutter = toInt(content.getStyle(MARGIN_TOP));
  178. if (!instance.wrapped) {
  179. content.wrap(TPL_CONTENT_WRAPPER);
  180. if (expand) {
  181. gutter = -(height + gutter);
  182. content.setStyle(MARGIN_TOP, gutter);
  183. }
  184. instance.wrapped = true;
  185. }
  186. instance.set(ANIMATING, true);
  187. instance.animate(
  188. {
  189. marginTop: -(height + gutter) + PIXEL
  190. },
  191. function() {
  192. instance.set(ANIMATING, false);
  193. instance.set(EXPANDED, expand);
  194. }
  195. );
  196. }
  197. else {
  198. instance.set(EXPANDED, expand);
  199. }
  200. return expand;
  201. },
  202. _onExpandedChange: function(event) {
  203. var instance = this;
  204. instance._uiSetExpanded(event.newVal);
  205. },
  206. _uiSetExpanded: function(val) {
  207. var instance = this;
  208. instance.get(CONTENT).replaceClass(CSS_TOGGLER_CONTENT_STATE[!val], CSS_TOGGLER_CONTENT_STATE[val]);
  209. instance.get(HEADER).replaceClass(CSS_TOGGLER_HEADER_STATE[!val], CSS_TOGGLER_HEADER_STATE[val]);
  210. }
  211. }
  212. });
  213. A.Toggler = Toggler;
  214. }, '@VERSION@' ,{skinnable:true, requires:['aui-base','transition']});
  215. AUI.add('aui-toggler-delegate', function(A) {
  216. var Lang = A.Lang,
  217. isBoolean = Lang.isBoolean,
  218. isObject = Lang.isObject,
  219. isString = Lang.isString,
  220. AArray = A.Array,
  221. DOC = A.config.doc,
  222. Toggler = A.Toggler,
  223. DASH = '-',
  224. DOT = '.',
  225. EMPTY_STR = '',
  226. SPACE = ' ',
  227. ANIMATED = 'animated',
  228. CLICK = 'click',
  229. CLOSE_ALL_ON_EXPAND = 'closeAllOnExpand',
  230. CONTAINER = 'container',
  231. CONTENT = 'content',
  232. CUBIC_BEZIER = 'cubic-bezier(0.25, 0.1, 0.25, 1)',
  233. EXPANDED = 'expanded',
  234. FIRST_CHILD = 'firstChild',
  235. HEADER = 'header',
  236. KEYDOWN = 'keydown',
  237. LINEAR = 'linear',
  238. TOGGLER = 'toggler',
  239. TOGGLER_ANIMATING_CHANGE = 'toggler:animatingChange',
  240. TOGGLER_DELEGATE = 'toggler-delegate',
  241. TRANSITION = 'transition',
  242. WRAPPER = 'wrapper',
  243. getCN = A.getClassName,
  244. CSS_TOGGLER_CONTENT_WRAPPER = getCN(TOGGLER, CONTENT, WRAPPER);
  245. var TogglerDelegate = A.Component.create({
  246. NAME: TOGGLER_DELEGATE,
  247. ATTRS: {
  248. animated: {
  249. validator: isBoolean,
  250. value: false,
  251. writeOnce: true
  252. },
  253. closeAllOnExpand: {
  254. validator: isBoolean,
  255. value: false
  256. },
  257. container: {
  258. setter: A.one,
  259. value: DOC
  260. },
  261. content: {
  262. validator: isString
  263. },
  264. expanded: {
  265. validator: isBoolean,
  266. value: true
  267. },
  268. header: {
  269. validator: isString
  270. },
  271. transition: {
  272. validator: isObject,
  273. value: {
  274. duration: 0.4,
  275. easing: CUBIC_BEZIER
  276. }
  277. }
  278. },
  279. EXTENDS: A.Base,
  280. prototype: {
  281. items: null,
  282. initializer: function() {
  283. var instance = this;
  284. instance.bindUI();
  285. instance.renderUI();
  286. },
  287. renderUI: function() {
  288. var instance = this;
  289. if (instance.get(CLOSE_ALL_ON_EXPAND)) {
  290. instance.items = [];
  291. instance.get(CONTAINER).all(instance.get(HEADER)).each(function(header) {
  292. instance.items.push(
  293. instance._create(header)
  294. );
  295. });
  296. }
  297. },
  298. bindUI: function() {
  299. var instance = this;
  300. var container = instance.get(CONTAINER);
  301. var header = instance.get(HEADER);
  302. instance.on(TOGGLER_ANIMATING_CHANGE, A.bind(instance._onAnimatingChange, instance));
  303. container.delegate([CLICK, KEYDOWN], A.bind(instance.headerEventHandler, instance), header);
  304. },
  305. findContentNode: function(header) {
  306. var instance = this;
  307. var content = instance.get(CONTENT);
  308. var contentNode = header.next(content) || header.one(content);
  309. if (!contentNode) {
  310. var wrapper = header.next(DOT + CSS_TOGGLER_CONTENT_WRAPPER);
  311. if (wrapper) {
  312. contentNode = wrapper.get(FIRST_CHILD);
  313. }
  314. }
  315. return contentNode;
  316. },
  317. headerEventHandler: function(event) {
  318. var instance = this;
  319. if (instance.animating) {
  320. return false;
  321. }
  322. var target = event.currentTarget;
  323. var toggler = target.getData(TOGGLER) || instance._create(target);
  324. if (Toggler.headerEventHandler(event, toggler) && instance.get(CLOSE_ALL_ON_EXPAND)) {
  325. AArray.each(
  326. instance.items,
  327. function(item, index, collection) {
  328. if (item !== toggler && item.get(EXPANDED)) {
  329. item.collapse();
  330. }
  331. }
  332. );
  333. }
  334. },
  335. _create: function(header) {
  336. var instance = this;
  337. var toggler = new Toggler({
  338. animated: instance.get(ANIMATED),
  339. bindDOMEvents: false,
  340. bubbleTargets: [ instance ],
  341. content: instance.findContentNode(header),
  342. expanded: instance.get(EXPANDED),
  343. header: header,
  344. transition: instance.get(TRANSITION)
  345. });
  346. return toggler;
  347. },
  348. _onAnimatingChange: function(event) {
  349. var instance = this;
  350. instance.animating = event.newVal;
  351. }
  352. }
  353. });
  354. A.TogglerDelegate = TogglerDelegate;
  355. }, '@VERSION@' ,{requires:['aui-toggler-base'], skinnable:false});
  356. AUI.add('aui-toggler', function(A){}, '@VERSION@' ,{skinnable:true, use:['aui-toggler-base','aui-toggler-delegate']});