panel-form.mustache revision 163214f6685497247d57aa5ea96fb233b3785fcf
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<div class="intro">
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <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>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley</div>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<div class="example newwindow">
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <a href="panel-form-example.html" target="_blank" class="button">
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley View Example in New Window
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley </a>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley</div>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<h2>Creating a modal form using Panels</h2>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<h3>Setting Up The YUI Instance</h3>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<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>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<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.
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley```
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob HalleyYUI({...}).use("panel", "datatable-base", "dd-plugin", function(Y) {
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley // We'll write example code here where we have Y.Datatable, Y.Plugin.Drag and Y.Panel available
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley});
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley```
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<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>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<h3>Creating a Panel From Markup</h3>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<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>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley```
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<div id="panelContent">
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <div class="yui3-widget-bd">
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <form>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <fieldset>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <p><label for="id">ID</label><br/>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <input type="text" name="id" id="productId" placeholder=""></p>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <p><label for="name">Name</label><br/>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <input type="text" name="name" id="name" value="" placeholder=""></p>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <p><label for="password">Price</label><br/>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley <input type="text" name="price" id="price" value="" placeholder="$"></p>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley </fieldset>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley </form>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley </div>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley```
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<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>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<h3>Instantiating the Parent Panel</h3>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<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>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<p>After creating the panel instance, we invoke `panel.render()` to update the DOM to reflect the current state of the panel.</p>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley```
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halleyvar panel = new Y.Panel({
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley srcNode: "#panelContent",
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley width: 250,
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley centered: true,
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley visible: false,
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley modal:true,
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley headerContent: "Add A New Product",
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley plugins: [Y.Plugin.Drag]
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley});
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halleypanel.render();
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley```
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<h3>Adding Footer buttons to the Panel</h3>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<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>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley```
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halleypanel.addButton(
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley {
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley value: "Add Item",
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley action: function(e) {
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley e.preventDefault();
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley addItem(); //this method adds a record to the datatable
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley },
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley section: Y.WidgetStdMod.FOOTER
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley }
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley);
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halleypanel.addButton(
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley {
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley value: "Remove All Items",
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley action: function(e) {
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley e.preventDefault();
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley removeAllItemsConfirm();
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley },
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley section: Y.WidgetStdMod.FOOTER
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley }
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley);
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley```
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<h3>Creating the nested Panel through JavaScript</h3>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley<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>
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley```
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halleyvar nestedPanel = new Y.Panel({
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley bodyContent: "Are you sure you want to remove all items?",
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley zIndex: 5, //We set a z-index higher than the parent's z-index
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley centered:true,
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley width:400,
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley modal:true,
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley //We add the "Yes" and "No" buttons
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley buttons: [
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley {
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley value: "Yes",
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley action : function(e) {
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley e.preventDefault();
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley nestedPanel.hide();
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley panel.hide();
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley removeItems(); //this method removes all data from the datatable
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley },
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley section: Y.WidgetStdMod.FOOTER
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley },
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley {
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley value: "No",
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley action: function(e) {
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley e.preventDefault();
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley nestedPanel.hide();
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley },
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley section: Y.WidgetStdMod.FOOTER
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley }
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley ]
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley});
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>
```