This example shows how you can use Overlay's constrained positioning support to constrain the XY position of the overlay so that it remains within another node on the page (or within the viewport).
As with the "Basic XY Positioning" example, to create an instance of an Overlay on your page, the only module you need to request is the overlay
module. The overlay
module will pull in the widget
, widget-stack
, widget-position
, widget-position-align
, widget-position-constrain
and widget-stdmod
extensions it uses.
YUI({...}).use("overlay", function (Y) { // We'll write example code here, where we have a Y.Overlay class // available, which is bundled with XY positioning, align and // constrain support. });
Using the overlay
module, will also pull down the default CSS required for overlay, on top of which we only need to add our required look/feel CSS for the example.
Note: be sure to add the yui3-skin-sam
classname to the
page's <body>
element or to a parent element of the widget in order to apply
the default CSS skin. See Understanding Skinning.
<body class="yui3-skin-sam"> <!-- You need this skin class -->
For this example, we'll instantiate an Overlay from script, as we did for the "Alignment Support" example, but use the render
attribute to specify the node under which we want the Overlay to be rendered in the DOM, and to indicate that we want it rendered on construction. The render
attribute is a sugar attribute for the render()
method:
// Create Overlay from script. overlay = new Y.Overlay({ id: "overlay", width : "140px", height: "120px", headerContent: "Constrained", bodyContent : "Use the sliders to move the overlay", footerContent: '<label><input type="checkbox" id="constrain"> Constrain </label>', constrain: "#constrain-box", align : { node : "#constrain-box", points: ["cc", "cc"] }, render: "#overlay-example" });
We align the overlay to the center of the #constrain-box
node, which we're also using as the constraining node for the overlay. The constrain
attribute accepts a node reference (either an actual Node instance, or a string selector reference), or it can simply be set to true
to constrain the overlay to the Viewport.
For this example, we set up a couple of Slider instances which can be used to set the Overlay's x
and y
attribute values.
// Get the region for the constraining box. var constrainRegion = Y.one("#constrain-box").get("region"); // Use the Overlay's current `x` and `y` to set the initial Slider values. // Create horizontal Slider. sx = new Y.Slider({ id : "x", length: "450px", min : constrainRegion.left - 50, max : constrainRegion.right + 50, value : overlay.get("x"), render: "#overlay-example" }); // Create vertical Slider. sy = new Y.Slider({ id : "y", axis : 'y', length: "400px", min : constrainRegion.top - 50, max : constrainRegion.bottom + 50, value : overlay.get("y"), render: "#overlay-example" });
We set the min
and max
values of the slider instances to allow the overlay to be moved beyond the edge of the constraining region, and set the initial value
of the sliders to reflect the current centered position of the overlay.
Finally, we set up valueChange
listeners for the sliders, when attempt to set the corresponding axis position of the overlay:
// Set the Overlay's `x` attribute value. sx.after("valueChange", function (e) { overlay.set("x", e.newVal); }); // Set the Overlay's `y` attribute value. sy.after("valueChange", function (e) { overlay.set("y", e.newVal); });
As mentioned in the "Basic XY Positioning" example, the overlay.css Sam Skin file (build/overlay/assets/skins/sam/overlay.css) provides the default functional CSS for the overlay. Namely the CSS rules to hide the overlay, and position it absolutely. However there's no default out-of-the-box look/feel applied to the Overlay widget.
The example provides it's own look and feel for the Overlay, by defining rules for the content box, header and body sections:
/* Overlay Look/Feel */ .yui3-overlay-content { background-color: #ECEFFB; border: 1px solid #9EA8C6; border-radius: 3px; box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.25); } .yui3-overlay-content .yui3-widget-hd { background-color: #B6BFDA; color: #30418C; font-size: 120%; font-weight: bold; padding: 0.2em 0.5em 0.3em; border-radius: 2px 2px 0 0; } .yui3-overlay-content .yui3-widget-bd { padding: 0.4em 0.6em 0.5em; } .yui3-overlay-content .yui3-widget-ft { background-color:#DFE3F5; padding: 0.4em 0.6em 0.5em; border-radius: 0 0 2px 2px; }
<div class="overlay-example yui3-skin-sam" id="overlay-example"> <div id="constrain-box"></div> </div> <script type="text/javascript"> YUI().use("overlay", "slider", function (Y) { var constrainRegion = Y.one("#constrain-box").get("region"), overlay, sx, yx, checkbox; // Create Overlay from script. overlay = new Y.Overlay({ id: "overlay", width : "150px", height: "120px", headerContent: "Constrained", bodyContent : "Use the sliders to move the overlay", footerContent: '<label><input type="checkbox" id="constrain"> Constrain </label>', constrain: "#constrain-box", align : { node : "#constrain-box", points: ["cc", "cc"] }, render: "#overlay-example" }); // Create horizontal Slider. sx = new Y.Slider({ id : "x", length: "450px", min : constrainRegion.left - 50, max : constrainRegion.right + 50, value : overlay.get("x"), render: "#overlay-example" }); // Create vertical Slider. sy = new Y.Slider({ id : "y", axis : 'y', length: "400px", min : constrainRegion.top - 50, max : constrainRegion.bottom + 50, value : overlay.get("y"), render: "#overlay-example" }); sx.after("valueChange", function (e) { overlay.set("x", e.newVal); }); sy.after("valueChange", function (e) { overlay.set("y", e.newVal); }); function enableConstraints (constrain) { if (constrain) { overlay.set("constrain", "#constrain-box"); overlay.set("headerContent", "Constrained"); } else { overlay.set("constrain", false); overlay.set("headerContent", "Unconstrained"); } // Sync the current values of the sliders to the overlay. overlay.set("xy", [sx.get("value"), sy.get("value")]); } // Reference `<input type="checkbox" />` from the Overlay's footer. checkbox = Y.one("#constrain"); checkbox.set("checked", true); checkbox.on("click", function (e) { enableConstraints(this.get("checked")); }); // Enable constraints by default. enableConstraints(true); }); </script>