This documentation is currently being moved to our new documentation site.

Please view or edit the documentation there, instead.

If you're looking for Fluid Project coordination, design, communication, etc, try the Fluid Project Wiki.

Prototutorial - Creating a new Panel using the UI Options Preference Framework

How to create a panel with the UI Options Framework

This document is an early draft that explains how to use the new APIs and declarative schemas to create your own preferences editor using the UI Options Framework. It documents code that hasn't yet been merged into Infusion's master branch, and may change somewhat over the next couple of weeks.

Here's a quick overview of how to create a new preferences editor, in this case called "Cat Options," using the UI Options Framework. This example editor contains one panel, which allows a user to select their preferred cat size using a slider.

Step 1: Create the HTML and CSS for the panel. This defines how it will look.

<div class="the-cat-panel">
    <div class="cat-size">
        <input type="range" id="size" min="1" max="2" />
        <label for="size" class="catpanel-size-label">How big do you want your cat?</label>
    </div>
</div>

Step 2: Make a primary schema grade. This defines the schema of each of your preferences.

The "schema" object conforms to the JSON Schema Specification

fluid.defaults("catOptions.primarySchema", {
    gradeNames: ["autoInit", "fluid.uiOptions.schema"],
    schema: {
        "catOptions.size": {
            "type": "number",
            "default": 1,
            "minimum": 1,
            "maximum": 10,
            "divisibleBy": 1
        }
    }
});

Example: https://github.com/cindyli/infusion/blob/a222ec41fccf18c134829260805514cf4f091a7c/src/webapp/components/uiOptions/js/PrimaryBuilder.js

Step 3: Make a cat panel grade, which represents the information needed to render the panel.

Primarily this includes a prototree, which defines the instructions required by the Infusion Renderer to render the markup, and a preferences map, which binds the state of the component to your schema.

    fluid.defaults("catOptions.panel", {
        gradeNames: ["fluid.uiOptions.panels", "autoInit"],
        preferenceMap: {
            "catOptions.size": {
                "model.value": "default",
                "range.min": "minimum",
                "range.max": "maximum
            }
        },
        
        range: {
            min: 1,
            max: 2
        },
        
        selectors: {
            catSizeSlider: "#size",
            label: ".catpanel-size-label"
        },
                
        protoTree: {
            "catSizeSlider": {
                    valuebinding: "{value}",
                    decorators: {
                        attrs: {
                            min: "{that}.options.range.min",
                            max: "{that}.options.range.max"
                            }
                    }
            }, 
            label: {
                messagekey: "catpanel.catsize"
            }
        },
        
        classnameMap: null, // must be supplied by implementors
        controlValues: {
            textFont: ["default", "times", "comic", "arial", "verdana"]
        }
    });

Example: https://github.com/cindyli/infusion/blob/a222ec41fccf18c134829260805514cf4f091a7c/src/webapp/components/uiOptions/js/Panels.js

Step 4: Make message bundles for your panel. This provides a place for localized, human-readable string.

catOptions-catPanel_en.json:

{
    "catpanel.catsize": "How big do you want your cat?"
}

catOptions-catPanel_fr.json:

{
    "catpanel.catsize": "Voulez vous un chat tres gros?"
}

Step 5: Make an overall HTML template with containers for each panel.

<html>
   <title>Customize your cat</title>
   <body>
        <h1> Customize Your Cat!</h1>
        <div class="catOptions-catSizePanel"></div>
    </body>
</html>

Step 6: Make an auxilliary schema document. It represents the structure of the component.

    fluid.defaults("catOptions.auxSchema", {
        gradeNames: ["fluid.uiOptions.auxSchema", "autoInit"],
        auxiliarySchema: {
            "namespace": "catOptions",
            "templatePrefix": "../pages/catOptionsPanel/html/",
            "catSize": {
                "type": "catOptions.size"
            },
            
            "enactors": [
                {
                    "type": "catOptions.enactors.catSize"
                }
            ],
            
            "panels": [
                {
                    "type": "catOptions.panel",
                    "container": ".catOptions-catSizePanel",  // the css selector in the template where the panel is rendered
                    "template": "%prefix/CatOptions-catSizePanel.html"
                }
            ]
        }
    });

Example: https://github.com/cindyli/infusion/blob/a222ec41fccf18c134829260805514cf4f091a7c/src/webapp/components/uiOptions/js/AuxiliarySchema.js

Step 7: Make an Enactor. This does the actual work of enacting the user's preference.

Coming soon!