Location: PHPKode > scripts > HTML_QuickForm_ComboBox > html_quickform_combobox/combobox.php
<?php
/* vim: set number autoindent tabstop=4 shiftwidth=4 softtabstop=4: */

/**
* This package add combobox type to HTML_QuickForm
*
* A combobox is an element composed by an input text and a dropdown list:
* you can either select an option from the list or  write into the text field.

* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt.  If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to hide@address.com so we can mail you a copy immediately.
*
* @category   HTML
* @package    HTML_QuickForm_ComboBox
* @author     Fabio Ambrosanio <hide@address.com>
* @license    http://www.php.net/license/3_01.txt  PHP
* @version    @package_version@
*
* $Id: combobox.php,v 1.2 2006/11/29 21:14:39 fabamb Exp $
*/
require_once 'HTML/QuickForm/text.php';

/**
* This class represents a combobox element of HTML_QuickForm framework.
*
* @author     Fabio Ambrosanio <hide@address.com>
* @category   HTML
* @package    HTML_QuickForm_ComboBox
* @version    @package_version@
* @license    http://www.php.net/license/3_01.txt  PHP
*/
class HTML_QuickForm_ComboBox extends HTML_QuickForm_text
{
    // {{{ properties

    /**
     * Elements of the dropdown list
     *
     * @var array
     * @access private
     */
    var $_elements = null;

    /**
     * Filename of css stylesheet
     *
     * @var string
     */
    var $_css = 'combobox.css';

    /**
     * Path of css stylesheet
     *
     * @var unknown_type
     */
    var $_css_path = false;

    /**
     * Filename and path of javascript library
     */
    var $_js = 'combobox.js';

    /**
     * Options for element's UI.
     * You can modify the appearence of combobox (see below for the list of elements and classes.
     *
     * If options contains a value for arrowImage key, an image is used instead of a button.
     *
     * @var array
     * @access private
     */
    var $_options = array(
        'boxClass' => 'comboBox',         // style class of external box
        'inputClass' => 'comboBoxInput',      // style class of input text field
        'buttonClass' => 'comboBoxButton',      // style class of dropdown button
        'arrowClass' => 'comboBoxArrow',      // style class of dropdown image
        'containerClass' => 'comboBoxContainer',  // style class of dropdown container
        'optionClass' => 'comboBoxOption',      // style class of dropdown options
        'optionClassOver' => 'comboBoxOptionOver',  // style class of dropdown options when highlighted
        'buttonValue' => '*'            // value of dropdown button
    );

    // }}}

    // {{{ constructor

    /**
     * Class constructor
     *
     * @param     string    $elementName    (required)Input field name attribute.
     * @param     string    $elementLabel   (required)Input field label in form.
     * @param     array     $elements       (optional)Combobox elements.
     * @param     array     $options        (optional)An associative array which elements specify different
     *                                      aspects of the combobox.
     * @param     mixed     $attributes     (optional)Either a typical HTML attribute string
     *                                      or an associative array. Date format is passed along the attributes.
     * @access    public
     * @return    void
	 *
	 * With $options you can specify the CSS class to use with different aspects of the combobox.
	 * The compobox's aspects that you can change assigning different CSS class are:
	 * <pre>
	 *	Aspect			Description									Default class
	 *  boxClass		external box								comboBox
	 * 	inputClass		input textfield								comboBoxInput
	 *	buttonClass		dropdown button (if used)					comboBoxButton
	 *	arrowClass		dropdown arrow (if used)					comboBoxArrow
	 *	containerClass	dropdown container							comboBoxContainer
	 *	optionClass		single option inside dropdown container		comboBoxOption
	 *	optionClassOver	single option when mouse is over			comboBoxOptionOver
	 * </pre>
	 *
	 * You can change the button (value)label with buttonValue option, es.: butonValue => 'V' or
	 * specify images to use to render the button:
	 * <pre>
	 *	arrowImage			image used to render the button in normal state
	 *	arrowImageOver		image used when the mouse is over the button
	 *	arrowImageDown		image used when the button in clicked
	 * </pre>
     */
    function HTML_QuickForm_ComboBox($elementName = null, $elementLabel = null, $elements = null, $options = null, $attributes = null)
    {
        $this->HTML_QuickForm_text($elementName, $elementLabel, $attributes);
        $this->_persistantFreeze = true;
        if (isset($elements)) {
            $this->_elements = $elements;
        }
        $id = $this->getAttribute('id');
        if ("$id" == '') {
            $this->updateAttributes(array(
                'id' => $elementName
            ));
        }

        // update element options
        if ($options && is_array($options)) {
            $this->_options = array_merge($this->_options, $options);
        }
    } //end constructor

    // }}}

    // {{{ toHtml()

