Gadgets API

Creating a User Interface

This document describes how to add different user interface elements to your gadget.

Contents

  1. Views
    1. Including Multiple Content Sections
    2. Concatenating Views
    3. Determining the Current Gadget View
    4. Getting All Available Views
    5. Navigating to Another View
    6. Passing Data through requestNavigateTo()
  2. Managing Gadget Height
  3. Setting a Gadget's Title
  4. Tabs
    1. Anatomy of a Tabs Object
    2. How It Works
    3. Manipulating Tabs By Index
    4. Customizing Tab Display
  5. MiniMessages
    1. How It Works
    2. Creating Messages in Different Locations
    3. Creating Messages Using DOM Methods
    4. Creating a Timer Message
    5. Creating a Static Message
    6. Customizing MiniMessage Display
  6. Flash
    1. Flash Example

Views

A view is a location where a gadget is displayed. Different views have different characteristics. For example, an OpenSocial container might have a view that shows gadgets in a small format, and a view that shows gadgets in full page format. For a list of the views supported by your site, application, or container, see the documentation for that site, application, or container.

As an example, a gadget might display in home view mode ("small mode"), meaning that it appears in a column layout among other gadgets. To create a canvas ("big mode") view of your gadget, where the gadget expands horizontally to span the entire gadget area, you must define a <Content> section for the "canvas" view type, as follows:

<Content type="html" view="canvas"> 

Suppose you define a <Content> section for the canvas view of a gadget. Then you must also create a <Content> section to make the gadget display properly in the home view. This can either be "default" or "home". For more discussion of writing gadgets that support multiple <Content> sections, see Including Multiple Content Sections.

Here is a version of a Hello World gadget that defines <Content> section views for "home" and "canvas". Its width changes according to whether you display it in the home view or the canvas view.

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Hello World!">
    <Require feature="opensocial-0.8" />
  </ModulePrefs>
  <Content type="html" view="home">
    <![CDATA[
      Hello, small world!
    ]]>
  </Content>
  <Content type="html" view="canvas">
    <![CDATA[
      Hello, big world!
    ]]>
  </Content>
</Module>

Including Multiple Content Sections

You can include more than one <Content> section in a gadget XML file, where each <Content> section declares the views it should be rendered on. All <Content> sections should be siblings in the document tree, and may use the optional parameter view= to define the views in which they should render.

Two content sections

Here is a simple example that shows a gadget with two content sections, one for "profile" and one for "canvas":

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Multiple Content Sections (version 1)">
    <Require feature="opensocial-0.8" />
  </ModulePrefs>
  <Content type="html" view="profile">
  <![CDATA[
    <h1>Profile</h1>
  ]]>
  </Content>
  <Content type="html" view="canvas">
  <![CDATA[
    <h1>Canvas</h1>
  ]]>
  </Content>
</Module>

The output is as follows:

Profile view

<h1>Profile</h1>

Canvas view

<h1>Canvas</h1>

Any other views that are not canvas or profile

no content is displayed

Content sections with multiple views specified

Content sections can specify multiple views, separated by commas:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Multiple Content Sections (version 2)">
    <Require feature="opensocial-0.8" />
  </ModulePrefs>
  <Content type="html" view="canvas,profile">
  <![CDATA[
    <h1>Canvas and Profile</h1>
  ]]>
  </Content>
</Module>

The output is as follows:

Profile view

<h1>Canvas and Profile</h1>

Canvas view

<h1>Canvas and Profile</h1>

Any other views that are not canvas or profile

no content is displayed

Content section with view specified and no default content section

If you specify a content section with a view parameter, that content section is only shown on that view. If you don't specify a default content section, other views will not display any content.

<?xml version="1.0" encoding="UTF-8" ?>
<Module>  
  <ModulePrefs title="Multiple Content Sections (version 3)">
    <Require feature="opensocial-0.8" />
  </ModulePrefs>
  <Content type="html" view="profile">
  <![CDATA[
    <h1>Profile</h1>
  ]]>        
  </Content>
</Module>

The output is as follows:

Profile view

<h1>Profile</h1>

Canvas view

no content is displayed

Any other views that are not canvas or profile

no content is displayed

Content section with view specified and a default content section

To specify a default content section, simply define a content section with no view parameter:

