<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP version 4                                                        |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2005 The PHP Group                                |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license,       |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// | http://www.php.net/license/2_02.txt.                                 |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// | license@php.net so we can mail you a copy immediately.               |
// +----------------------------------------------------------------------+
// | Authors: Jason Hines <jason@greenhell.com>                           |
// +----------------------------------------------------------------------+
//
// $Id: $

require_once("HTML/QuickForm/input.php");

/**
 * HTML_QuickForm_AjaxFilterSelect QuickForm element class
 *
 * A QuickForm element that provides a select element populated with 
 * results from an AJAX-enabled search.  Requires the HTML_AJAX package.
 * AjaxFilterSelect must be given valid callback information, which tells
 * it where to retrieve the search results.
 *
 * Example QuickForm usage:
 * <code>
 * <?php
 * require('HTML/QuickForm.php');
 *
 * // New QuickForm instance
 * $form = new HTML_QuickForm;
 * 
 * // Create AjaxFilterSelect element instance
 * $fs = $form->createElement("ajax_filter_select","account_id","Account:");
 *
 * // Set callback information (server_url, class_name, function_name)
 * $fs->setServerCallback("/account_list.php","account_list","get_accounts");
 *
 * // Add AjaxFilterSelect element to form
 * $form->addElement($fs);
 * ?>
 * </code>
 *
 * AJAX Server Class Example:
 * <code>
 * <?php
 * require('HTML/AJAX/Server.php');
 * $server = new HTML_AJAX_Server();
 * $account_list = new account_list;
 * $server->registerClass($account_list);
 * $server->handleRequest();
 * 
 * class account_list {
 *     function get_accounts($query_text) {
 *         // $query_text is the user input.
 *         // Execute a database query, and return
 *         // the results in an associate array.
 *         return $result;
 *     }
 * }
 * ?>
 * </code>
 *
 * The AJAX server must return an associate array (or also
 * known as name=>value pairs) because the array is used to populate
 * a select element with values and text.
 *
 * See the HTML_AJAX PEAR package for more information on
 * creating AJAX server classes.
 *
 * @version   $Revision: $
 * @author    Jason Hines <jason@greenhell.com>
 * @access    public
 * @package   HTML_QuickForm_AjaxFilterSelect
 * @category  HTML
 */

class HTML_QuickForm_ajaxfilterselect extends HTML_QuickForm_input {

