Opened 7 years ago

Closed 6 years ago

#8217 closed bug (duplicate)

Resizable: Containment, which is grandparent, is not considered right.

Reported by: franz@… Owned by:
Priority: minor Milestone: 2.0.0
Component: ui.resizable Version: 1.8.18
Keywords: Cc:
Blocked by: Blocking:

Description

The containment isn't considered right, if the resizable is a grandchild of the containment.

http://jsfiddle.net/Tw8EU/11/

I could solve the bug for my application by changing the line 706-710 from

  var isParent = self.containerElement.get(0) == self.element.parent().get(0),
  isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));

  if(isParent && isOffsetRelative) woset -= self.parentData.left;

to

  woset -= self.parentData.left;

As I haven't had time to understand the calculations, I don't know, if this fixes really fixes the problem.

Maybe the isParent calculation should consider not only the direct parent, but all parents of the element? In the sense of “isAncestor”?

Change History (5)

comment:1 Changed 7 years ago by franz@…

The wrong fiddle seems to be attached. I've recreated the case on

http://jsfiddle.net/Tw8EU/14/

What's wrong there: The containment is the box with the black border. It's not possible to extend the image until the right border of this box – it just stops 50px left of it, which is the left position of the containment.

Last edited 7 years ago by franz@… (previous) (diff)

comment:2 in reply to:  description Changed 7 years ago by franz@…

The same problem appears on the left and the top border. See

http://jsfiddle.net/Tw8EU/16/

Starting the resize procedure moves the image to the green border, but the containment has the black border.

In this case, left and top are negative offets to the parent, but still positive ones to the containment.

comment:3 Changed 7 years ago by franz@…

I've rewritten the complete plugin now, I've tested it using Firefox, with and without the ghost and the helper setting.

Unfortunately, github cannot create a new account now, so I paste the code here:

$.ui.plugin.add("resizable", "containment", {

	start: function(event, ui) {
		var self = $(this).data("resizable"), o = self.options, el = self.element;
		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
		if (!ce) return;

		self.containerElement = $(ce);

		if (/document/.test(oc) || oc == document) {
			self.parentData = {
				element: $(document), left: 0, top: 0,
				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
			};
		}

		// i'm a node, so compute top, left, right, bottom
		else {
			var element = $(ce), p = [];
			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });

			self.containerOffset = element.offset();
			self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };

			var co = self.containerOffset, ch = self.containerSize.height,	cw = self.containerSize.width,
						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);

			self.parentData = {
				element: ce, left: co.left, top: co.top, width: width, height: height
			};
		}
		
		var offsetParent = el.offsetParent();
		var parentOffset = $(offsetParent).offset();
		
		if(self._helper) {
			parentOffset = {left: 0, top: 0};
		}
		
		self.containerData = {
			element: self.parentData.element, 
			left: self.parentData.left - parentOffset.left, 
			top: self.parentData.top - parentOffset.top, 
			right: self.parentData.left - parentOffset.left + self.parentData.width, 
			bottom: self.parentData.top - parentOffset.top + self.parentData.height,
			parentOffset: $(offsetParent).offset()
		};
	},

	resize: function(event, ui) {
		var self = $(this).data("resizable"), 
			o = self.options,
			cp = self.position,
			pRatio = self._aspectRatio || event.shiftKey,
			cd = self.containerData;
		
		if(cp.left < cd.left) {
			self.size.width = self.size.width - (cd.left - cp.left);
			if (pRatio) self.size.height = self.size.width / o.aspectRatio;
			self.position.left = cd.left;			
		}
		
		if(cp.top < cd.top) {
			self.size.height = self.size.height - (cd.top - cp.top);
			if (pRatio) self.size.width = self.size.height * o.aspectRatio;
			self.position.top = cd.top;			
		}
		
		var right = self.position.left + self.size.width;
		var bottom = self.position.top + self.size.height;
		
		if(right > cd.right) {
			self.size.width = self.size.width - (right - cd.right);
			if (pRatio) self.size.height = self.size.width / o.aspectRatio;
		}
		
		if(bottom > cd.bottom) {
			self.size.height = self.size.height - (bottom - cd.bottom);
			if (pRatio) self.size.width = self.size.height * o.aspectRatio;
		}
	},

	stop: function(event, ui){
		var self = $(this).data("resizable"), 
			o = self.options, 
			cd = self.containerData,
			ce = self.containerElement;

		var helper = $(self.helper),
			ho = helper.offset(), 
			w = helper.outerWidth() - self.sizeDiff.width, 
			h = helper.outerHeight() - self.sizeDiff.height;

		if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
			$(this).css({ left: ho.left - cd.parentOffset.left, width: w, height: h });

		if (self._helper && !o.animate && (/static/).test(ce.css('position')))
			$(this).css({ left: ho.left - cd.parentOffset.left, width: w, height: h });

	}
});

comment:4 Changed 7 years ago by Scott González

Milestone: 1.9.02.0.0

comment:5 Changed 6 years ago by tj.vantoll

Resolution: duplicate
Status: newclosed

Duplicate of #7485.

Note: See TracTickets for help on using tickets.