<Module>  
  <ModulePrefs title="Multiple Content Sections (version 4)">
    <Require feature="opensocial-0.8" />
  </ModulePrefs>
  <Content type="html" view="profile">
  <![CDATA[
    <h1>Profile</h1>
  ]]>        
  </Content>
  <Content type="html">
  <![CDATA[
    <h1>Default</h1>
  ]]>
  </Content>
</Module>

The output is as follows:

Profile view

<h1>Profile</h1>

Canvas view

<h1>Default</h1>

Any other views that are not canvas or profile

<h1>Default</h1>

Concatenating Views

Views are supported across OpenSocial containers, but each container may support a different set of views.

Suppose you want to write a gadget that had the same display for home and profile. Instead of creating duplicate <Content> sections, you could concatenate the views for a single <Content> section, as follows:

<Content type="html" view="home,profile">

You can use this technique either across containers or within the same container. For example, gadgets that handle presentation logic for differently sized views in a single <Content> section can extend that support to the canvas page by declaring view="home,canvas".

Determining the Current Gadget View

The easiest way to get the current view is to include the "views" feature in your gadget module preferences:

<ModulePrefs title="Views example">
  <Require feature="views" />
</ModulePrefs>

When the views feature is included, you can obtain the current view by calling the gadget.util.getCurrentView() function.

The following example demonstrates getting the current view and conditionally executing code against the returned value:

function getViewName() {
  return gadgets.views.getCurrentView().getName();
}

if (getViewName() == "canvas") {
  /* Do canvas specific stuff here */
}

if (getViewName() == "home") {
  /* Do home specific stuff here */
}

Getting All Available Views

Obtain the available View objects by calling the gadgets.views.getSupportedViews() function.

var supported_views = gadgets.views.getSupportedViews();

The object returned by the getSupportedViews call contains gadgets.views.View objects representing all of the available views, indexed by view name.

If you wish to provide links to other views, you need to pass a gadgets.views.View object to the gadgets.views.requestNavigateTo() method. You can choose to use one of the objects returned by the getSupportedViews() call. The following code sample demonstrates this method:

function navigateTo(dest) {
  var supported_views = gadgets.views.getSupportedViews();
  gadgets.views.requestNavigateTo(supported_views[dest]);
};

/**
 * When called, this method asks the container to switch to the canvas
 */
function gotoCanvas() {
  navigateTo("canvas");
};

/**
 * When called, this method asks the container to switch to the home
 */
function gotoHome() {
  navigateTo("home");
};

An alternative is to create a new View object manually, and then use that to initiate navigation. The following code sample shows creating a new gadgets.views.View object and passing it to the gadgets.views.requestNavigateTo() method:

/**
 * When called, this method asks the container to switch to the canvas
 */
function gotoCanvas() {
  var canvas_view = new gadgets.views.View("canvas");
  gadgets.views.requestNavigateTo(canvas_view);
};

/**
 * When called, this method asks the container to switch to the home
 */
function gotoHome() {
  var home_view = new gadgets.views.View("home");
  gadgets.views.requestNavigateTo(home_view);
};

Here is a complete example based on the "Hello World" gadget:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs height="100" title="Navigation">
    <Require feature="views" />
  </ModulePrefs>
  <Content type="html" view="home">
  <![CDATA[
  <div>Hello world Home view</div>
  <script type="text/javascript">

    function goToView(dest) {
      var supported_views = gadgets.views.getSupportedViews();
      gadgets.views.requestNavigateTo(supported_views[dest]);
    };
  </script>

  <a href="javascript:goToView('canvas')" >Go to canvas view</a><br><br>

  ]]>
  </Content>
  <Content type="html" view="canvas">
  <![CDATA[
  <div>Hello world Canvas view</div>
  <script type="text/javascript">

    function goToView(dest) {
      var supported_views = gadgets.views.getSupportedViews();
      gadgets.views.requestNavigateTo(supported_views[dest]);
    };
  </script>
  <a href="javascript:goToView('home')" >Go to home view</a><br><br>
  ]]>
  </Content>
  </Module>

Passing Data through requestNavigateTo()

If you are using the gadgets.views.requestNavigateTo() calls, you may supply an optional parameter containing data to be passed to the new page.

