Header.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /* Top toolbar area with buttons and title
  2. ----------------------------------------------------------------------------------------------------------------------*/
  3. // TODO: rename all header-related things to "toolbar"
  4. function Header(calendar, options) {
  5. var t = this;
  6. // exports
  7. t.render = render;
  8. t.destroy = destroy;
  9. t.updateTitle = updateTitle;
  10. t.activateButton = activateButton;
  11. t.deactivateButton = deactivateButton;
  12. t.disableButton = disableButton;
  13. t.enableButton = enableButton;
  14. t.getViewsWithButtons = getViewsWithButtons;
  15. // locals
  16. var el = $();
  17. var viewsWithButtons = [];
  18. var tm;
  19. function render() {
  20. var sections = options.header;
  21. tm = options.theme ? 'ui' : 'fc';
  22. if (sections) {
  23. el = $("<div class='fc-toolbar'/>")
  24. .append(renderSection('left'))
  25. .append(renderSection('right'))
  26. .append(renderSection('center'))
  27. .append('<div class="fc-clear"/>');
  28. return el;
  29. }
  30. }
  31. function destroy() {
  32. el.remove();
  33. }
  34. function renderSection(position) {
  35. var sectionEl = $('<div class="fc-' + position + '"/>');
  36. var buttonStr = options.header[position];
  37. if (buttonStr) {
  38. $.each(buttonStr.split(' '), function(i) {
  39. var groupChildren = $();
  40. var isOnlyButtons = true;
  41. var groupEl;
  42. $.each(this.split(','), function(j, buttonName) {
  43. var viewSpec;
  44. var buttonClick;
  45. var overrideText; // text explicitly set by calendar's constructor options. overcomes icons
  46. var defaultText;
  47. var themeIcon;
  48. var normalIcon;
  49. var innerHtml;
  50. var classes;
  51. var button;
  52. if (buttonName == 'title') {
  53. groupChildren = groupChildren.add($('<h2>&nbsp;</h2>')); // we always want it to take up height
  54. isOnlyButtons = false;
  55. }
  56. else {
  57. viewSpec = calendar.getViewSpec(buttonName);
  58. if (viewSpec) {
  59. buttonClick = function() {
  60. calendar.changeView(buttonName);
  61. };
  62. viewsWithButtons.push(buttonName);
  63. overrideText = viewSpec.buttonTextOverride;
  64. defaultText = viewSpec.buttonTextDefault;
  65. }
  66. else if (calendar[buttonName]) { // a calendar method
  67. buttonClick = function() {
  68. calendar[buttonName]();
  69. };
  70. overrideText = (calendar.overrides.buttonText || {})[buttonName];
  71. defaultText = options.buttonText[buttonName]; // everything else is considered default
  72. }
  73. if (buttonClick) {
  74. themeIcon = options.themeButtonIcons[buttonName];
  75. normalIcon = options.buttonIcons[buttonName];
  76. if (overrideText) {
  77. innerHtml = htmlEscape(overrideText);
  78. }
  79. else if (themeIcon && options.theme) {
  80. innerHtml = "<span class='ui-icon ui-icon-" + themeIcon + "'></span>";
  81. }
  82. else if (normalIcon && !options.theme) {
  83. innerHtml = "<span class='fc-icon fc-icon-" + normalIcon + "'></span>";
  84. }
  85. else {
  86. innerHtml = htmlEscape(defaultText);
  87. }
  88. classes = [
  89. 'fc-' + buttonName + '-button',
  90. tm + '-button',
  91. tm + '-state-default'
  92. ];
  93. button = $( // type="button" so that it doesn't submit a form
  94. '<button type="button" class="' + classes.join(' ') + '">' +
  95. innerHtml +
  96. '</button>'
  97. )
  98. .click(function() {
  99. // don't process clicks for disabled buttons
  100. if (!button.hasClass(tm + '-state-disabled')) {
  101. buttonClick();
  102. // after the click action, if the button becomes the "active" tab, or disabled,
  103. // it should never have a hover class, so remove it now.
  104. if (
  105. button.hasClass(tm + '-state-active') ||
  106. button.hasClass(tm + '-state-disabled')
  107. ) {
  108. button.removeClass(tm + '-state-hover');
  109. }
  110. }
  111. })
  112. .mousedown(function() {
  113. // the *down* effect (mouse pressed in).
  114. // only on buttons that are not the "active" tab, or disabled
  115. button
  116. .not('.' + tm + '-state-active')
  117. .not('.' + tm + '-state-disabled')
  118. .addClass(tm + '-state-down');
  119. })
  120. .mouseup(function() {
  121. // undo the *down* effect
  122. button.removeClass(tm + '-state-down');
  123. })
  124. .hover(
  125. function() {
  126. // the *hover* effect.
  127. // only on buttons that are not the "active" tab, or disabled
  128. button
  129. .not('.' + tm + '-state-active')
  130. .not('.' + tm + '-state-disabled')
  131. .addClass(tm + '-state-hover');
  132. },
  133. function() {
  134. // undo the *hover* effect
  135. button
  136. .removeClass(tm + '-state-hover')
  137. .removeClass(tm + '-state-down'); // if mouseleave happens before mouseup
  138. }
  139. );
  140. groupChildren = groupChildren.add(button);
  141. }
  142. }
  143. });
  144. if (isOnlyButtons) {
  145. groupChildren
  146. .first().addClass(tm + '-corner-left').end()
  147. .last().addClass(tm + '-corner-right').end();
  148. }
  149. if (groupChildren.length > 1) {
  150. groupEl = $('<div/>');
  151. if (isOnlyButtons) {
  152. groupEl.addClass('fc-button-group');
  153. }
  154. groupEl.append(groupChildren);
  155. sectionEl.append(groupEl);
  156. }
  157. else {
  158. sectionEl.append(groupChildren); // 1 or 0 children
  159. }
  160. });
  161. }
  162. return sectionEl;
  163. }
  164. function updateTitle(text) {
  165. el.find('h2').text(text);
  166. }
  167. function activateButton(buttonName) {
  168. el.find('.fc-' + buttonName + '-button')
  169. .addClass(tm + '-state-active');
  170. }
  171. function deactivateButton(buttonName) {
  172. el.find('.fc-' + buttonName + '-button')
  173. .removeClass(tm + '-state-active');
  174. }
  175. function disableButton(buttonName) {
  176. el.find('.fc-' + buttonName + '-button')
  177. .attr('disabled', 'disabled')
  178. .addClass(tm + '-state-disabled');
  179. }
  180. function enableButton(buttonName) {
  181. el.find('.fc-' + buttonName + '-button')
  182. .removeAttr('disabled')
  183. .removeClass(tm + '-state-disabled');
  184. }
  185. function getViewsWithButtons() {
  186. return viewsWithButtons;
  187. }
  188. }