<?php
/************************************************************
* Part of WebWidgets library
* Contain classes for making input fields.
* **********************************************************
* Version 0.8 09.10.02
* **********************************************************
* License: GPL - http://www.fsf.org/copyleft/gpl.txt
* **********************************************************
* Contain classes:
*
* FormControl - abstract class.
* TextField
* TextArea
* Hidden
* Password
* Radio
* CheckBox
* Option
* Select
* Submit
* Reset
* FileField - produce field to upload file
* InputImage
* Button
* **********************************************************
* Author: Dmitry Levashov (hide@address.com , hide@address.com)
* *********************************************************/
/************************************************************
* Abstract class form elements widgets
* Declare common interface for access to form elements
***********************************************************/
class FormControl extends WebWidget
{
/**
* Field label, used in error message
* @param string
*/
var $Label;
/**
* Error message
* @param string
*/
var $ErrMsg = 'Incorrect value';
/**
* Constructor
* @param string tag name
* @param string name of form field
* @param string value of field
* @param string label of field
* @param array tags attributes
* @access public
*/
function FormControl($tag, $name, $val='', $label='', $attr='')
{
$this->Id = WebWidget::_makeId();
$this->Tag = strtolower($tag);
if ($attr) $this->setAttr($attr);
if ($name) $this->setAttr('name', $name);
if ($val) $this->setAttr('value', $val);
$this->Label = $label;
} // end func constructor
/**
* Overloaded method from parent class.
* For "name" atribute check is it array element name.
* If so, call _getRealName method to parse name
* @param string/array attribute name / array of attributes
* @param string attribute value
* @access public
*/
function setAttr($attr, $val='')
{
if (!$attr) return;
if (!is_array($attr)) {
if ('name' == $attr) $this->Attr['name'] = $this->_getRealName($val);
else $this->Attr[$attr] = $val;
} else {
foreach ($attr as $k=>$v) {
if ('name' == $k) $this->Attr['name'] = $this->_getRealName($v);
else $this->Attr[$k] = $v;
}
}
} // end func setAttr
/**
* Set form element value
*/
function setValue($value) { $this->Attr['value'] = $value; } // end func setValue
/**
* Return value, which user input in form field.
* If flag $struct is true, return whole structure,
* according to the full element name (see _fetFullName()).
* If - false, return name-value pair
* @param bool flag
* @access public
* @return array
*/
function getValue($struct = true)
{
return $this->_getStruct($this->Attr['value'], $struct);
} // end func getValue
/**
* Returns attributes as string
* @access private
* @return string
*/
function _attr2str()
{
foreach ($this->Attr as $k=>$v) {
if ($k != 'name' || !$this->Groups)
$str .= ' ' . $k . '="' . htmlspecialchars($v) . '"';
else
$str .= ' ' .$k . '="'.$this->_getFullName() . '"';
}
return $str;
} // end func _attr2str
/**
* If field name is name of array element, parse name and
* put part in $Groups array. Return field name
* @access private
* @param string
* @return string
*/
function _getRealName($name)
{
if (preg_match_all('/([^\[\]]+)|\[()\]/i', $name,$m)) {
$rname = array_pop($m[1]);
$this->Groups = $m[1];
return $rname;
}
return htmlspecialchars($name);
} // end func _getRealName
/**
* If array $Groups is not empty, build name of field as array element name
* @access private
* @return string
*/
function _getFullName()
{
$str = $this->Groups[0];
if (sizeof($this->Groups) > 1)
$str .= '[' . implode('][', array_slice($this->Groups, 1)) . ']';
return $str.'['.$this->Attr['name'].']';
} // end func _getFullName
/**
* Fetch field value from _GET or _POST, passed by reference.
* @param array _POST or _GET or part of it
* @access private
* @return array
*/
function &_fetch(&$source)
{
if ($this->Groups) {
for ($i=0; $i<sizeof($this->Groups); $i++) {
$source = &$source[$this->Groups[$i]];
}
}
return ($this->Attr['name']) ? $source[$this->Attr['name']] : $source;
} // end func &_fetch
/**
* Validate input value, return true or false
* @access private
* @return bool
*/
function _valid() { return true; } // end func _valid
/**
* Build array for getValue method and put element value in it
* @param mix element value
* @param bool build whole array?
* @access private
*/
function _getStruct($val, $struct=true)
{
if (!$this->Groups || !$struct)
return array($this->Attr['name'] => $val);
$res[$this->Groups[0]] = array();
$data = &$res[$this->Groups[0]];
for ($i=1; $i<sizeof($this->Groups); $i++) {
$data[$this->Groups[$i]] = array();
$data = &$data[$this->Groups[$i]];
}
if (!$this->Attr['name'])
$data = $val;
else
$data[$this->Attr['name']] = $val;
return $res;
} // end func _getStruct
/**
* Build Html output
* @access private
*/
function _createView()
{
$this->View = '<' . $this->Tag . $this->_attr2str() . " />\n";
} // end func _createView
} // end class FormControl
/***********************************************************
* produce text field
***********************************************************/
class TextField extends FormControl
{
/**
* Type of data in field
* @param string
*/
var $DType = 'str';
/**
* Param for validate field. Min & max field value (string lenth)
* @param array
*/
var $Range;
/**
* RegExp for validate filed
* @param string
*/
var $Reg;
/**
* name of callback function to validate field
* @param string
*/
var $Callback;
/**
* Constructor
* @param string name of the field
* @param string value of the field
* @param string label of the field
* @param array attributes
* @param string data type
* @access public
*/
function TextField($name, $val='', $label='', $attr='', $dtype='str')
{
parent::FormControl('input', $name, $val, $label, $attr);
$this->Attr['type'] = 'text';
$this->DType = $dtype;
} // end func conctructor
/**
* Set min & max value (string lenth) of field
* @param int min value
* @param int max value
* @access public
*/
function setRange($min=0, $max=0)
{
if ($min) $this->Range['min'] = $min;
if ($max) $this->Range['max'] = $max;
} // end func setRange
/**
* Set RegExp for validate field
* @param string regexp
* @access public
*/
function setReg($reg) { $this->Reg = $reg; } // end func setReg
/**
* Set callback function for validate field
* @param string callback function name
* @access public
*/
function setCallback($callback) { $this->CallBack = $callback; } // end func setCallback
/**
* Fetch value from _GET or _POST, passed by reference, if form was submitted.
* If element contains incorrect value, put into $err array pair
* of element label and error message
* @param array
* @param array array of error messages
* @access private
*/
function _complite(&$source, &$err)
{
$this->Attr['value'] = $this->_clean($this->_fetch($source));
if (!$this->_valid())
$err[($this->Label) ? $this->Label : $this->Attr['name']] = $this->ErrMsg;
} // end func _complite
/**
* "Clean" user input
* @param string user input data
* @return string "clean data"
* @access private
*/
function _clean($data)
{
if ('int' == $this->DataType) {
return intval($data);
} elseif ('double' == $this->DataType) {
return doubleval($data);
} else {
return trim($data);
}
} // end func _clean
/**
* Validate field value
* @return bool coorect value or not
* @access private
*/
function _valid()
{
if ($this->Reg) {
return preg_match($this->Reg, $this->Attr['value']);
} elseif ($this->CallBack) {
return $this->Callback($this->Attr['value']);
} elseif ($this->Range) {
$val = ('str' == $this->DType) ? strlen($this->Attr['value']) : $this->Attr['value'];
if ($this->Range['min'] && $val < $this->Range['min']) return false;
if ($this->Range['max'] && $val > $this->Range['max']) return false;
}
return true;
} // end func _valid
} // end class TextField
/*********************************************************
* produce textarea field
********************************************************/
class TextArea extends FormControl
{
/**
* Param for validate field. Min & max string lenth
* @param array
*/
var $Range;
/**
* RegExp for validate filed
* @param string
*/
var $Reg;
/**
* name of callback function to validate field
* @param string
*/
var $Callback;
/**
* Value of the field
* @param string
*/
var $Value;
/**
* Constructor
* @param string name of field
* @param string value of field
* @param string label of field
* @param array attributes
* @access public
*/
function TextArea($name, $val='', $label='', $attr='')
{
parent::FormControl('textarea', $name, '', $label, $attr);
$this->Value = $val;
} // end func constructor
/**
* Set field value
* @param string field value
*/
function setValue($value) { $this->Value = $value; } // end func setValue
/**
* Set min & max string lenth for field value
*/
function setRange($min=0, $max=0)
{
if ($min) $this->Range['min'] = (int)$min;
if ($max) $this->Range['max'] = (int)$max;
} // end func setRange
/**
* Set RegExp for validate field
* @param string regexp
* @access public
*/
function setReg($reg) { $this->Reg = $reg; } // end func setReg
/**
* Set callback function for validate field
* @param string callback function name
* @access public
*/
function setCallback($callback) { $this->CallBack = $callback; } // end func setCallback
/**
* Return field value
* @return array
*/
function getValue($struct=true)
{
return $this->_getStruct($this->Value, $struct);
} // end func getValue
/**
* Fetch value from _GET or _POST, passed by reference, if form was submitted.
* If element contains incorrect value, put into $err array pair
* of element label and error message
* @param array
* @param array array of error messages
* @access private
*/
function _complite(&$source, &$err)
{
$this->Value = trim($this->_fetch($source));
if (!$this->_valid())
$err[($this->Label) ? $this->Label : $this->Attr['name']] = $this->ErrMsg;
} // end func _complite
/**
* Validate field value
* @return bool coorect value or not
* @access private
*/
function _valid()
{
if ($this->Reg) {
return preg_match($this->Reg, $this->Value);
} elseif ($this->CallBack) {
return $this->Callback($this->Value);
} elseif ($this->Range) {
if ($this->Range['min'] && $this->Value < $this->Range['min']) return false;
if ($this->Range['max'] && $this->Value > $this->Range['max']) return false;
}
return true;
} // end func _valid
/**
* Build Html output
*/
function _createView()
{
$this->View = '<textarea'.$this->_attr2str().">\n";
$this->View .= $this->Value . "</textarea>\n";
} //end func _createView
} // end class TextArea
/*****************************************************************
* produce hidden field
*****************************************************************/
class Hidden extends FormControl
{
/**
* Contructor
* @param string name of the field
* @param string value of the field
* @access public
*/
function Hidden($name, $val='1')
{
parent::FormControl('input', $name, $val);
$this->Attr['type'] = 'hidden';
} // end func constructor
} // end class Hidden
/********************************************************************
* produce password field
********************************************************************/
class Password extends FormControl
{
/**
* RegExp for validate input
* @param string
*/
var $Reg = '/^[a-z0-9_\-\.]{6,12}$/i';
/**
* Error message
* @param string
*/
var $ErrMsg = 'Incorrect chars';
/**
* Constructor
* @param string name of the field
* @param string value of the field
* @param string label of the field
* @param array attributes
* @access public
*/
function Password($name, $val='', $label='', $attr='')
{
parent::FormControl('input', $name, '', $label, $attr);
$this->Attr['type'] = 'password';
} // end func constructor
/**
* Set RegExp for validate field
* @param string regexp
* @access public
*/
function setReg($reg) { $this->Reg = $reg; } // end func setReg
/**
* Fetch value from _GET or _POST, passed by reference, if form was submitted.
* If element contains incorrect value, put into $err array pair
* of element label and error message
* @param array
* @param array array of error messages
* @access private
*/
function _complite(&$source, &$err)
{
$this->Attr['value'] = trim($this->_fetch($source));
if (!$this->_valid())
$err[($this->Label) ? $this->Label : $this->Attr['name']] = $this->ErrMsg;
} // end func _complite
/**
* Validate field value
* @return bool coorect value or not
* @access private
*/
function _valid()
{
if ($this->Reg) {
return preg_match($this->Reg, $this->Attr['value']);
} elseif ($this->CallBack) {
return $this->Callback($this->Attr['value']);
}
return true;
} // end func _valid
} // end class Password
/***************************************************************
* produce radio button
***************************************************************/
class Radio extends FormControl
{
/**
* Constructor
* @param string name of the field
* @param string value of the field
* @param string label of the field
* @param array attributes
* @access public
*/
function Radio($name, $val, $label='', $attr='')
{
parent::FormControl('input', $name, $val, $label, $attr);
$this->Attr['type'] = 'radio';
if (!$label) $this->Label = $val;
} // end func contructor
/**
* Return value, if radio button checked
* If flag $struct is true, return whole structure,
* according to the full element name (see _fetFullName()).
* If - false, return name-value pair
* @param boolean flag
* @access public
* @return array
*/
function getValue($struct=true)
{
if (!$this->Attr['checked']) return false;
return $this->_getStruct($this->Attr['value'], $struct);
} // end func getValue
/**
* Fetch field value from _GET or _POST, passed by reference.
* @param array _POST or _GET or part of it
* @param array array of error messages
* @access private
* @return array
*/
function _complite(&$source, &$err)
{
$val = $this->_fetch($source);
if (($this->Attr['name'] && $this->Attr['value'] == $val)
|| (!$this->Attr['name'] && is_array($val) && in_array($this->Attr['value'], $val))) {
$this->Attr['checked'] = 'on';
} else {
unset($this->Attr['checked']);
}
} // end func _complite
/**
* Build array for getValue method and put element value in it
* @param mix element value
* @param boolean build array accordind to "full" field name or not
* @access private
*/
function _getStruct($val, $struct)
{
if (!$this->Groups || !$struct)
return array($this->Attr['name'] => $val);
$res[$this->Groups[0]] = array();
$data = &$res[$this->Groups[0]];
for ($i=1; $i<sizeof($this->Groups); $i++) {
$data[$this->Groups[$i]] = array();
$data = &$data[$this->Groups[$i]];
}
if ($this->Attr['name'])
$data[$this->Attr['name']] = $val;
else
$data[] = $val;
return $res;
} // end func _getStruct
} // end class Radio
/******************************************************************
* produce checkbox
*****************************************************************/
class CheckBox extends Radio
{
/**
* Constructor
* @param string name of the field
* @param string value of the field
* @param string label of the field
* @param array attributes
* @access public
*/
function CheckBox($name, $val='', $label='', $attr='')
{
parent::FormControl('input', $name, ($val)?$val:1, $label, $attr);
$this->Attr['type'] = 'checkbox';
if (!$label) $this->Label = ($name) ? $name : $val ;
} // end func contructor
/**
* Fetch value from _GET or _POST, passed by reference, if form was submitted.
* If element contains incorrect value, put into $err array pair
* of element label and error message
* @param array
* @param array array of error messages
* @access private
*/
function _complite(&$source, &$err)
{
unset($this->Attr['checked']);
$val = $this->_fetch($source);
if ($this->Attr['name']) {
if (($this->Attr['value'] && $this->Attr['value'] == $val))
$this->Attr['checked'] = 'on';
} elseif (!$this->Attr['name'] && $this->Attr['value']) {
if (is_array($val) && in_array($this->Attr['value'], $val))
$this->Attr['checked'] = 'on';
}
} // end func _complite
} // end class CheckBox
/*********************************************************************
* produce tag "option". Not nessesery to use this class directly.
* Use Select class.
*********************************************************************/
class Option extends FormControl
{
/**
* Constructor
* @param string value of the field
* @param string label of the field
* @param array attributes
* @access public
*/
function Option($val, $label='', $attr='')
{
parent::FormControl('option', '', $val, $label, $attr);
if (!$this->Attr['value'] && $this->Label) $this->Attr['value'] = $this->Label;
if ($this->Attr['value'] && !$this->Label) $this->Label = $this->Attr['value'];
} // end func Option
/**
* Return value, if option selected.
* @access public
* @return array
*/
function getValue()
{
if (!$this->Attr['selected']) return false;
return $this->Attr['value'];
} // end func getValue
/**
* Fetch value from _GET or _POST, passed by reference, if form was submitted.
* @param array
* @access private
*/
function _complite(&$source)
{
unset($this->Attr['selected']);
if (!is_array($source)) {
if (isset($this->Attr['value']) && $this->Attr['value'] == $source)
$this->Attr['selected'] = 'on';
} elseif(is_array($source)) {
if (isset($this->Attr['value']) && in_array($this->Attr['value'], $source))
$this->Attr['selected'] = 'on';
}
} // end func _complite
/**
* Build html output
* @access private
* @return void
*/
function _createView()
{
$this->View = '<option'.$this->_attr2str().'>';
$this->View .= $this->Label . "</option>\n";
} // end func _createView
} // end class Option
/************************************************************
* produce select filed
***********************************************************/
class Select extends FormControl
{
/**
* Array of childs objects (objects of the Option class)
* @param array childs objects
*/
var $Childs = array();
/**
* Param for validate field. Min & max number of selected option
* @param array
*/
var $Range;
/**
* Constructor
* @param string name of the field
* @param string value of the field
* @param string label of the field
* @param array attributes
* @access public
*/
function Select($name, $val='', $label='', $attr=null)
{
parent::FormControl('select', $name, '', $label, $attr);
$this->Value = $val;
if ($this->Attr['multiple'] ) {
$this->Groups[] = $this->Attr['name'];
$this->Attr['name'] = '';
}
} // end func constructor
/**
* Add new option object in $Childs array
* Return Id of added object on success or false
* @param object widget
* @access public
* @return int
*/
function add(&$Widget)
{
$this->Childs[] = &$Widget;
if ($this->Value) {
if ( isset($Widget->Attr['value']) && $this->Value == $Widget->Attr['value'] )
$Widget->Attr['selected'] = 'on';
}
return $Widget->Id;
} // end func add
/**
* Wrapper for add method.
* Create new option object(s) and add it to $Childs array
* If $value - string, only one option added
* If $value is array and $use_keys = true, array keys become options values.
* If $use_keys = false, array values become options values
* @param mix option value or array of options values
* @param string option label
* @param bool use or not array keys as options values
* @access public
* @return mixed
*/
function addOption($value, $label='', $use_keys=false)
{
if (!is_array($value)) {
$id = $this->add(new Option($value, $label));
} else {
foreach ($value as $key=>$val) {
$id[] = $this->add(new Option(($use_keys) ? $key : $val, $val));
}
}
return $id;
} // end func addOption
function setValue($val) { $this->Value = $val; }
/**
* Set min & max of selected options
* @param int min value
* @param int max value
* @access public
*/
function setRange($min=0, $max=0)
{
if ($min) $this->Range['min'] = ($this->Attr['multiple']) ? 1 : (int)$min;
if ($max) $this->Range['max'] = ($this->Attr['multiple']) ? 1 : (int)$max;
} // end func setRange
/**
* Return value, selected option(s).
* If flag $struct is true, return whole structure,
* according to the full element name (see _fetFullName()).
* If - false, return name-value pair
* @param boolean flag
* @access public
* @return array
*/
function getValue($struct=true)
{
foreach ($this->Childs as $i=>$Child) {
if (($data = $this->Childs[$i]->getValue()) !== false){
if ($this->Attr['multiple'])
$res[] = $data;
else
return $this->_getStruct($data, $struct);
}
}
return ($res) ? $this->_getStruct($res, $struct) : false;
} // end func getValue
/**
* Fetch value from _GET or _POST, passed by reference, if form was submitted.
* If element contains incorrect value, put into $err array pair
* of element label and error message
* @param array
* @param array array of error messages
* @access private
*/
function _complite(&$source, &$err)
{
$s = $this->_fetch($source);
foreach ($this->Childs as $i=>$Child) {
$this->Childs[$i]->_complite($s, $err);
if ($this->Childs[$i]->Attr['selected'])
$count++;
}
if ($this->Range) {
if ($this->Range['min'] && $count < $this->Range['min'])
$err[$this->Label] = $this->ErrMsg;
if ($this->Range['max'] && $count > $this->Range['max'])
$err[$this->Label] = $this->ErrMsg;
}
} // end func _complite
/**
* Build array for getValue method and put element value in it
* @param mix element value
* @param bool build whole array?
* @access private
*/
function _getStruct($val, $struct)
{
if (!$this->Groups || !$struct)
return array($this->Attr['name'] => $val);
$res[$this->Groups[0]] = array();
$data = &$res[$this->Groups[0]];
for ($i=1; $i<sizeof($this->Groups); $i++) {
$data[$this->Groups[$i]] = array();
$data = &$data[$this->Groups[$i]];
}
if (!$this->Attr['name'])
$data = $val;
else
$data[$this->Attr['name']] = $val;
return $res;
} // end func _getStruct
/**
* Build html output
* @access private
*/
function _createView()
{
$this->View = '<select' . $this->_attr2str() . ">\n";
foreach ($this->Childs as $i=>$Child) {
$this->View .= $this->Childs[$i]->getView();
}
$this->View .= "</select>\n";
} // end func _createView
} // end class Select
/**********************************************************
* Class to make submit button
**********************************************************/
class Submit extends FormControl
{
/**
* Flag indicate what button pressed
* @param bool
*/
var $_Submit = false;
/**
* Constructor
* @param string button name
* @param string button value
* @param array attributes
* @access public
*/
function Submit($name='', $val='Submit', $attr=null)
{
parent::FormControl('input', $name, $val, $label, $attr);
$this->Attr['type'] = 'submit';
} // end func constructor
/**
* Return value only if button was pressed. So your can use
* several buttons in one form. For example 'previous' - 'next', etc.
* If flag $struct is true, return whole structure,
* according to the full element name (see _fetFullName()).
* If - false, return name-value pair
* @param bool flag
* @access public
* @return array
*/
function getValue($struct=true)
{
if (!$this->_Submit) return false;
return $this->_getStruct($this->Attr['value'], $struct);
} // end func getValue
/**
* Fetch value from _GET or _POST, passed by reference, if form was submitted.
* @param array
* @param array array of error messages
* @access private
*/
function _complite(&$source, &$err)
{
if ($this->Attr['value'] == $this->_fetch($source))
$this->_Submit = true;
} // end func _complite
} // end class Submit
/***************************************************
* Class to make reset button
***************************************************/
class Reset extends FormControl
{
/**
* Constructor
* @param string button value
* @param array attributes
* @access public
*/
function Reset($val='Submit', $attr=null)
{
parent::FormControl('input', '', $val, $label, $attr);
$this->Attr['type'] = 'reset';
} // end func constructor
/**
* Overwrite parent method. Reset button returns no value
* @return boolean
*/
function getValue() { return false; } // end func getValue
} // end class Reset
/*******************************************************
* produce form field for upload file
*******************************************************/
class FileField extends FormControl
{
/**
* Value of field.
* @param array
*/
var $Value = array('name'=>'', 'type'=>'', 'tmp_name'=>'', 'size'=>0);
/**
* Constructor. Has the same params as other FormControl childs classes contructors,
* but $value param don't used.
* In difference from other form fields,
* name of file field can be array element name, but no more then 2 dimentional array name
* @param string name of the field
* @param string value of the field
* @param string label of the field
* @param array attributes
* @access public
*/
function FileField($name, $value='', $label='', $attr='')
{
parent::FormControl('input', $name, '', $label, $attr);
$this->Attr['type'] = 'file';
} // end func constructor
/**
* Set min & max file size in bytes.
* Min size means that file must be uploaded.
* @param int min size
* @param int max size
* @access public
*/
function setRange($min=0, $max=0)
{
if ($min) $this->Range['min'] = (int)$min;
if ($max) $this->Range['max'] = (int)$max;
} // end func setRange
/**
* Fetch values from $_FILES array, if file was uploaded
* Has the same params as other fields, but do not use $source param
* @param array
* @param array array of error message
*/
function _complite(&$source, &$err)
{
if (!$this->Groups) {
$this->Value = $_FILES[$this->Attr['name']];
} else {
$file = $_FILES[$this->Groups[0]];
$this->Value['name'] = $file['name'][$this->Attr['name']];
$this->Value['type'] = $file['type'][$this->Attr['name']];
$this->Value['tmp_name'] = $file['tmp_name'][$this->Attr['name']];
$this->Value['size'] = $file['size'][$this->Attr['name']];
}
//print_r($this->Value);
if (!$this->_valid())
$err[($this->Label) ? $this->Label : $this->Attr['name']] = $this->ErrMsg;
} // end func _comlite
/**
* Validate file size
* @access private
* @return bool
*/
function _valid()
{
if ($this->Range['max'] && $this->Value['size'] > $this->Range['max'])
return false;
return true;
} // end func _valid
} // end class FileField
/******************************************************************
* produce input tag with type=image
*****************************************************************/
class ImageField extends FormControl
{
var $Attr = array('border'=>1);
/**
* Value of the field. Array of coords where image was clicked
* @param array
*/
var $Value = array('x'=>0, 'y'=>0);
/**
* Flag indicate that image was clicked
* @param bool
*/
var $_Submit = false;
/**
* Constructor
* @param string name of the field
* @param string value of the field
* @param string label of the field
* @param array attributes
* @access public
*/
function ImageField($name, $value='', $label='', $attr='')
{
parent::FormControl('input', $name, '', $label, $attr);
$this->Attr['type'] = 'image';
$this->setAttr('src', $value);
} // end func constructor
/**
* Return value only when image was clicked.
* If flag $struct is true, return whole structure,
* according to the full element name (see _fetFullName()).
* If - false, return name-value pair
* @param bool flag
* @access public
* @return array
*/
function getValue($struct=true)
{
if (!$this->_Submit) return false;
return $this->_getStruct($this->Value, $struct);
} // end func getValue
/**
* Fetch value from _GET or _POST, passed by reference, if form was submitted.
* @param array
* @param array array of error messages
* @access private
*/
function _complite(&$source, &$err)
{
if ( (list($this->Value['x'], $this->Value['y']) = $this->_fetch($source)) != false)
$this->_Submit = true;
} // end func _complite
/**
* fetch click coord from GET or POST
* @param array _POST or _GET or part of it
* @access private
* @return array
*/
function &_fetch(&$source)
{
if ($this->Groups) {
for ($i=0; $i<sizeof($this->Groups); $i++) {
$source = &$source[$this->Groups[$i]];
}
}
if ($source[$this->Attr['name'].'_x'])
return array($source[$this->Attr['name'].'_x'], $source[$this->Attr['name'].'_y']);
return false;
} // end func _fetch
} // end class ImageFiled
/******************************************************************
* produce button tag, if need this exotic :))
******************************************************************/
class Button extends Submit
{
var $Value;
/**
* Constructor
* @param string name of the field
* @param string value of the field
* @param string label of the field
* @param array attributes
* @access public
*/
function Button($name, $val='', $label='', $attr='')
{
parent::FormControl('button', $name, $val, $label, $attr);
if ($label) $this->add(new CData($label));
} // end func constructor
/**
* Add new object to $Child array.
* $Child can contain only text or image tag
* @param object
* @access public
* @return int
*/
function add(&$Widget)
{
if ('cdata' != get_class($Widget) && 'img' != $Widget->Tag)
return false;
$this->Childs[] = &$Widget;
return $Widget->Id;
} // end func add
/**
* Build html output
* @access private
* @return void
*/
function _createView()
{
$this->View = '<button' . $this->_attr2str().'>';
foreach ($this->Childs as $i=>$Child)
$this->View .= $this->Childs[$i]->getView();
$this->View .= "</button>\n";
} // end func _createView
} // end class Button
?>