The following code passes two variables: foo and bar to the canvas surface of the current gadget:

function gotoCanvas(params) {
  var canvas_view = new gadgets.views.View("canvas");
  gadgets.views.requestNavigateTo(canvas_view, params);
};

var my_params = {
  foo : 12345,
  bar : "Bar value"
};

gotoCanvas(my_params);

In the canvas view, check for these values with the following code:

var prefs = gadgets.views.getParams();
var foo = prefs["foo"];
/* foo contains 12345 */

var bar = prefs["bar"];
/* bar contains "Bar value" */<sup class="changed">New!</sup>

Managing Gadget Height

By default, gadgets are 200 pixels high. You can use the <ModulePrefs> attribute height="nn" to specify a static height that is bigger or smaller than the default. You can use the <ModulePrefs> attribute scrolling="true" to cause your gadget to have a vertical scroll bar if the content height causes your gadget to exceed its designated height.

But some gadgets need to be able to dynamically change their height. For example, suppose you have a list gadget whose height needs to expand and contract depending on the contents of the list. As users add items to the list, the gadget grows. When they clear the list, the gadget returns to its original height. Here is what the running gadget might look like:

Grocery List Gadget

To give your gadget the ability to resize itself, you need to add the following things to your gadget spec:

  • A <Require feature="dynamic-height"/> tag (under <ModulePrefs>) to tell the gadget to load the dynamic-height library.
  • A call to the JavaScript function gadgets.window.adjustHeight() whenever there is a change in content, or another event occurs that requires the gadget to resize itself.

For example, here is the gadget spec for the grocery list gadget:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Dynamic Height"
    height="100">
    <Require feature="dynamic-height"/>
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
    <script type="text/javascript">
    // This example lets users add items to a grocery list and then clear the list.
    // When items are added or cleared, the gadget resizes itself.
    var mylist = "";
    var flag = 0;

    // Function that is invoked whenever user clicks the Add button to add an
    // item to the list.
    function addToList (form) {
        var input = _trim(form.inputbox.value);
        if (input == "") {
            return;
        }

        // Make alternating lines green/white, depending on value of flag variable.
        if(flag == 0){
            mylist += "<div style='padding-left: 5px;background-color: #E6FFE6; font-family:Arial, Helvetica;'>" +input + "</div>";
            flag = 1;
        }
        else {
            mylist += "<div style='padding-left: 5px;font-family:Arial, Helvetica;'>" +input + "</div>";
            flag = 0;
        }

        // Call setContent to output HTML to div and resize gadget
        setContent(mylist);
    }

    // Clear the list
    function clearList(form) {
        // Call setContent to remove all items from the list and resize the gadget
        setContent("");
    }

    // Outputs content to the div and resizes the gadget
    function setContent(html) {
        document.getElementById('content_div').innerHTML = html;

       // Tells gadget to resize itself
       gadgets.window.adjustHeight();
    }
    </script>
  <FORM NAME="myform" ACTION="" METHOD="GET"><BR>
  <INPUT TYPE="text" NAME="inputbox" VALUE="">
  <INPUT TYPE="button" NAME="button" Value="Add" onClick="addToList(this.form)">
  <INPUT TYPE="button" NAME="button2" Value="Clear" onClick="clearList(this.form)">
  </FORM>
  <div id="content_div"></div>
  ]]>
  </Content>
</Module>

For guidelines on testing a gadget's width and height, see Testing Width and Height.

Setting a Gadget's Title

You can use the gadgets.window.setTitle() function to programmatically set your gadget's title. To use this function, your gadget spec must include the following:

  • Under <ModulePrefs>, a <Require feature="settitle"/> tag to tell the gadget to load the settitle library.
  • A call togadgets.window.setTitle() to set the gadget's title.

This example provides a text field that lets the user set the gadget's title:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Set Title Example">
    <Require feature="settitle"/>
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
    <script type="text/javascript">
    function changeTitle(form) {
      var newTitle = form.inputbox.value;
      gadgets.window.setTitle(newTitle);
    }
    </script>
<FORM NAME="myform" ACTION="" METHOD="GET">Change the Gadget Title: <BR><BR>
<INPUT TYPE="text" NAME="inputbox" VALUE=""><BR><BR>
<INPUT TYPE="button" NAME="button" Value="Change Title" onClick="changeTitle(this.form)">
</FORM>
<div id="content_div"></div>
  ]]>
  </Content>
</Module>

Tabs

You can use the tabs library to add a tabbed user interface to your gadget. To use tabs, your gadget spec must minimally include the following:

  • Under <ModulePrefs>, a <Require feature="tabs"/> tag to tell the gadget to load the tabs library.
  • JavaScript for constructing your tabs and populating them with content. See How It Works for details.

It is also common to include the setprefs library so that the gadget can persistently store the user's last selected tab. Then if the user leaves the page and comes back, your gadget loads the remembered tab. To take advantage of this feature, embed two lines of code in your gadget spec:

<Require feature="setprefs"/>
...
<UserPref name="selectedTab" datatype="hidden"/>

Anatomy of a Tabs Object

The tabs library provides functions and CSS to operate on the following objects:

  • TabSet object. The tabs object is the parent container around all of the tabs. Programmatically, the tabs object is an array of individual tab objects. The underlying HTML implementation is typically a <table> element, referred to in the API as the "header container." You access this HTML through the gadgets.TabSet.getHeaderContainer() function.
  • Tab object. A tab object is a single tab within an array of indexed tabs. The underlying HTML implementation is typically a <td> element, referred to in the API as a "name container." You access this HTML through the gadgets.Tab.getNameContainer() function.
  • Content container. A content container holds the content for an individual tab object. The underlying HTML implementation is typically a <div> element, referred to in the API as a "content container." You access this HTML through the gadgets.Tab.getContentContainer() function.

How It Works

You create a tabs object (that is, an object that contains a set of indexed tabs) using the gadgets.TabSet() constructor. For example:

// Initialize tabs, designate the tab named "Two" as
// the tab selected by default.
var tabs = new gadgets.TabSet(__MODULE_ID__, "Two"); 

Once you have a tabs object, you can add individual tabs to it using the addTab() function. An individual tab has three major components: an index, a name, and a unique ID that matches the ID of a corresponding <div>. The <div> is where the tab's content gets placed. If you don't provide the <div> container yourself, the tabs library generates one for you.

The addTab() method takes the following arguments:

  • String tabName -- Label of the tab to create.
  • Object opt_params -- Optional parameter object. It can include the following:
    • contentContainer --An existing HTML element to be used as the tab content container. If omitted, the tabs library creates one.
    • callback --A callback function to be executed when the tab is selected.
    • tooltip-- A tooltip description that pops up when user moves the mouse cursor over the tab.
    • index -- The index at which to insert the tab. If omitted, the new tab is appended to the end.

addTab() returns a string containing DOM id of the tab container.

You can add a tab to a tabs object and populate it with content in any of the following ways:

Technique #1: Capture the tab's ID when you create it, and use the ID to add content to the tab's corresponding <div>:

var one_Id = tabs.addTab("One");
document.getElementById(one_Id).innerHTML = "Content for tab One.";

A variation on this approach is to define the tab name in HTML. For example:

var one_Id = tabs.addTab('<div style="color: red; font-weight: bold; background-color:#ccf;">Cool Tab</div>');
document.getElementById(one_Id).innerHTML = "Content for tab One.";

Technique #2: Create the tab and add a corresponding <div> to the HTML portion of the gadget; place static content in the <div>:

tabs.addTab("Two", "two_id");
...
</script>
<div id="two_id" style="display:none">Content for tab Two.</div>

Technique #3: Create the tab and add a corresponding <div> to the HTML portion of the gadget; place static content in the <div>. Use a callback function to add dynamic content to the static content:

tabs.addTab("Three", "three_id", callback);
...
function callback(tabId) {
var p = document.createElement("p");
p.innerHTML = "This is dynamic content generated in callback.";
document.getElementById(tabId).appendChild(p);
} ...
</script>
<div id="three_id" style="display:none">This is static content for tab Three.</div>

Technique #4: Use the addTab(tabName, opt_params) function to add a tab by name. For example:

tabs.addTab("Tab", {
     contentContainer: document.getElementById("domId"),
     callback: func,
     tooltip: "Popup description"

}); 

Here is a sample gadget that shows the different ways of adding tabs and filling them with content:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Tabs Demo" height="140" scrolling="true" >
    <Require feature="tabs" />
  </ModulePrefs>
  <Content type="html">
  <![CDATA[

    <script type="text/javascript">
    // Initialize tabs, designate the tab named "Two" as
    // the tab selected by default.
    var tabs = new gadgets.TabSet(__MODULE_ID__, "Two");
    function init() {
        // Technique #1: Capture the tab's ID when you create it, and use the ID
        // to add content to the tab's corresponding <div>.
        var one_Id = tabs.addTab('<div style="color: red; font-weight: bold; background-color:#ccf;">Cool Tab</div>');
        document.getElementById(one_Id).innerHTML = "Content for tab One.";

        // Technique #2: Create the tab and define a corresponding <div> in the
        // HTML portion of the gadget. Add static content to the <div>.

        tabs.addTab("Two", {
           contentContainer: document.getElementById("two_id")
        });

        // Technique #3: Create the tab and define a corresponding <div> in the
        // HTML portion of the gadget. Add static content to the <div>.
        // Use a callback function to add dynamic content to the static content.

        tabs.addTab("Three", {
           contentContainer: document.getElementById("three_id"),
           callback: callback
        });

        // Technique #4: Create the tab with a tooltip message. If specified <div>
        // doesn't exist, tabs library creates one.
        // Invoke callback function.
        tabs.addTab("Four", {
           contentContainer: document.getElementById("four_id"),
           callback: callback,
           tooltip: "I'm special"
        });
    }

    // Callback that provides content to tabs Three and Four
    function callback(tabId) {
      var p = document.createElement("p");
      // Get selected tab
      var selectedTab = tabs.getSelectedTab();
      p.innerHTML = "This is dynamic content generated in callback for tab " + selectedTab.getName();
      document.getElementById(tabId).appendChild(p);
    }

    // Call init function to initialize and display tabs.
    gadgets.util.registerOnLoadHandler(init);
    </script>

   <div id="two_id" style="display:none">Content for tab Two.</div>
   <div id="three_id" style="display:none">This is static content for tab Three.</div>
  ]]>
  </Content>
</Module>

Manipulating Tabs By Index

The tabs API also includes functions that let you manipulate tabs by index. Tabs are indexed 0 through n, with 0 being the first tab. For example, if you have 3 tabs, their indices are 0, 1, and 2. You can use the indices to select a tab programmatically, and to switch the position of two tabs.

Note that while a tab's ID stays constant, its index does not. If you move the third tab into the first position, for example, its index changes from 2 to 0.

Here is an example of selecting a tab programmatically. This snippet creates a link. When the user clicks on the link, the second tab is selected, as if the user clicked on the tab itself:

<script>
...
function selectTab() {
tabs.setSelectedTab(1);
}
</script> <a href="javascript:void(0)" onclick="selectTab()">Select Second Tab</a>

Here is an example of moving a tab programmatically. This snippet creates a link. When the user clicks on the link, the gadget switches the positions of the first and second tabs:

<script>
...
function switchTabs() {
tabs.swapTabs(0, 1);
} </script> <a href="javascript:void(0)" onclick="switchTabs()">Switch Tabs</a>

Customizing Tab Display

This section describes how you can customize the appearance of your tabs with CSS or JavaScript.

Customizing Tabs with CSS

The tabs CSS defines the classes that are applied to the HTML elements that lay out the tabs.

You can use the following CSS classes to override the default settings and modify the look and feel of your tabs.

CSS Class Description
.tablib_table Applies to the HTML table containing the tabs.
.tablib_selected Applies to the selected tab.
.tablib_unselected Applies to all unselected tabs.
.tablib_spacerTab Applies to the spacer elements between each tab.
.tablib_emptyTab Controls the beginning and end spacers around the tabs.
.tablib_navContainer Applies to parent container, which contains all tab-related content (that is, tab headers and all individual content containers).

Here are the default CSS classes and settings you can override:

