jquery.window.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /**
  2. * EasyUI for jQuery 1.5.5.4
  3. *
  4. * Copyright (c) 2009-2018 www.jeasyui.com. All rights reserved.
  5. *
  6. * Licensed under the freeware license: http://www.jeasyui.com/license_freeware.php
  7. * To use it on other terms please contact us: info@jeasyui.com
  8. *
  9. */
  10. /**
  11. * window - EasyUI for jQuery
  12. *
  13. * Dependencies:
  14. * panel
  15. * draggable
  16. * resizable
  17. *
  18. */
  19. (function($){
  20. function moveWindow(target, param){
  21. var state = $.data(target, 'window');
  22. if (param){
  23. if (param.left != null) state.options.left = param.left;
  24. if (param.top != null) state.options.top = param.top;
  25. }
  26. $(target).panel('move', state.options);
  27. if (state.shadow){
  28. state.shadow.css({
  29. left: state.options.left,
  30. top: state.options.top
  31. });
  32. }
  33. }
  34. /**
  35. * center the window only horizontally
  36. */
  37. function hcenter(target, tomove){
  38. var opts = $.data(target, 'window').options;
  39. var pp = $(target).window('panel');
  40. var width = pp._outerWidth();
  41. if (opts.inline){
  42. var parent = pp.parent();
  43. opts.left = Math.ceil((parent.width() - width) / 2 + parent.scrollLeft());
  44. } else {
  45. opts.left = Math.ceil(($(window)._outerWidth() - width) / 2 + $(document).scrollLeft());
  46. }
  47. if (tomove){moveWindow(target);}
  48. }
  49. /**
  50. * center the window only vertically
  51. */
  52. function vcenter(target, tomove){
  53. var opts = $.data(target, 'window').options;
  54. var pp = $(target).window('panel');
  55. var height = pp._outerHeight();
  56. if (opts.inline){
  57. var parent = pp.parent();
  58. opts.top = Math.ceil((parent.height() - height) / 2 + parent.scrollTop());
  59. } else {
  60. opts.top = Math.ceil(($(window)._outerHeight() - height) / 2 + $(document).scrollTop());
  61. }
  62. if (tomove){moveWindow(target);}
  63. }
  64. function create(target){
  65. var state = $.data(target, 'window');
  66. var opts = state.options;
  67. var win = $(target).panel($.extend({}, state.options, {
  68. border: false,
  69. doSize: true, // size the panel, the property undefined in window component
  70. closed: true, // close the panel
  71. cls: 'window ' + (!opts.border?'window-thinborder window-noborder ':(opts.border=='thin'?'window-thinborder ':'')) + (opts.cls || ''),
  72. headerCls: 'window-header ' + (opts.headerCls || ''),
  73. bodyCls: 'window-body ' + (opts.noheader ? 'window-body-noheader ' : ' ') + (opts.bodyCls||''),
  74. onBeforeDestroy: function(){
  75. if (opts.onBeforeDestroy.call(target) == false){return false;}
  76. if (state.shadow){state.shadow.remove();}
  77. if (state.mask){state.mask.remove();}
  78. },
  79. onClose: function(){
  80. if (state.shadow){state.shadow.hide();}
  81. if (state.mask){state.mask.hide();}
  82. opts.onClose.call(target);
  83. },
  84. onOpen: function(){
  85. if (state.mask){
  86. state.mask.css($.extend({
  87. display:'none',
  88. zIndex: $.fn.window.defaults.zIndex++
  89. }, $.fn.window.getMaskSize(target)));
  90. }
  91. if (state.shadow){
  92. state.shadow.css({
  93. display:'none',
  94. zIndex: $.fn.window.defaults.zIndex++,
  95. left: opts.left,
  96. top: opts.top,
  97. width: state.window._outerWidth(),
  98. height: state.window._outerHeight()
  99. });
  100. }
  101. state.window.css('z-index', $.fn.window.defaults.zIndex++);
  102. opts.onOpen.call(target);
  103. },
  104. onResize: function(width, height){
  105. var popts = $(this).panel('options');
  106. $.extend(opts, {
  107. width: popts.width,
  108. height: popts.height,
  109. left: popts.left,
  110. top: popts.top
  111. });
  112. if (state.shadow){
  113. state.shadow.css({
  114. left: opts.left,
  115. top: opts.top,
  116. width: state.window._outerWidth(),
  117. height: state.window._outerHeight()
  118. });
  119. }
  120. opts.onResize.call(target, width, height);
  121. },
  122. onMinimize: function(){
  123. if (state.shadow){state.shadow.hide();}
  124. if (state.mask){state.mask.hide();}
  125. state.options.onMinimize.call(target);
  126. },
  127. onBeforeCollapse: function(){
  128. if (opts.onBeforeCollapse.call(target) == false){return false;}
  129. if (state.shadow){state.shadow.hide();}
  130. },
  131. onExpand: function(){
  132. if (state.shadow){state.shadow.show();}
  133. opts.onExpand.call(target);
  134. }
  135. }));
  136. state.window = win.panel('panel');
  137. // create mask
  138. if (state.mask){state.mask.remove();}
  139. if (opts.modal){
  140. state.mask = $('<div class="window-mask" style="display:none"></div>').insertAfter(state.window);
  141. }
  142. // create shadow
  143. if (state.shadow){state.shadow.remove();}
  144. if (opts.shadow){
  145. state.shadow = $('<div class="window-shadow" style="display:none"></div>').insertAfter(state.window);
  146. }
  147. // center and open the window
  148. var closed = opts.closed;
  149. if (opts.left == null){hcenter(target);}
  150. if (opts.top == null){vcenter(target);}
  151. moveWindow(target);
  152. if (!closed){win.window('open');}
  153. }
  154. function constrain(left, top, width, height){
  155. var target = this;
  156. var state = $.data(target, 'window');
  157. var opts = state.options;
  158. if (!opts.constrain){return {};}
  159. if ($.isFunction(opts.constrain)){
  160. return opts.constrain.call(target, left, top, width, height);
  161. }
  162. var win = $(target).window('window');
  163. var parent = opts.inline ? win.parent() : $(window);
  164. if (left < 0){left = 0;}
  165. if (top < parent.scrollTop()){top = parent.scrollTop();}
  166. if (left + width > parent.width()){
  167. if (width == win.outerWidth()){ // moving
  168. left = parent.width() - width;
  169. } else { // resizing
  170. width = parent.width() - left;
  171. }
  172. }
  173. if (top - parent.scrollTop() + height > parent.height()){
  174. if (height == win.outerHeight()){ // moving
  175. top = parent.height() - height + parent.scrollTop();
  176. } else { // resizing
  177. height = parent.height() - top + parent.scrollTop();
  178. }
  179. }
  180. return {
  181. left:left,
  182. top:top,
  183. width:width,
  184. height:height
  185. };
  186. }
  187. /**
  188. * set window drag and resize property
  189. */
  190. function setProperties(target){
  191. var state = $.data(target, 'window');
  192. state.window.draggable({
  193. handle: '>div.panel-header>div.panel-title',
  194. disabled: state.options.draggable == false,
  195. onBeforeDrag: function(e){
  196. if (state.mask) state.mask.css('z-index', $.fn.window.defaults.zIndex++);
  197. if (state.shadow) state.shadow.css('z-index', $.fn.window.defaults.zIndex++);
  198. state.window.css('z-index', $.fn.window.defaults.zIndex++);
  199. },
  200. onStartDrag: function(e){
  201. start1(e);
  202. },
  203. onDrag: function(e){
  204. proc1(e);
  205. return false;
  206. },
  207. onStopDrag: function(e){
  208. stop1(e, 'move');
  209. }
  210. });
  211. state.window.resizable({
  212. disabled: state.options.resizable == false,
  213. onStartResize:function(e){
  214. start1(e);
  215. },
  216. onResize: function(e){
  217. proc1(e);
  218. return false;
  219. },
  220. onStopResize: function(e){
  221. stop1(e, 'resize');
  222. }
  223. });
  224. function start1(e){
  225. if (state.pmask){state.pmask.remove();}
  226. state.pmask = $('<div class="window-proxy-mask"></div>').insertAfter(state.window);
  227. state.pmask.css({
  228. display: 'none',
  229. zIndex: $.fn.window.defaults.zIndex++,
  230. left: e.data.left,
  231. top: e.data.top,
  232. width: state.window._outerWidth(),
  233. height: state.window._outerHeight()
  234. });
  235. if (state.proxy){state.proxy.remove();}
  236. state.proxy = $('<div class="window-proxy"></div>').insertAfter(state.window);
  237. state.proxy.css({
  238. display: 'none',
  239. zIndex: $.fn.window.defaults.zIndex++,
  240. left: e.data.left,
  241. top: e.data.top
  242. });
  243. state.proxy._outerWidth(e.data.width)._outerHeight(e.data.height);
  244. state.proxy.hide();
  245. setTimeout(function(){
  246. if (state.pmask){state.pmask.show();}
  247. if (state.proxy){state.proxy.show();}
  248. }, 500);
  249. }
  250. function proc1(e){
  251. $.extend(e.data, constrain.call(target, e.data.left, e.data.top, e.data.width, e.data.height));
  252. state.pmask.show();
  253. state.proxy.css({
  254. display: 'none',
  255. left: e.data.left,
  256. top: e.data.top
  257. });
  258. state.proxy._outerWidth(e.data.width);
  259. state.proxy._outerHeight(e.data.height);
  260. }
  261. function stop1(e, method){
  262. $.extend(e.data, constrain.call(target, e.data.left, e.data.top, e.data.width+0.1, e.data.height+0.1));
  263. $(target).window(method, e.data);
  264. state.pmask.remove();
  265. state.pmask = null;
  266. state.proxy.remove();
  267. state.proxy = null;
  268. }
  269. }
  270. // when window resize, reset the width and height of the window's mask
  271. $(function(){
  272. if (!$._positionFixed){
  273. $(window).resize(function(){
  274. $('body>div.window-mask:visible').css({
  275. width: '',
  276. height: ''
  277. });
  278. setTimeout(function(){
  279. $('body>div.window-mask:visible').css($.fn.window.getMaskSize());
  280. }, 50);
  281. });
  282. }
  283. });
  284. $.fn.window = function(options, param){
  285. if (typeof options == 'string'){
  286. var method = $.fn.window.methods[options];
  287. if (method){
  288. return method(this, param);
  289. } else {
  290. return this.panel(options, param);
  291. }
  292. }
  293. options = options || {};
  294. return this.each(function(){
  295. var state = $.data(this, 'window');
  296. if (state){
  297. $.extend(state.options, options);
  298. } else {
  299. state = $.data(this, 'window', {
  300. options: $.extend({}, $.fn.window.defaults, $.fn.window.parseOptions(this), options)
  301. });
  302. if (!state.options.inline){
  303. document.body.appendChild(this);
  304. }
  305. }
  306. create(this);
  307. setProperties(this);
  308. });
  309. };
  310. $.fn.window.methods = {
  311. options: function(jq){
  312. var popts = jq.panel('options');
  313. var wopts = $.data(jq[0], 'window').options;
  314. return $.extend(wopts, {
  315. closed: popts.closed,
  316. collapsed: popts.collapsed,
  317. minimized: popts.minimized,
  318. maximized: popts.maximized
  319. });
  320. },
  321. window: function(jq){
  322. return $.data(jq[0], 'window').window;
  323. },
  324. move: function(jq, param){
  325. return jq.each(function(){
  326. moveWindow(this, param);
  327. });
  328. },
  329. hcenter: function(jq){
  330. return jq.each(function(){
  331. hcenter(this, true);
  332. });
  333. },
  334. vcenter: function(jq){
  335. return jq.each(function(){
  336. vcenter(this, true);
  337. });
  338. },
  339. center: function(jq){
  340. return jq.each(function(){
  341. hcenter(this);
  342. vcenter(this);
  343. moveWindow(this);
  344. });
  345. }
  346. };
  347. $.fn.window.getMaskSize = function(target){
  348. var state = $(target).data('window');
  349. if (state && state.options.inline){
  350. return {};
  351. } else if ($._positionFixed){
  352. return {position: 'fixed'};
  353. } else {
  354. return {
  355. width: $(document).width(),
  356. height: $(document).height()
  357. };
  358. }
  359. };
  360. $.fn.window.parseOptions = function(target){
  361. return $.extend({}, $.fn.panel.parseOptions(target), $.parser.parseOptions(target, [
  362. {draggable:'boolean',resizable:'boolean',shadow:'boolean',modal:'boolean',inline:'boolean'}
  363. ]));
  364. };
  365. // Inherited from $.fn.panel.defaults
  366. $.fn.window.defaults = $.extend({}, $.fn.panel.defaults, {
  367. zIndex: 9000,
  368. draggable: true,
  369. resizable: true,
  370. shadow: true,
  371. modal: false,
  372. border: true, // possible values are: true,false,'thin','thick'
  373. inline: false, // true to stay inside its parent, false to go on top of all elements
  374. // window's property which difference from panel
  375. title: 'New Window',
  376. collapsible: true,
  377. minimizable: true,
  378. maximizable: true,
  379. closable: true,
  380. closed: false,
  381. constrain: false
  382. /*
  383. constrain: function(left,top,width,height){
  384. return {
  385. left:left,
  386. top:top,
  387. width:width,
  388. height:height
  389. };
  390. }
  391. */
  392. });
  393. })(jQuery);