Yahoo! Developer Network Home - Help

YDN Site Search

# YUI Library Examples: Container Family: Creating a Resizable Panel

# Container Family: Creating a Resizable Panel

Operating systems offer windows that can be resized, often by dragging from the lower right-hand corner (and, on Microsoft Windows, from the window edges). This example of the Panel Control implements resizability by creating a subclass which provides a handle for resizing the panel from the lower right-hand corner. Click the button below to show the panel, then use the bottom-right corner to resize it.

View example in new window.

ResizePanel #1 from Markup

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Suspendisse nulla. Fusce mauris massa, rutrum eu, imperdiet ut, placerat at, nunc. Vestibulum consequat ligula ut lacus. Nulla nec pede. Fusce consequat, augue et eleifend ornare, nibh mi dapibus lorem, ut lacinia turpis eros at eros. Proin laoreet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla velit. Fusce id sem sit amet felis porta mollis. Aliquam erat volutpat. Etiam tortor. Donec dui felis, pretium quis, vulputate et, molestie non, nisi.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Suspendisse nulla. Fusce mauris massa, rutrum eu, imperdiet ut, placerat at, nunc. Vestibulum consequat ligula ut lacus. Nulla nec pede. Fusce consequat, augue et eleifend ornare, nibh mi dapibus lorem, ut lacinia turpis eros at eros. Proin laoreet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla velit. Fusce id sem sit amet felis porta mollis. Aliquam erat volutpat. Etiam tortor. Donec dui felis, pretium quis, vulputate et, molestie non, nisi.

## Subclassing Panel to Create ResizePanel

In this tutorial, we will build a subclass for Panel called ResizePanel that will allow the Panel to be resized using a draggable handle in the bottom-right corner of the footer.

The first step to subclassing the Panel is writing the constructor for the new subclass (ResizePanel, in this case) and specifying its inheritance from the Panel class using YAHOO.extend:

YAHOO.namespace("example.container"); // BEGIN RESIZEPANEL SUBCLASS // YAHOO.widget.ResizePanel = function(el, userConfig) { if (arguments.length > 0) { YAHOO.widget.ResizePanel.superclass.constructor.call(this, el, userConfig); } }

Next, we will define a few constants for use by the ResizePanel class: "CSS_PANEL_RESIZE", which defines the CSS class to apply to the Panel, and "CSS_RESIZE_HANDLE", the CSS class to apply to the resize handler.

YAHOO.widget.ResizePanel.CSS_PANEL_RESIZE = "yui-resizepanel"; YAHOO.widget.ResizePanel.CSS_RESIZE_HANDLE = "resizehandle";

Next, the initialization method for the ResizePanel is defined. The first step the initialization must perform is to call the superclass's init method so that the superclasses can initialize first. After that, take the following steps:

1. We fire the beforeInitEvent and add the CSS class to the Panel;
2. We create the element that will serve as the resize handle in the footer;
3. We make sure that the footer is set to blank text if no footer is specified by render time, since a footer is required in order for the ResizePanel to function properly.
4. Finally, we subscribe a function `onBeforeRender` to the Panel's beforeRender event wherein we'll configure the resize handle's Drag and Drop instance (instance of YAHOO.util.DragDrop). The resize is achieved by calculating the difference in position between the handle's start point and end point.