.tablib_table {
width: 100%;
border-collapse: separate;
border-spacing: 0px;
empty-cells: show;
font-size: 11px;
text-align: center;
}
.tablib_emptyTab {
border-bottom: 1px solid #676767;
padding: 0px 1px;
}
.tablib_spacerTab {
border-bottom: 1px solid #676767;
padding: 0px 1px;
width: 1px;
}
.tablib_selected {
padding: 2px 0px;
background-color: #ffffff;
border: 1px solid #676767;
border-bottom-width: 0px;
color: #3366cc;
font-weight: bold;
width: 80px;
cursor: default;
}
.tablib_unselected {
padding: 2px 0px;
background-color: #dddddd;
border: 1px solid #aaaaaa;
border-bottom-color: #676767;
color: #000000;
width: 80px;
cursor: pointer;
}
.tablib_navContainer {
width: 10px;
vertical-align: middle;
}
.tablib_navContainer a:link, .tablib_navContainer a:visited, .tablib_navContainer a:hover {
color: #3366aa;
text-decoration: none;
}

For example:

<![CDATA[
  <style type="text/css">
   .tablib_selected { color: #FF0000; }
   .tablib_unselected { color: #660099; }
   .tablib_table { font-size:20px; }
   .tablib_emptyTab { padding:2px 5px; }
   .tablib_spacerTab { padding:0px 5px; }
</style>
<script...>

You can also use JavaScript to apply CSS styles to the tabs header container. The function getHeaderContainer()returns the tabs HTML table, which you can then modify as desired.

For example, this snippet changes the font size and adds some margin at the top:

var tabs = new gadgets.TabSet();
...

var table = tabs.getHeaderContainer();
table.style.fontSize = "10px";
table.style.marginTop = "15px";

You can customize the style for individual tab headers by getting the individual tab elements and modifying their properties. Here's an example that makes the first tab's style unique:

var tabs = new gadgets.TabSet();
tabs.addTab("Unique");
...
var firstTab = tabs.getTabs()[0].getNameContainer();
firstTab.style.backgroundColor = "#999999";
firstTab.style.color = "#ffffff";

Changing Tab Alignment

By default, tabs are centered as they're added. But if you have less than 3 or 4 tabs, you may want to align them to the left or right. You can do this using the alignTabs() function. It takes one parameter with the value left, right, or center. If you're aligning tabs to the left or right, there's an additional optional parameter that you can pass in to indicate the offset width from the left or right side.The default size is 3px.

For example:

var tabs = new gadgets.TabSet();
...
// Align tabs to the left and offset it by 10 pixels
tabs.alignTabs("left", 10);

Hiding Tabs

You can use the displayTabs() function to toggle the display of tabs and their contents. This function takes a boolean value of either true or false.

Here's an example that creates a button that shows or hides the tabs:

<input onclick="toggleTabs()" type="button" value="Show/Hide"/>
<script>
var tabs = new gadgets.TabSet();
...
var showTabs = true;
function toggleTabs() {
showTabs = !showTabs;
tabs.displayTabs(showTabs);
}
</script>

MiniMessages

A MiniMessage is a temporary message displayed to users from within a gadget. MiniMessages are designed to be dismissed, either programmatically or by the user. The basic types of MiniMessages are as follows:

  • Dismissable messages that users can remove by clicking an [x].
  • Timer messages that disappear after a specified number of seconds have elapsed.
  • Static messages that must be programmatically dismissed.

To use MiniMessages, your gadget spec must include the following:

  • Under <ModulePrefs>, a <Require feature="minimessage"/> tag to tell the gadget to load the MiniMessage library.
  • JavaScript functions that describe your MiniMessage behavior. See the reference for a complete list of the functions in the MiniMessage library.

Some of the reasons you might want to use MiniMessages are as follows:

  • Promotion: You can use MiniMessages to display a promotional message in your gadget.
  • Status: Many gadgets fetch and load data behind the scenes. You can use MiniMessages to display "Loading..." or other status-related messages.
  • Debug/Error: If a gadget encounters an error, it can use MiniMessages to notify the user instead of silently failing.
  • Other: Depending on the type of gadget (for example, calendar, eBay), you may want to display notifications to users. Because MiniMessages are small and dismissible, you can use them to communicate special information.

How it Works

The basic steps for adding a MiniMessage to your gadget are simple:

1. Import the minimessage library:

<Require feature="minimessage"/>

2. Instantiate a new MiniMessage object using the gadgets.MiniMessage() constructor:

var msg = new gadgets.MiniMessage(__MODULE_ID__);

In most cases, you'll want to make this a single global object that can be accessed from all scopes.

3. Create a new MiniMessage with some text:

msg.createDismissibleMessage("Please close me when you're done reading me.");

This adds a dismissable preformatted message with an associated [x] to the top of your gadget. When users click the [x], the message closes.

You're done! You've created one of the many types of dismissible messages.

Creating Messages in Different Locations

By default, messages are placed inside a container HTML element at the very top of the gadget. Each successive message is appended as a child to the container, in top-down order. But you can modify this behavior for either all messages or just a single message.

Setting a Location for All Messages

You can override the default location of the message container element by passing an HTML element, preferably a <div>, to the constructor. This element becomes the message container where messages are inserted and displayed.

For example, in this snippet the <h3> message "I'm on top now!" appears at the top of the gadget. The MiniMessages are displayed beneath it in the messageBox <div> in the order in which the messages were added.

<div>
<h3>I'm on top now!</h3>
</div>
<div id="messageBox"></div>
<script type="text/javascript"> // In the constructor, state that messages should be be displayed // in the messageBox <div> rather than at the top of the gadget. var msg = new gadgets.MiniMessage(__MODULE_ID__, document.getElementById("messageBox")); msg.createDismissibleMessage("I'm the first message."); msg.createDismissibleMessage("I'm the second message."); msg.createDismissibleMessage("I'm at the bottom."); </script>

Setting a Location for a Single Message

You can create a dismissible message in a designated location instead of appending it in the message container. You do this by marking up the message within the HTML portion of the gadget, and then passing the HTML element (preferably a <div>) as the first parameter to createDismissibleMessage().

For example, in this snippet the message is displayed within the status <div>:

<div id="status" style="color:#B30000;">
<b>Check out our new API documentation!</b> -- <a href="http://www.google.com/apis/gadgets" target="_blank">Read</a>
</div>
<script type="text/javascript"> var msg = new gadgets.MiniMessage(__MODULE_ID__); // Pass the HTML element to createDismissableMessage() to indicate // where the message should be displayed. msg.createDismissibleMessage(document.getElementById("status")); </script>

Creating Messages Using DOM Methods

There may be cases where you'll want to generate the dismissible message using HTML DOM methods. Since the message doesn't exist in the DOM, it is appended by default in the message container.

For example:

<script type="text/javascript">
  var msg = new gadgets.MiniMessage(__MODULE_ID__);
  // Generate the message using DOM methods
  var div = document.createElement("div");
  div.innerHTML = "New message created by W3C DOM methods.";
  // Set some DOM properties
  div.onmouseover = function() {
    div.style.backgroundColor = "green";
  };
  div.onmouseout = function() {
    div.style.backgroundColor = "";
  };
  msg.createDismissibleMessage(div);

</script>

Creating a Timer Message

A timer message is a preformatted message that disappears after the specified amount of time has elapsed. The function createTimerMessage() takes two parameters: a message string, and a number indicating for how many seconds the message should be displayed. For example:

var msg = new gadgets.MiniMessage(__MODULE_ID__);
msg.createTimerMessage("I'm going to disappear in 5 seconds.", 5);

Creating a Static Message

A static message is a preformatted message that displays until the message is programmatically dismissed by the dismissMessage() function. This is useful for displaying notification messages to keep the user informed while the gadget is executing background tasks, such as fetching content. For example:

  var msg = new gadgets.MiniMessage(__MODULE_ID__);
  var loadMessage = msg.createStaticMessage(document.getElementById("loading"));

Customizing MiniMessage Display

There are two different ways to change the default appearance of MiniMessages:

  • Change the appearance of individual messages.
  • Globally change the appearance of all messages.

Changing the Style of Individual Messages

You use DOM functions to change a message's style. When you create a new dismissible message, an HTML element is returned. You can modify the appearance of a message by setting the style properties of the returned HTML element. For example:

<script type="text/javascript">
  var msg = new gadgets.MiniMessage(__MODULE_ID__);
  var statusMsg = msg.createDismissibleMessage("This is a critical error!");
  // Change the message's background color to red
  statusMsg.style.backgroundColor = "red";
  statusMsg.style.color = "white";
</script>

Note: Notice that this example shows the correct way to change the entire background color of a message. Setting the background color of the <div> that contains the message doesn't change the entire background color.

Changing the Style of All Messages

You use CSS to globally change the style for all messages. The CSS defines the classes that are applied to the HTML elements that define MiniMessages.

You can use the following CSS classes to override the default settings and modify the look and feel of your messages.

CSS Class Description
.mmlib_table Applies to the HTML table containing the message.
.mmlib_xlink Applies to the [x] link used to dismiss a message. The setting applies to dismissible message only.

For example, this changes the background to navy blue and the foreground to white:

<![CDATA[
   <style>
     .mmlib_table__MODULE_ID__ {
       background-color: #000066;
       color: #ffffff;
     }
   </style>
<script...>

Here are the default CSS classes and settings you can override:

.mmlib_table {
  width: 100%;
  font: bold 9px arial,sans-serif;
  background-color: #fff4c2;
  border-collapse: separate;
  border-spacing: 0px;
  padding: 1px 0px;
  }
.mmlib_xlink {
  font: normal 1.1em arial,sans-serif;
  font-weight: bold;
  color: #0000cc;
  cursor: pointer;
  }

Flash

You can use the flash library to embed a Flash movie (specifically, a .swf file) in your gadget. To embed Flash content, your gadget spec must minimally include the following:

  • Under <ModulePrefs>, a <Require feature="flash"/> tag to tell the gadget to load the flash library.
  • A call to gadgets.flash.embedFlash() to embed a .swf file in your gadget and display it in a designated location. Note that to use this feature, all resources must be bundled in a .swf file.

The flash library includes the following functions:

Function Description
gadgets.flash.embedFlash(swf_url, swf_container, swfVersion, opt_params)

Embeds the .swf file specified by swf_url, and displays it in the gadget at the location specified by swf_container. The parameter opt_params is an object that An optional object that may contain any valid html parameter.

Returns true if successful, or false if not.

Note: If you experience performance problems or if the caret does not display (sometimes an issue in Firefox 2.0), try explicitly setting wmode to "window" as follows: gadgets.flash.embedFlash("example.swf", "wrapper", {wmode: "window"});

gadgets.flash.embedCachedFlash(swf_url, swf_container, swfVersion, opt_params) Injects a cached Flash file into the DOM tree. Parameters and return value are the same as embedFlash() method.
gadgets.flash.getMajorVersion() Returns the Flash Player's major version or zero if Flash Player is not detected.

Flash Example

When you click a button in this sample gadget, it plays the corresponding .swf file. When you click Stop, the gadget displays a still photograph.

Here is the gadget spec for the example:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Trevor Does Tricks" height="300">
  <Require feature="flash" />
</ModulePrefs>
<Content type="html">
<![CDATA[

<style type="text/css">
  input.mybutton
  {
     background-color:#FFCC99;
     border-style:solid;
     border-color:#000000;
     font-family:Comic Sans MS,sans-serif;
     font-size:14px;
  }
</style>

<div id="flashcontainer" style="text-align: center;"></div>

<script type="text/javascript">

  // Display still photo.
  function showPhoto() {
    document.getElementById("flashcontainer").innerHTML = "<img src='http://doc.examples.googlepages.com/Trevor.JPG' />";
  }

  // Play .swf file for specified trick.
  function doTrick(trick) {

    // The URL for the .swf file that shows the specified trick.
    var url = "http://doc.examples.googlepages.com/Trevor-"+trick+".swf";

    // Play .swf file.
      gadgets.flash.embedFlash(url, "flashcontainer", {
      swf_version: 6,
      id: "flashid",
      width: 300,
      height: 250
    })
  }

  // When gadget first loads, display still photo.
  gadgets.util.registerOnLoadHandler(showPhoto);
  </script>
  <br />
  <div style="text-align: center;">
    <input type=submit class="mybutton" value="Spin" onClick="doTrick('spin')">
    <input type=submit class="mybutton" value="Speak" onClick="doTrick('speak')">
    <input type=submit class="mybutton" value="Sit" onClick="doTrick('sit')">
    <input type=submit class="mybutton" value="Down" onClick="doTrick('down')">
    <input type=submit class="mybutton" value="Stop" onClick="showPhoto()">
  </div>
  ]]>
</Content>
</Module>

Back to top

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and code samples are licensed under the Apache 2.0 License.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.