Skip to content

Instantly share code, notes, and snippets.

@tilomitra
Created August 10, 2011 23:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tilomitra/1138587 to your computer and use it in GitHub Desktop.
Save tilomitra/1138587 to your computer and use it in GitHub Desktop.
component.json for panel
{
"name" : "panel",
"displayName": "Panel",
"description": "The Panel is a UI Control that is meant to behave similarly to an OS window. The Panel control extends the functionality of Overlay, adding support for modality, close/dismiss buttons, autohiding and autofocus. Plugins to make it draggable and resizable are supported as well. Panel includes a pre-defined stylesheet to support default look and feel characteristics.",
"author" : "tilomitra",
"tags": ["widget", "beta", "panel", "extension"],
"use" : ["panel"],
"examples" : [
{
"name" : "panel-form",
"displayName": "Creating a modal form",
"description": "Shows how to instantiate multiple Panel instances, and use nested modality to interact with a Datatable.",
"modules" : ["panel", "datatable"],
"tags" : ["panel", "datatable"],
"hideTableOfContents": true
},
{
"name" : "panel-animate",
"displayName": "Creating an animated panel",
"description": "Shows how to create a panel that animates as it is shown and hidden",
"modules" : ["panel", "transition"],
"tags" : ["panel", "transition"],
"hideTableOfContents": true
}
],
"pages": {
"panel-form-example": {
"displayName": "Using a panel to show a modal form",
"layout": "panel-example"
},
"panel-animate-example": {
"displayName": "Creating an animated panel using transitions",
"layout": "panel-example"
}
}
}
<!DOCTYPE html>
<html lang="en" class="yui3-loading">
<head>
<meta charset="utf-8">
<title>{{title}}</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/combo?{{yuiVersion}}/build/cssreset/reset-min.css&amp;{{yuiVersion}}/build/cssfonts/fonts-min.css&amp;{{yuiVersion}}/build/cssgrids/grids-min.css&amp;{{yuiVersion}}/build/cssbase/base-min.css">
<script src="{{yuiSeedUrl}}"></script>
</head>
<body class="yui3-skin-sam">
{{>layout_content}}
</body>
</html>
#desc {
margin-bottom:20px;
border-bottom:1px dotted #333;
}
#desc span {
background:#a3350d;
padding:2px;
color:#f27243;
}
.yui3-panel {
outline:none;
}
.yui3-panel-content .yui3-widget-hd {
font-weight:bold;
}
.yui3-panel-content .yui3-widget-bd {
padding:15px;
}
.yui3-panel-content label {
margin-right:30px;
}
.yui3-panel-content fieldset {
border:none;
padding:0;
}
.yui3-panel-content input[type="text"] {
border:none;
border:1px solid #ccc;
padding: 3px 7px;
-webkit-border-radius:2px;
-moz-border-radius:2px;
border-radius:2px;
font-size:100%;
width:200px;
}
#addRow {
margin-top:10px;
}
<style type="text/css">
{{>panel-form-css-source}}
</style>
{{>panel-form-html-source}}
<script type="text/javascript">
{{>panel-form-js-source}}
</script>
<h2>Using a panel to show a modal form</h2>
<div class="yui3-u-1">
<div id="dt"></div>
<p><input type="button" id="addRow" value="Add"></p>
<div id="panelContent">
<div class="yui3-widget-bd">
<form>
<fieldset>
<p><label for="id">ID</label><br/>
<input type="text" name="id" id="productId" placeholder=""></p>
<p><label for="name">Name</label><br/>
<input type="text" name="name" id="name" value="" placeholder=""></p>
<p><label for="password">Price</label><br/>
<input type="text" name="price" id="price" value="" placeholder="$"></p>
</fieldset>
</form>
</div>
</div>
<div id="nestedPanel"></div>
</div>
YUI().use("datatable-base", "panel", "dd-plugin", function(Y) {
//Create the datatable with some gadget information
var cols = ["id","name","price"],
data = [
{id:"ga-3475", name:"gadget", price:"$6.99"},
{id:"sp-9980", name:"sprocket", price:"$3.75"},
{id:"wi-0650", name:"widget", price:"$4.25"}
],
dt = new Y.DataTable.Base({
columnset: cols,
recordset: data,
summary: "Price sheet for inventory parts",
caption: "Price sheet for inventory parts"
}),
//Create the main modal form
panel = new Y.Panel({
srcNode: "#panelContent",
width: 250,
centered: true,
visible: false,
modal:true,
zIndex:5,
headerContent: "Add A New Product",
plugins: [Y.Plugin.Drag]
}),
addRowBtn = Y.one("#addRow"),
nestedPanel;
//Render The Datatable
dt.render("#dt");
//Add the footer buttons to the modal form
panel.addButton(
{
value: "Add Item",
action: function(e) {
e.preventDefault();
addItem();
},
section: Y.WidgetStdMod.FOOTER
}
);
panel.addButton(
{
value: "Remove All Items",
action: function(e) {
e.preventDefault();
removeAllItemsConfirm();
},
section: Y.WidgetStdMod.FOOTER
}
);
//Render the modal form
panel.render();
//When the addRowBtn is pressed, show the modal form
addRowBtn.on('click', function(e) {
panel.show();
});
//Define the addItem function - this will be called
//when "Add Item" is pressed on the modal form
var addItem = function() {
var o = {},
id = Y.one('#productId'),
name = Y.one('#name'),
price = Y.one('#price');
o.id = id.get("value");
o.name = name.get("value");
o.price = price.get("value");
id.set("value", "");
name.set("value", "");
price.set("value", "");
data.push(o);
dt.set('recordset', data).render();
dt.render();
panel.hide();
};
//Define the removeItems function - this will be called
//when "Remove All Items" is pressed on the modal form
//and is confirmed "yes" by the nested panel.
var removeItems = function() {
data = [];
dt.set('recordset', data).render();
dt.render();
panel.hide();
};
//Instantiate the nested panel if it doesn't exist, otherwise just show it.
var removeAllItemsConfirm = function() {
if (!nestedPanel) {
nestedPanel = new Y.Panel({
bodyContent: "Are you sure you want to remove all items?",
zIndex: 6,
centered:true,
width:400,
modal:true,
buttons: [
{
value: "Yes",
action : function(e) {
e.preventDefault();
nestedPanel.hide();
panel.hide();
removeItems();
},
section: Y.WidgetStdMod.FOOTER
},
{
value: "No",
action: function(e) {
e.preventDefault();
nestedPanel.hide();
},
section: Y.WidgetStdMod.FOOTER
}
]
}).render('#nestedPanel');
}
else {
nestedPanel.show();
}
}
});
<div class="intro">
<p>This example demonstrates how to set up and instantiate Y.Panel to take advantage of its nested modality and header/footer button support. In this example, we create a simple datatable with some basic information that is updated and removed through a modal form with some custom buttons.</p>
</div>
<div class="example newwindow">
<a href="panel-form-example.html" target="_blank" class="button">
View Example in New Window
</a>
</div>
<h2>Creating a modal form using Panels</h2>
<h3>Setting Up The YUI Instance</h3>
<p>To create an instance of a Panel on your page, the only module you need to request is the `panel` module. The `panel` module will pull in the `widget`, `widget-stack`, `widget-position`, `widget-position-align`, `widget-position-constrain`, `widget-stdmod`, `widget-buttons`, `widget-modality` and `widget-autohide` extensions it uses.</p>
<p>For this example, we also use the YUI3 Datatable, and the Drag plugin to make the panels draggable. This requires us to also request the `datatable-base` and `dd-plugin` modules in our use statement.
```
YUI({...}).use("panel", "datatable-base", "dd-plugin", function(Y) {
// We'll write example code here where we have Y.Datatable, Y.Plugin.Drag and Y.Panel available
});
```
<p>Note, using the `panel` module, will also pull down the default CSS required for panel. The CSS that styles the Panel requires you to have the class `yui3-skin-sam` on a parent element, commonly the `<body>` tag.</p>
<h3>Creating a Panel From Markup</h3>
<p>For this example, we'll need two panel instances. The first will be created through markup, while the second will be created through JavaScript (just to illustrate the differences). The code snippet below is the markup for our modal form. It consists of a fieldset with a couple of `<input>` boxes. The `yui3-widget-bd` class is not required, but tells the Panel that this content goes in the body of the widget.</p>
```
<div id="panelContent">
<div class="yui3-widget-bd">
<form>
<fieldset>
<p><label for="id">ID</label><br/>
<input type="text" name="id" id="productId" placeholder=""></p>
<p><label for="name">Name</label><br/>
<input type="text" name="name" id="name" value="" placeholder=""></p>
<p><label for="password">Price</label><br/>
<input type="text" name="price" id="price" value="" placeholder="$"></p>
</fieldset>
</form>
</div>
```
<p>The container DIV with id="panelContent" is specified as the contentBox for the Panel instance, and during instantiation, the panel will look for DIV's marked with the `yui3-widget-hd, yui3-widget-bd, yui3-widget-ft` classes to setup the Overlay's header, body and footer content attributes.</p>
<h3>Instantiating the Parent Panel</h3>
<p>To create a panel instance, we use the panel constructor `Y.Panel`. We can pass in some additional configuration attributes such as `modal`, `headerContent`, and `centered`. We can make the panel draggable by adding the `Y.Plugin.Drag` plugin.</p>
<p>After creating the panel instance, we invoke `panel.render()` to update the DOM to reflect the current state of the panel.</p>
```
var panel = new Y.Panel({
srcNode: "#panelContent",
width: 250,
centered: true,
visible: false,
modal:true,
headerContent: "Add A New Product",
plugins: [Y.Plugin.Drag]
});
panel.render();
```
<h3>Adding Footer buttons to the Panel</h3>
<p>The parent panel has two buttons in the footer, "Add Item" and "Remove All Items". We add these buttons through the `addButton()` method present on the Y.Panel instance. For each button, we specify an `action` function, which will be called when the button is clicked, and a `section` property that specifies whether it should get rendered in the header or the footer.</p>
```
panel.addButton(
{
value: "Add Item",
action: function(e) {
e.preventDefault();
addItem(); //this method adds a record to the datatable
},
section: Y.WidgetStdMod.FOOTER
}
);
panel.addButton(
{
value: "Remove All Items",
action: function(e) {
e.preventDefault();
removeAllItemsConfirm();
},
section: Y.WidgetStdMod.FOOTER
}
);
```
<h3>Creating the nested Panel through JavaScript</h3>
<p>In the example, clicking the "Remove all items" button renders a nested confirmation panel. Since Y.Panel implements the `Y.WidgetStack` and `Y.WidgetModality` extensions, creating nested panels are easy to do for the developer. The nested panel code is as follows:</p>
```
var nestedPanel = new Y.Panel({
bodyContent: "Are you sure you want to remove all items?",
zIndex: 5, //We set a z-index higher than the parent's z-index
centered:true,
width:400,
modal:true,
//We add the "Yes" and "No" buttons
buttons: [
{
value: "Yes",
action : function(e) {
e.preventDefault();
nestedPanel.hide();
panel.hide();
removeItems(); //this method removes all data from the datatable
},
section: Y.WidgetStdMod.FOOTER
},
{
value: "No",
action: function(e) {
e.preventDefault();
nestedPanel.hide();
},
section: Y.WidgetStdMod.FOOTER
}
]
});
nestedPanel.render('#nestedPanel');
```
<p>In this case, we pass in an array of buttons to the `buttons` attribute. As a result, the nested panel does not have the close button in the top-right corner.</p>
<p>
<h3>CSS: Panel Look/Feel</h3>
<p>The panel.css Sam Skin file (build/panel/assets/skins/sam/panel.css) provides the default functional CSS for the panel. In addition, an image file (build/panel/assets/skins/sam/sprite_icons.gif) provides the icons for the "close" button.</p>
<p><strong>NOTE:</strong> As discussed on the Widget landing page, all widgets are enclosed in 2 containing elements - the boundingBox is the outer(most) element, and the contentBox is the inner element into which the widget's content is added. It is advised to apply any look/feel CSS for the widget to the content box and it's children. This leaves the bounding box without padding/borders, allowing for consistent positioning/sizing across box models.</p>
<h3>Complete Example Source</h3>
```
<style type="text/css">
{{>panel-form-css-source}}
</style>
{{>panel-form-html-source}}
<script type="text/javascript">
{{>panel-form-js-source}}
</script>
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment