Class it_html:

/**
 * Create a dropdown menu object. Warning: encodes html code within options!
 * @param $tags key => value pairs of <select> tag
 *        note: add brackets after name (eg. 'name' => "var[]") when using multiple attribute
 * @param $options array (value => text) of available options or
 *        string key:val{,key:val} where key will be rawurldecoded so it may contain %2C as comma
 *        supports optgroups as array (value => optgroup => array(value => text))
 * @param $selected optional currently selected value, or comma-separated list or array for multi-select
 * Note: use tag('select') and tag('option') if you want do roll your own
 */
function select($tags$options$selected null)
{
    
# Transmogrify key:val{,key:val} to array(key => val)
    
if (!is_array($options))
    {
        
$opts explode(','$options);
        
$options = array();

        foreach(
$opts as $opt)
        {
            list(
$key$value) = explode(':'$opt);
            
$options[rawurldecode($key)] = $value;
        }
    }

    
$selected = ($tags['multiple'] && is_string($selected)) ? explode(','$selected) : (array)$selected;

    
$html "";
    foreach(
$options as $value => $option)
    {
        if (
is_array($option))
        {
            
$grouphtml "";
            foreach(
$option as $optval => $opt)
                
$grouphtml .= $this->_tag("option", array(array('value' => $optval'selected' => in_array((string)$optval$selected)), self::_strip_tags(Q(self::_strip_tags($opt)))));
            
$html .= $this->_tag("optgroup", array(array('label' => $value$grouphtml)));
        }
        else
            
$html .= $this->_tag("option", array(array('value' => $value'selected' => in_array((string)$value$selected), 'disabled' => $option === ""), (trim($option) === "") ? "&nbsp;" self::_strip_tags(Q(self::_strip_tags($option))))); # self::_strip_tags removes .q debug param coloring
    
}

    return 
$this->_tag("select", array($tags$html));
}