YAHOO.extend(YAHOO.widget.ResizePanel, YAHOO.widget.Panel, { init: function(el, userConfig) { YAHOO.widget.ResizePanel.superclass.init.call(this, el); this.beforeInitEvent.fire(YAHOO.widget.ResizePanel); var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, oInnerElement = this.innerElement, oResizeHandle = document.createElement("DIV"), sResizeHandleId = this.id + "_resizehandle"; oResizeHandle.id = sResizeHandleId; oResizeHandle.className = YAHOO.widget.ResizePanel.CSS_RESIZE_HANDLE; Dom.addClass(oInnerElement, YAHOO.widget.ResizePanel.CSS_PANEL_RESIZE); this.resizeHandle = oResizeHandle; function initResizeFunctionality() { var me = this, oHeader = this.header, oBody = this.body, oFooter = this.footer, nStartWidth, nStartHeight, aStartPos, nBodyBorderTopWidth, nBodyBorderBottomWidth, nBodyTopPadding, nBodyBottomPadding, nBodyOffset; oInnerElement.appendChild(oResizeHandle); this.ddResize = new YAHOO.util.DragDrop(sResizeHandleId, this.id); this.ddResize.setHandleElId(sResizeHandleId); this.ddResize.onMouseDown = function(e) { nStartWidth = oInnerElement.offsetWidth; nStartHeight = oInnerElement.offsetHeight; if (YAHOO.env.ua.ie && document.compatMode == "BackCompat") { nBodyOffset = 0; } else { nBodyBorderTopWidth = parseInt(Dom.getStyle(oBody, "borderTopWidth"), 10), nBodyBorderBottomWidth = parseInt(Dom.getStyle(oBody, "borderBottomWidth"), 10), nBodyTopPadding = parseInt(Dom.getStyle(oBody, "paddingTop"), 10), nBodyBottomPadding = parseInt(Dom.getStyle(oBody, "paddingBottom"), 10), nBodyOffset = nBodyBorderTopWidth + nBodyBorderBottomWidth + nBodyTopPadding + nBodyBottomPadding; } me.cfg.setProperty("width", nStartWidth + "px"); aStartPos = [Event.getPageX(e), Event.getPageY(e)]; }; this.ddResize.onDrag = function(e) { var aNewPos = [Event.getPageX(e), Event.getPageY(e)], nOffsetX = aNewPos[0] - aStartPos[0], nOffsetY = aNewPos[1] - aStartPos[1], nNewWidth = Math.max(nStartWidth + nOffsetX, 10), nNewHeight = Math.max(nStartHeight + nOffsetY, 10), nBodyHeight = (nNewHeight - (oFooter.offsetHeight + oHeader.offsetHeight + nBodyOffset)); me.cfg.setProperty("width", nNewWidth + "px"); if (nBodyHeight < 0) { nBodyHeight = 0; } oBody.style.height = nBodyHeight + "px"; }; } function onBeforeShow() { initResizeFunctionality.call(this); this.unsubscribe("beforeShow", onBeforeShow); } function onBeforeRender() { if (!this.footer) { this.setFooter(""); } if (this.cfg.getProperty("visible")) { initResizeFunctionality.call(this); } else { this.subscribe("beforeShow", onBeforeShow); } this.unsubscribe("beforeRender", onBeforeRender); } this.subscribe("beforeRender", onBeforeRender); if (userConfig) { this.cfg.applyConfig(userConfig, true); } this.initEvent.fire(YAHOO.widget.ResizePanel); }, toString: function() { return "ResizePanel " + this.id; } });

### YUI Logger Output:

Note: Logging and debugging is currently turned off for this example.

Reload with logging
and debugging enabled.

### Container Family Examples:

- The Module Control
- Creating and Positioning an Overlay
- Simple Tooltip Example
- One Tooltip, Many Context Elements
- Simple Panel Example
- Skinning a Panel with Custom CSS: Introduction
- Skinning a Panel with Custom CSS: Advanced
- Creating a "Loading" Panel
- Creating a Resizable Panel
- Dialog Quickstart Example
- SimpleDialog Quickstart Example
- Using ContainerEffect Transitions
- Using the Overlay Manager to Manage Multiple Panels
- Implementing Container Keyboard Shortcuts with KeyListener
- Example of Color Picker Built in a Dialog via JavaScript (included with examples for Color Picker Control (beta))
- Calendar inside a Container (included with examples for Calendar Control)
- Menu Buttons (included with examples for Button Control)
- Split Buttons (included with examples for Button Control)
- Calendar Menu Button (included with examples for Button Control)
- Calendar Split Button (included with examples for Button Control)
- Color Picker Button (included with examples for Button Control)
- Fixed Width Menu Button (included with examples for Button Control)
- OS-Style Programs Menu (included with examples for Menu Family)
- Application Menubar (included with examples for Menu Family)
- Slider Button (included with examples for Button Control)

### More Container Family Resources:

- User's Guide (external)
- API Documentation
- Cheat Sheet PDF (external)

Copyright © 2007 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings