ui.resizable.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. (function($) {
  2. //Make nodes selectable by expression
  3. $.extend($.expr[':'], { resizable: "(' '+a.className+' ').indexOf(' ui-resizable ')" });
  4. $.fn.resizable = function(o) {
  5. return this.each(function() {
  6. if(!$(this).is(".ui-resizable")) new $.ui.resizable(this,o);
  7. });
  8. }
  9. //Macros for external methods that support chaining
  10. var methods = "destroy,enable,disable".split(",");
  11. for(var i=0;i<methods.length;i++) {
  12. var cur = methods[i], f;
  13. eval('f = function() { var a = arguments; return this.each(function() { if(jQuery(this).is(".ui-resizable")) jQuery.data(this, "ui-resizable")["'+cur+'"](a); if(jQuery(this.parentNode).is(".ui-resizable")) jQuery.data(this, "ui-resizable")["'+cur+'"](a); }); }');
  14. $.fn["resizable"+cur.substr(0,1).toUpperCase()+cur.substr(1)] = f;
  15. };
  16. //get instance method
  17. $.fn.resizableInstance = function() {
  18. if($(this[0]).is(".ui-resizable") || $(this[0].parentNode).is(".ui-resizable")) return $.data(this[0], "ui-resizable");
  19. return false;
  20. };
  21. $.ui.resizable = function(el,o) {
  22. var options = {}; o = o || {}; $.extend(options, o); //Extend and copy options
  23. this.element = el; var self = this; //Do bindings
  24. $.data(this.element, "ui-resizable", this);
  25. if(options.proxy) {
  26. var helper = function(e,that) {
  27. var helper = $('<div></div>').css({
  28. width: $(this).width(),
  29. height: $(this).height(),
  30. position: 'absolute',
  31. left: that.options.co.left,
  32. top: that.options.co.top
  33. }).addClass(that.options.proxy);
  34. return helper;
  35. }
  36. } else {
  37. var helper = "original";
  38. }
  39. //Destructive mode wraps the original element
  40. if(el.nodeName.match(/textarea|input|select|button|img/i)) options.destructive = true;
  41. if(options.destructive) {
  42. $(el).wrap('<div class="ui-wrapper" style="position: relative; width: '+$(el).outerWidth()+'px; height: '+$(el).outerHeight()+';"></div>');
  43. var oel = el;
  44. el = el.parentNode; this.element = el;
  45. //Move margins to the wrapper
  46. $(el).css({ marginLeft: $(oel).css("marginLeft"), marginTop: $(oel).css("marginTop"), marginRight: $(oel).css("marginRight"), marginBottom: $(oel).css("marginBottom")});
  47. $(oel).css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
  48. o.proportionallyResize = o.proportionallyResize || [];
  49. o.proportionallyResize.push(oel);
  50. var b = [parseInt($(oel).css('borderTopWidth')),parseInt($(oel).css('borderRightWidth')),parseInt($(oel).css('borderBottomWidth')),parseInt($(oel).css('borderLeftWidth'))];
  51. } else {
  52. var b = [0,0,0,0];
  53. }
  54. if(options.destructive || !$(".ui-resizable-handle",el).length) {
  55. //Adding handles (disabled not so common ones)
  56. var t = function(a,b) { $(el).append("<div class='ui-resizable-"+a+" ui-resizable-handle' style='"+b+"'></div>"); };
  57. //t('n','top: '+b[0]+'px;');
  58. t('e','right: '+b[1]+'px;'+(options.zIndex ? 'z-index: '+options.zIndex+';' : ''));
  59. t('s','bottom: '+b[1]+'px;'+(options.zIndex ? 'z-index: '+options.zIndex+';' : ''));
  60. //t('w','left: '+b[3]+'px;');
  61. t('se','bottom: '+b[2]+'px; right: '+b[1]+'px;'+(options.zIndex ? 'z-index: '+options.zIndex+';' : ''));
  62. //t('sw','bottom: '+b[2]+'px; left: '+b[3]+'px;');
  63. //t('ne','top: '+b[0]+'px; right: '+b[1]+'px;');
  64. //t('nw','top: '+b[0]+'px; left: '+b[3]+'px;');
  65. }
  66. //If other elements should be modified, we have to copy that array
  67. options.modifyThese = [];
  68. if(o.proportionallyResize) {
  69. options.proportionallyResize = o.proportionallyResize.slice(0);
  70. var propRes = options.proportionallyResize;
  71. for(var i in propRes) {
  72. if(propRes[i].constructor == String)
  73. propRes[i] = $(propRes[i], el);
  74. if(!$(propRes[i]).length) continue;
  75. var x = $(propRes[i]).width() - $(el).width();
  76. var y = $(propRes[i]).height() - $(el).height();
  77. options.modifyThese.push([$(propRes[i]),x,y]);
  78. }
  79. }
  80. options.handles = {};
  81. if(!o.handles) o.handles = { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' };
  82. for(var i in o.handles) { options.handles[i] = o.handles[i]; } //Copying the object
  83. for(var i in options.handles) {
  84. if(options.handles[i].constructor == String)
  85. options.handles[i] = $(options.handles[i], el);
  86. if(!$(options.handles[i]).length) continue;
  87. $(options.handles[i]).bind('mousedown', function(e) {
  88. self.interaction.options.axis = this.resizeAxis;
  89. })[0].resizeAxis = i;
  90. }
  91. //If we want to auto hide the elements
  92. if(o.autohide)
  93. $(this.element).addClass("ui-resizable-autohide").hover(function() { $(this).removeClass("ui-resizable-autohide"); }, function() { if(self.interaction.options.autohide && !self.interaction.init) $(this).addClass("ui-resizable-autohide"); });
  94. $.extend(options, {
  95. helper: helper,
  96. nonDestructive: true,
  97. dragPrevention: 'input,button,select',
  98. minHeight: options.minHeight || 50,
  99. minWidth: options.minWidth || 100,
  100. startCondition: function(e) {
  101. if(self.disabled) return false;
  102. for(var i in options.handles) {
  103. if($(options.handles[i])[0] == e.target) return true;
  104. }
  105. return false;
  106. },
  107. _start: function(h,p,c,t,e) {
  108. self.start.apply(t, [self, e]); // Trigger the start callback
  109. },
  110. _beforeStop: function(h,p,c,t,e) {
  111. self.stop.apply(t, [self, e]); // Trigger the stop callback
  112. },
  113. _drag: function(h,p,c,t,e) {
  114. self.drag.apply(t, [self, e]); // Trigger the start callback
  115. }
  116. });
  117. //Initialize mouse interaction
  118. this.interaction = new $.ui.mouseInteraction(el,options);
  119. //Add the class for themeing
  120. $(this.element).addClass("ui-resizable");
  121. }
  122. $.extend($.ui.resizable.prototype, {
  123. plugins: {},
  124. prepareCallbackObj: function(self) {
  125. return {
  126. helper: self.helper,
  127. resizable: self,
  128. axis: self.options.axis,
  129. options: self.options
  130. }
  131. },
  132. destroy: function() {
  133. $(this.element).removeClass("ui-resizable").removeClass("ui-resizable-disabled");
  134. this.interaction.destroy();
  135. },
  136. enable: function() {
  137. $(this.element).removeClass("ui-resizable-disabled");
  138. this.disabled = false;
  139. },
  140. disable: function() {
  141. $(this.element).addClass("ui-resizable-disabled");
  142. this.disabled = true;
  143. },
  144. start: function(that, e) {
  145. this.options.originalSize = [$(this.element).width(),$(this.element).height()];
  146. this.options.originalPosition = $(this.element).css("position");
  147. this.options.originalPositionValues = $(this.element).position();
  148. this.options.modifyThese.push([$(this.helper),0,0]);
  149. $(that.element).triggerHandler("resizestart", [e, that.prepareCallbackObj(this)], this.options.start);
  150. return false;
  151. },
  152. stop: function(that, e) {
  153. var o = this.options;
  154. $(that.element).triggerHandler("resizestop", [e, that.prepareCallbackObj(this)], this.options.stop);
  155. if(o.proxy) {
  156. $(this.element).css({
  157. width: $(this.helper).width(),
  158. height: $(this.helper).height()
  159. });
  160. if(o.originalPosition == "absolute" || o.originalPosition == "fixed") {
  161. $(this.element).css({
  162. top: $(this.helper).css("top"),
  163. left: $(this.helper).css("left")
  164. });
  165. }
  166. }
  167. return false;
  168. },
  169. drag: function(that, e) {
  170. var o = this.options;
  171. var rel = (o.originalPosition != "absolute" && o.originalPosition != "fixed");
  172. var co = rel ? o.co : this.options.originalPositionValues;
  173. var p = o.originalSize;
  174. this.pos = rel ? [this.rpos[0]-o.cursorAt.left, this.rpos[1]-o.cursorAt.top] : [this.pos[0]-o.cursorAt.left, this.pos[1]-o.cursorAt.top];
  175. var nw = p[0] + (this.pos[0] - co.left);
  176. var nh = p[1] + (this.pos[1] - co.top);
  177. if(o.axis) {
  178. switch(o.axis) {
  179. case 'e':
  180. nh = p[1];
  181. break;
  182. case 's':
  183. nw = p[0];
  184. break;
  185. case 'n':
  186. case 'ne':
  187. if(!o.proxy && (o.originalPosition != "absolute" && o.originalPosition != "fixed"))
  188. return false;
  189. if(o.axis == 'n') nw = p[0];
  190. var mod = (this.pos[1] - co.top); nh = nh - (mod*2);
  191. mod = nh <= o.minHeight ? p[1] - o.minHeight : (nh >= o.maxHeight ? 0-(o.maxHeight-p[1]) : mod);
  192. $(this.helper).css('top', co.top + mod);
  193. break;
  194. case 'w':
  195. case 'sw':
  196. if(!o.proxy && (o.originalPosition != "absolute" && o.originalPosition != "fixed"))
  197. return false;
  198. if(o.axis == 'w') nh = p[1];
  199. var mod = (this.pos[0] - co.left); nw = nw - (mod*2);
  200. mod = nw <= o.minWidth ? p[0] - o.minWidth : (nw >= o.maxWidth ? 0-(o.maxWidth-p[0]) : mod);
  201. $(this.helper).css('left', co.left + mod);
  202. break;
  203. case 'nw':
  204. if(!o.proxy && (o.originalPosition != "absolute" && o.originalPosition != "fixed"))
  205. return false;
  206. var modx = (this.pos[0] - co.left); nw = nw - (modx*2);
  207. modx = nw <= o.minWidth ? p[0] - o.minWidth : (nw >= o.maxWidth ? 0-(o.maxWidth-p[0]) : modx);
  208. var mody = (this.pos[1] - co.top); nh = nh - (mody*2);
  209. mody = nh <= o.minHeight ? p[1] - o.minHeight : (nh >= o.maxHeight ? 0-(o.maxHeight-p[1]) : mody);
  210. $(this.helper).css({
  211. left: co.left + modx,
  212. top: co.top + mody
  213. });
  214. break;
  215. }
  216. }
  217. if(e.shiftKey) nh = nw * (p[1]/p[0]);
  218. if(o.minWidth) nw = nw <= o.minWidth ? o.minWidth : nw;
  219. if(o.minHeight) nh = nh <= o.minHeight ? o.minHeight : nh;
  220. if(o.maxWidth) nw = nw >= o.maxWidth ? o.maxWidth : nw;
  221. if(o.maxHeight) nh = nh >= o.maxHeight ? o.maxHeight : nh;
  222. if(e.shiftKey) nh = nw * (p[1]/p[0]);
  223. var modifier = $(that.element).triggerHandler("resize", [e, that.prepareCallbackObj(this)], o.resize);
  224. if(!modifier) modifier = {};
  225. for(var i in this.options.modifyThese) {
  226. var c = this.options.modifyThese[i];
  227. c[0].css({
  228. width: modifier.width ? modifier.width+c[1] : nw+c[1],
  229. height: modifier.height ? modifier.height+c[2] : nh+c[2]
  230. });
  231. }
  232. return false;
  233. }
  234. });
  235. })($);