OptionSelectorInfotron

This will also quickly become a favourite, is my guess. Easy to grok and instantly usable. It wraps a select tag and lets you populate it by options dynamically when sending an array as a message to input terminal collection_in.

Sample Declaration

<div id="optionselector"
     impl="~0128ae4a68864a11dbb93d3cba05831679"
     properties="'sends_value_only': 'false'"
     script="http://localhost/OptionSelector.js">
</div>

Input Terminals

Output Terminals

Properties

Demos that use it

How does it work?

Actually it would be quite simple to modify it so that it created its own select element as well, but it's a good illustration of a medium-sized blueprint which manages wrapped elements.

When a selection is made, it is posted on the selected_option_out output terminal, and the query input/output terminal set is (obviously) for out of band queries for the state of the select element.

If the property sends_value_only is set to true, then only a list of selected values is sent, otherwise a dictionary (associative array) of name/value apirs (eform) is sent.



BLUEPRINT(
"~0128ae4a68864a11dbb93d3cba05831679",
[
 ["collection_in", "onCollection", 10],
 ["selected_option_query_in", "onSelectedQuery", 10]
],
[
 "selected_option_out",
 "selected_option_query_result_out"
],
function(Class)
{
    Class.prototype._onInit = function(props)
    {
        var self = this;
        var o = this.dom_node.getElementsByTagName("SELECT")[0];
        
        this.sends_value_only = props["sends_value_only"];

        o.onchange = function(e)
        {
            var t, item;

            e = e || __w.event;
            t = e.target || e.srcElement;

            item = self.onSelect(t);
            self.postMessage("selected_option_out", item);
        };
    };

    Class.prototype.onSelect = function(t)
    {
        var item;

        var o = t.options[t.selectedIndex];

        if (this.sends_value_only) {
            item = o.value;
        } else {
            item = o.eform;
        }

        return item;
    };

    Class.prototype.onSelectedQuery = function(msg)
    {
        var item = this.onSelect(this.dom_node.getElementsByTagName("SELECT")[0]);
        this.postMessage("selected_option_query_result_out", item);
    };

    Class.prototype.onCollection = function(msg)
    {
        var i, n, o, sel;

        if (!msg.sort) {
            coll = msg["members"];
        } else {
            coll = msg;
        }

        select = this.dom_node.getElementsByTagName("SELECT")[0];
	select.selectedIndex = -1;

        n = coll.length;
        this.debug(n + " options over " + select.options.length);
        select.options.length = n;

        for (i = 0; i < n; i ++) {
            o = select.options[i];
                if (!o) {
                    this.debug("create " + (i + 1));
                    o = new Option();
                    select.options[i] = o;
                }
                
                o.value = coll[i]["label"];
                o.text = coll[i]["name"];            
                o.eform = coll[i];
        }
    };
}, "Option Selector");