    var 
$_server_url null;
    var 
$_server_class null;
    var 
$_server_method null;

    
/**
     * Sets callback info required to make the AJAX call
     *
     * @param   string  $server_url     URL/Path to the AJAX server
     * @param   string  $class_name     Name of the AJAX server class
     * @param   string  $function_name  The class function to call
     * @author  Jason Hines <jason@greenhell.com>
     * @return  void
     * @access  public
     */
    
function setServerCallback($server_url,$class_name,$function_name) {
        
$this->_server_url $server_url;
        
$this->_server_class $class_name;
        
$this->_server_method $function_name;
    }

    
/**
     * Returns the input field in HTML
     *
     * @access    public
     * @return    string or PEAR error on misconfiguration
     */
    
function toHtml() {
        if (
is_null($this->_server_url) || is_null($this->_server_class) || is_null($this->_server_method)) {
            return 
PEAR::raiseError("AjaxFilterSelect element not configured!");
        }

        if (
$this->_flagFrozen) {
            return 
$this->getFrozenHtml();
        } else {
            
$out $this->_getTabs();
            
$out .= '<script type="text/javascript" src="'.$this->_server_url.'?client=all&stub='.$this->_server_class.'"></script>';
            
$out .= '
            <script type="text/javascript">
                function fs_findInput_'
.$this->getName().'() {
                    var fs_Callback = {
                        '
.$this->_server_method.': function(result) {
                            fs_setupInput("'
.$this->getName().'");
                            var s = document.getElementById("fs_select_'
.$this->getName().'");
                            var i = 0;
                            for (id in result) {
                                if (i==0) {
                                    var l = document.getElementById("fs_label_'
.$this->getName().'");
                                    l.value = result[id];
                                }
                                s.options[i++] = new Option(result[id],id);
                            }
                        }
                    }
                    var remoteObject = new '
.$this->_server_class.'(fs_Callback);
                    remoteObject.'
.$this->_server_method.'(document.getElementById("fs_text_'.$this->getName().'").value);
                }
            </script>'
;
            
$out .= $this->_getJavascript();
            
$out .= '<div id="filterselect_'.$this->getName().'"></div>';
            
$out .= "<input type=\"hidden\" name=\"fs_label_".$this->getName()."\" id=\"fs_label_".$this->getName()."\" value=\"".$_REQUEST['fs_label_'.$this->getName()]."\" />";
            if (
$this->getValue()) {
                
$out .= "<script type=\"text/javascript\">fs_valueInput('".$this->getName()."','".$this->getValue()."');</script>";
            } else {
                
$out .= "<script type=\"text/javascript\">fs_clearInput('".$this->getName()."');</script>";
            }
            return 
$out;
        }
    }

    
/**
     * Return script containing functions for AjaxAutoFilter
     *
     * @return  string    $js   String of Javascript code
     * @access  private
     */
    
function _getJavascript() {
        if (
defined('_FILTERSELECT_JS_EXISTS')) {
            return 
$js;
        }
        
define('_FILTERSELECT_JS_EXISTS'true);
        
$js .= '
            <script type="text/javascript">
            function fs_clearInput(n) {
                // container
                var div = document.createElement("div");
                div.id = "filterselect_"+n;
    
                // text input
                var t = document.createElement("input");
                t.type = "text";
                t.name = n;
                t.id = "fs_text_"+n;
                t.autocomplete = "off";
                div.appendChild(t);

                // find button
                var f = document.createElement("input");
                f.type = "button";
                f.id = "fs_find_"+n;
                f.value = "Find";
                f.onclick = function() { eval("fs_findInput_"+n+"()"); }
                div.appendChild(f);

                // replace div
                var old_div = document.getElementById("filterselect_"+n);
                old_div.parentNode.replaceChild(div,old_div);
            }
            function fs_setupInput(n) {
                // container
                var div = document.createElement("div");
                div.id = "filterselect_"+n;
    
                // select
                var s = document.createElement("select");
                s.name = n;
                s.id = "fs_select_"+n;
                s.onchange = function() { fs_saveLabel(n,s); }
                div.appendChild(s);

                // clear button
                var c = document.createElement("input");
                c.type = "button";
                c.id = "fs_clear_"+n;
                c.value = "Clear";
                c.onclick = function() { fs_clearInput(n); }
                div.appendChild(c);

                // replace div
                var old_div = document.getElementById("filterselect_"+n);
                old_div.parentNode.replaceChild(div,old_div);
            }
            function fs_valueInput(n,v) {
                // container
                var div = document.getElementById("filterselect_"+n);

                // hidden input
                h = document.createElement("input");
                h.type = "hidden";
                h.value = v;
                h.id = "fs_text_"+n;
                h.name = n;
                div.appendChild(h);

                // get label value
                var l = document.getElementById("fs_label_"+n);

                // print input
                t = document.createElement("span");
                t.innerHTML = l.value + "&nbsp;&nbsp;&nbsp;";
                div.appendChild(t);

                // clear button
                var c = document.createElement("input");
                c.type = "button";
                c.id = "fs_clear_"+n;
                c.value = "Change";
                c.onclick = function() { fs_clearInput(n); }
                div.appendChild(c);
            }
            function fs_saveLabel(n,s) {
                var l = document.getElementById("fs_label_"+n);
                l.value = s.options[s.selectedIndex].text;
            }
            </script>'
;
          return 
$js;
     }

}

#if (class_exists('HTML_QuickForm')) {
#    HTML_QuickForm::registerElementType('ajaxfilterselect', 'HTML/QuickForm/ajaxfilterselect.php', 'HTML_QuickForm_ajaxfilterselect');
#}


?>