jquery.layout.buttons.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /**
  2. * @preserve jquery.layout.buttons 1.0
  3. * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $
  4. *
  5. * Copyright (c) 2011
  6. * Kevin Dalman (http://allpro.net)
  7. *
  8. * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
  9. * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
  10. *
  11. * @dependancies: UI Layout 1.3.0.rc30.1 or higher
  12. *
  13. * @support: http://groups.google.com/group/jquery-ui-layout
  14. *
  15. * Docs: [ to come ]
  16. * Tips: [ to come ]
  17. */
  18. // NOTE: For best readability, view with a fixed-width font and tabs equal to 4-chars
  19. ;(function ($) {
  20. if (!$.layout) return;
  21. // tell Layout that the state plugin is available
  22. $.layout.plugins.buttons = true;
  23. // Add State-Management options to layout.defaults
  24. $.layout.defaults.autoBindCustomButtons = false;
  25. // Set stateManagement as a layout-option, NOT a pane-option
  26. $.layout.optionsMap.layout.push("autoBindCustomButtons");
  27. var lang = $.layout.language;
  28. /*
  29. * Button methods
  30. */
  31. $.layout.buttons = {
  32. // set data used by multiple methods below
  33. config: {
  34. borderPanes: "north,south,west,east"
  35. }
  36. /**
  37. * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons
  38. *
  39. * @see _create()
  40. */
  41. , init: function (inst) {
  42. var pre = "ui-layout-button-"
  43. , layout = inst.options.name || ""
  44. , name;
  45. $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) {
  46. $.each($.layout.buttons.config.borderPanes.split(","), function (ii, pane) {
  47. $("."+pre+action+"-"+pane).each(function(){
  48. // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name'
  49. name = $(this).data("layoutName") || $(this).attr("layoutName");
  50. if (name == undefined || name === layout)
  51. inst.bindButton(this, action, pane);
  52. });
  53. });
  54. });
  55. }
  56. /**
  57. * Helper function to validate params received by addButton utilities
  58. *
  59. * Two classes are added to the element, based on the buttonClass...
  60. * The type of button is appended to create the 2nd className:
  61. * - ui-layout-button-pin
  62. * - ui-layout-pane-button-toggle
  63. * - ui-layout-pane-button-open
  64. * - ui-layout-pane-button-close
  65. *
  66. * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
  67. * @param {string} pane Name of the pane the button is for: 'north', 'south', etc.
  68. * @return {Array.<Object>} If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise returns null
  69. */
  70. , get: function (inst, selector, pane, action) {
  71. var $E = $(selector)
  72. , o = inst.options
  73. , err = o.showErrorMessages
  74. ;
  75. if (!$E.length) { // element not found
  76. if (err) alert(lang.errButton + lang.selector +": "+ selector);
  77. }
  78. else if ($.layout.buttons.config.borderPanes.indexOf(pane) === -1) { // invalid 'pane' sepecified
  79. if (err) alert(lang.errButton + lang.pane +": "+ pane);
  80. $E = $(""); // NO BUTTON
  81. }
  82. else { // VALID
  83. var btn = o[pane].buttonClass +"-"+ action;
  84. $E .addClass( btn +" "+ btn +"-"+ pane )
  85. .data("layoutName", o.name); // add layout identifier - even if blank!
  86. }
  87. return $E;
  88. }
  89. /**
  90. * NEW syntax for binding layout-buttons - will eventually replace addToggle, addOpen, etc.
  91. *
  92. * @param {(string|!Object)} sel jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
  93. * @param {string} action
  94. * @param {string} pane
  95. */
  96. , bind: function (inst, sel, action, pane) {
  97. var _ = $.layout.buttons;
  98. switch (action.toLowerCase()) {
  99. case "toggle": _.addToggle (inst, sel, pane); break;
  100. case "open": _.addOpen (inst, sel, pane); break;
  101. case "close": _.addClose (inst, sel, pane); break;
  102. case "pin": _.addPin (inst, sel, pane); break;
  103. case "toggle-slide": _.addToggle (inst, sel, pane, true); break;
  104. case "open-slide": _.addOpen (inst, sel, pane, true); break;
  105. }
  106. return inst;
  107. }
  108. /**
  109. * Add a custom Toggler button for a pane
  110. *
  111. * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
  112. * @param {string} pane Name of the pane the button is for: 'north', 'south', etc.
  113. * @param {boolean=} slide true = slide-open, false = pin-open
  114. */
  115. , addToggle: function (inst, selector, pane, slide) {
  116. $.layout.buttons.get(inst, selector, pane, "toggle")
  117. .click(function(evt){
  118. inst.toggle(pane, !!slide);
  119. evt.stopPropagation();
  120. });
  121. return inst;
  122. }
  123. /**
  124. * Add a custom Open button for a pane
  125. *
  126. * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
  127. * @param {string} pane Name of the pane the button is for: 'north', 'south', etc.
  128. * @param {boolean=} slide true = slide-open, false = pin-open
  129. */
  130. , addOpen: function (inst, selector, pane, slide) {
  131. $.layout.buttons.get(inst, selector, pane, "open")
  132. .attr("title", lang.Open)
  133. .click(function (evt) {
  134. inst.open(pane, !!slide);
  135. evt.stopPropagation();
  136. });
  137. return inst;
  138. }
  139. /**
  140. * Add a custom Close button for a pane
  141. *
  142. * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
  143. * @param {string} pane Name of the pane the button is for: 'north', 'south', etc.
  144. */
  145. , addClose: function (inst, selector, pane) {
  146. $.layout.buttons.get(inst, selector, pane, "close")
  147. .attr("title", lang.Close)
  148. .click(function (evt) {
  149. inst.close(pane);
  150. evt.stopPropagation();
  151. });
  152. return inst;
  153. }
  154. /**
  155. * Add a custom Pin button for a pane
  156. *
  157. * Four classes are added to the element, based on the paneClass for the associated pane...
  158. * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin:
  159. * - ui-layout-pane-pin
  160. * - ui-layout-pane-west-pin
  161. * - ui-layout-pane-pin-up
  162. * - ui-layout-pane-west-pin-up
  163. *
  164. * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
  165. * @param {string} pane Name of the pane the pin is for: 'north', 'south', etc.
  166. */
  167. , addPin: function (inst, selector, pane) {
  168. var $E = $.layout.buttons.get(inst, selector, pane, "pin");
  169. if ($E.length) {
  170. var s = inst.state[pane];
  171. $E.click(function (evt) {
  172. $.layout.buttons.setPinState(inst, $(this), pane, (s.isSliding || s.isClosed));
  173. if (s.isSliding || s.isClosed) inst.open( pane ); // change from sliding to open
  174. else inst.close( pane ); // slide-closed
  175. evt.stopPropagation();
  176. });
  177. // add up/down pin attributes and classes
  178. $.layout.buttons.setPinState(inst, $E, pane, (!s.isClosed && !s.isSliding));
  179. // add this pin to the pane data so we can 'sync it' automatically
  180. // PANE.pins key is an array so we can store multiple pins for each pane
  181. s.pins.push( selector ); // just save the selector string
  182. }
  183. return inst;
  184. }
  185. /**
  186. * Change the class of the pin button to make it look 'up' or 'down'
  187. *
  188. * @see addPin(), syncPins()
  189. * @param {Array.<Object>} $Pin The pin-span element in a jQuery wrapper
  190. * @param {string} pane These are the params returned to callbacks by layout()
  191. * @param {boolean} doPin true = set the pin 'down', false = set it 'up'
  192. */
  193. , setPinState: function (inst, $Pin, pane, doPin) {
  194. var updown = $Pin.attr("pin");
  195. if (updown && doPin === (updown=="down")) return; // already in correct state
  196. var
  197. pin = inst.options[pane].buttonClass +"-pin"
  198. , side = pin +"-"+ pane
  199. , UP = pin +"-up "+ side +"-up"
  200. , DN = pin +"-down "+side +"-down"
  201. ;
  202. $Pin
  203. .attr("pin", doPin ? "down" : "up") // logic
  204. .attr("title", doPin ? lang.Unpin : lang.Pin)
  205. .removeClass( doPin ? UP : DN )
  206. .addClass( doPin ? DN : UP )
  207. ;
  208. }
  209. /**
  210. * INTERNAL function to sync 'pin buttons' when pane is opened or closed
  211. * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes
  212. *
  213. * @see open(), close()
  214. * @param {string} pane These are the params returned to callbacks by layout()
  215. * @param {boolean} doPin True means set the pin 'down', False means 'up'
  216. */
  217. , syncPinBtns: function (inst, pane, doPin) {
  218. // REAL METHOD IS _INSIDE_ LAYOUT - THIS IS HERE JUST FOR REFERENCE
  219. $.each(state[pane].pins, function (i, selector) {
  220. $.layout.buttons.setPinState(inst, $(selector), pane, doPin);
  221. });
  222. }
  223. , _load: function (inst) {
  224. // ADD Button methods to Layout Instance
  225. $.extend( inst, {
  226. bindButton: function (selector, action, pane) { return $.layout.buttons.bind(inst, selector, action, pane); }
  227. // DEPRECATED METHODS...
  228. , addToggleBtn: function (selector, pane, slide) { return $.layout.buttons.addToggle(inst, selector, pane, slide); }
  229. , addOpenBtn: function (selector, pane, slide) { return $.layout.buttons.addOpen(inst, selector, pane, slide); }
  230. , addCloseBtn: function (selector, pane) { return $.layout.buttons.addClose(inst, selector, pane); }
  231. , addPinBtn: function (selector, pane) { return $.layout.buttons.addPin(inst, selector, pane); }
  232. });
  233. // init state array to hold pin-buttons
  234. for (var i=0; i<4; i++) {
  235. var pane = $.layout.buttons.config.borderPanes[i];
  236. inst.state[pane].pins = [];
  237. }
  238. // auto-init buttons onLoad if option is enabled
  239. if ( inst.options.autoBindCustomButtons )
  240. $.layout.buttons.init(inst);
  241. }
  242. , _unload: function (inst) {
  243. // TODO: unbind all buttons???
  244. }
  245. };
  246. // add initialization method to Layout's onLoad array of functions
  247. $.layout.onLoad.push( $.layout.buttons._load );
  248. //$.layout.onUnload.push( $.layout.buttons._unload );
  249. })( jQuery );