    /**
     * Returns Html for the Combobox input element
     *
     * @access      public
     * @return      string  the HTML string representing the combobox
     */
    function toHtml()
    {
        // generate an unique id for all UI elements
        $uid = uniqid('cb');

        if ($this->_flagFrozen) {
            // input froze: return parent html
            $html = parent::toHtml();
        } else {
            // eventually write style classes and javascript functions
            $html = $this->_getCSS();
            $html .= $this->_getJS();

            // build input text field
            $this->updateAttributes(array(
                'class' => $this->_options['inputClass']
            ));
            $input = parent::toHtml();

            // wich type of button? input-button or image?
            if (!$this->_options['arrowImage']) {
                // build simple button
                $buttonClass = $this->_options['buttonClass'];
                $buttonValue = $this->_options['buttonValue'];
                $button = "<input value=\"$buttonValue\" type=\"button\" id=\"$uid.button\" class=\"$buttonClass\" onClick=\"comboBoxShowOptions('$uid')\" onblur=\"comboBoxHideOptions('$uid')\"/>";
            } else {
                // build button implemented with an image
                $arrowImage = $this->_options['arrowImage'];

                // have we an image for mouse-over?
                $arrowImageOver = $this->_options['arrowImageOver'];
                if (!$arrowImageOver) $arrowImageOver = $arrowImage;

                // have we an image for mouse-down?
                $arrowImageDown = $this->_options['arrowImageDown'];
                if (!$arrowImageDown) $arrowImageDown = $arrowImage;

                $arrowClass = $this->_options['arrowClass'];
                $button = "<input type=\"image\" src=\"$arrowImage\" id=\"$uid.arrow\" class=\"$arrowClass\" align=\"top\" onClick=\"comboBoxShowOptions('$uid'); return false;\" onMouseOver=\"comboBoxSwitchImage('$uid')\" onMouseOut=\"comboBoxSwitchImage('$uid')\" arrowimage=\"$arrowImage\" arrowimageover=\"$arrowImageOver\" arrowimagedown=\"$arrowImageDown\" onblur=\"comboBoxHideOptions('$uid')\" />";
            }

            // build elements list
            $options = '';
            if (is_array($this->_elements)) {
                $optionClass = $this->_options['optionClass'];
                if ($this->_is_assoc_array($this->_elements)) {
                    foreach ($this->_elements as $k => $e) {
                        $options .= "<div class=\"$optionClass\" width=\"500px\" value=\"$k\">$e</div>";
                    }
                } else {
                    foreach ($this->_elements as $e) {
                        $options .= "<div class=\"$optionClass\" width=\"500px\">$e</div>";
                    }
                }
            }

            // build the whole combobox
            $boxClass = $this->_options['boxClass'];
            $containerClass = $this->_options['containerClass'];
            $html .= "<div id=\"$uid.box\" class=\"$boxClass\" width=\"500px\">$input$button</div><div id=\"$uid.container\" class=\"$containerClass\"  width=\"500px\">$options</div>";

            // add this combobox to a javascript array:
            // when the page is loaded a script will resize each combobox
            $html .= "<script type=\"text/javascript\">var aCombo = new Object();aCombo[\"id\"] = '$uid';combos[combos.length++] = aCombo;</script>";
        }

        return $html;
    }// end func toHtml

    // }}}

    // {{{ setCSS($filename, $path)

    /**
     * Sets new CSS file
     *
     * @param string $filename	filename of CSS file
     * @param string $path		path of CSS file
	 * @param string $options	associative array which elements specify CSS classes for different aspects cf the combobox
	 */
	function setCSS($filename, $path = false, $options = false)
	{
		$this->_css = $filename;
		$this->_css_path = $path;
		if ($options && is_array($options)) {
			$this->_options = array_merge($this->_options, $options);
		}
	}// end func setCSS

    // }}}

    /**
     * Returns CSS styles
     *
     * @return string
     * @access private
     */
    function _getCSS()
    {
    	if (defined('HTML_QUICKFORM_COMBOBOX_CSS_' . $this->_css_path . $this->_css)) return '';
    	define('HTML_QUICKFORM_COMBOBOX_CSS_' . $this->_css_path . $this->_css, true);

    	$location = $this->_getFileLocation($this->_css, $this->_css_path);
        $css = "<style type=\"text/css\">";
        $css .= "/* "; if ($this->_css_path) $css .= $this->_css_path . DIRECTORY_SEPARATOR;
        $css .= $this->_css . " */";
        $css .= file_get_contents($location) . "</style>";
        return $css;
    }

    /**
     * Returns javascript functions
     *
     * @return string
     * @access private
     */
    function _getJS()
    {
    	if (defined('HTML_QUICKFORM_COMBOBOX_JS')) return '';
    	define('HTML_QUICKFORM_COMBOBOX_JS', true);

        $location = $this->_getFileLocation($this->_js, false);
        $js = "<script type=\"text/javascript\">" . file_get_contents($location) . "</script>";
        return $js;
    }


    /**
     * Calcs the canonical path of the specified file
     *
     * @param string $filename
     * @param string $path
     * @return string
     */
    function _getFileLocation($filename, $path)
    {
    	if ($path) {
    		$location = realpath($path . DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename;
    	} else {
	        $path = '@data-dir@'.DIRECTORY_SEPARATOR.'HTML_QuickForm_ComboBox'.DIRECTORY_SEPARATOR;
    	    if(strpos($path, '@'.'data-dir@') === 0) {
        	    $path = realpath(dirname(__FILE__).DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
        	}
        	$location = $path.$filename;
    	}
        return $location;
    }

    /**
     * Checks if an array is associative
     *
     * @param array $php_val
     * @return true if $php_val is an associative array, false otherwise
     */
    function _is_assoc_array( $php_val )
    {
        if( !is_array( $php_val ) ){
            # Neither an associative, nor non-associative array.
            return false;
        }

        $given_keys = array_keys( $php_val );
        $non_assoc_keys = range( 0, count( $php_val ) );

        if ( function_exists( 'array_diff_assoc' ) ) { # PHP > 4.3.0
                return array_diff_assoc( $given_keys, $non_assoc_keys );
        } else {
                return array_diff( $given_keys, $non_assoc_keys ) and array_diff( $non_assoc_keys, $given_keys );
        }
    }

} // end class HTML_QuickForm_ComboBox

if (class_exists('HTML_QuickForm')) {
    HTML_QuickForm::registerElementType('combobox', 'HTML/QuickForm/combobox.php', 'HTML_QuickForm_ComboBox');
}
?>
Return current item: HTML_QuickForm_ComboBox